I am trying to add an entry in google calendar but getting service forbidden exception. It's a simple entry having a title, content and a date range. Code snippet provided below;
public void temp() {
URL postURL = null;
try {
postURL = new URL("http://www.google.com/calendar/feeds/MAILID#gmail.com/PASSWORD/full");
EventEntry eventEntry = new EventEntry();
eventEntry.setTitle(new PlainTextConstruct("One"));
eventEntry.setContent(new PlainTextConstruct("Two"));
When eventTime = new When();
eventTime.setStartTime(DateTime.parseDateTime("2016-03-09T15:00:00-08:00"));
eventTime.setEndTime(DateTime.parseDateTime("2016-03-09T15:00:00-08:00"));
eventEntry.addTime(eventTime);
CalendarService calendarService = new CalendarService("Savor");
EventEntry createdEvent = calendarService.insert(postURL, eventEntry);
} catch (Exception e) {
e.printStackTrace();
}
}
While doing this, I am getting ServiceForbidden exception provided below[Please ignore the line numbers shown in exception]
com.google.gdata.util.ServiceForbiddenException: Forbidden
<HTML>
<HEAD>
<TITLE>Forbidden</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Forbidden</H1>
<H2>Error 403</H2>
</BODY>
</HTML>
at com.google.gdata.client.http.HttpGDataRequest.handleErrorResponse(HttpGDataRequest.java:605)
at com.google.gdata.client.http.GoogleGDataRequest.handleErrorResponse(GoogleGDataRequest.java:564)
at com.google.gdata.client.http.HttpGDataRequest.checkResponse(HttpGDataRequest.java:560)
at com.google.gdata.client.http.HttpGDataRequest.execute(HttpGDataRequest.java:538)
at com.google.gdata.client.http.GoogleGDataRequest.execute(GoogleGDataRequest.java:536)
at com.google.gdata.client.Service.insert(Service.java:1409)
at com.google.gdata.client.GoogleService.insert(GoogleService.java:613)
at GCalender.temp(GCalender.java:68)
at GCalender.main(GCalender.java:85)
Exception occurs in this line: EventEntry createdEvent = calendarService.insert(postURL, eventEntry);
Trying to resolve this but sort of stucked up at this point. If anyone has came across this already, please provide your inputs, would be a great help..
Thanks!!
PS: Pls. ignore if the question is tagged with incorrect tag entries.
You are using Google Calendar API v2 which is Shut down. You need to switch to Google Calendar v3
Documentation for Events: insert
event = service.events().insert(calendarId, event).execute();
Update:
Your code has the following
MAILID#gmail.com/PASSWORD/
You need to also be aware that accessing Google APIs using a login and password no longer works. Client login was also shut down. You will need to Authenticate your application using Oauth2.
Related
I simply want to debug a controller but I can't watch the variables I get from 2sxc functions.
I tried to log varables via Log4Net writting :
private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof(MyClassName));
but the type ILog is not known in a 2sxc controller. Am I missing a reference?
I also found this snippet:
using DotNetNuke.Services.Log.EventLog;
var objEventLog = new EventLogController();
objEventLog.AddLog("Sample Message", "Something Interesting Happened!", PortalSettings, UserId, EventLogController.EventLogType.ADMIN_ALERT)
But I don't know what to send to "PortalSettings" and I don't any clue in the helpers of the 2sxc programming interface.
How do you guys debug 2sxc controllers and log events (not only for debuging)?
Thank you for your help!
Credit of these snippets: Scott McCulloch (https://www.smcculloch.com/code/logging-to-the-dnn-event-log)
This gives part of the answer: http://www.dnnsoftware.com/community-blog/cid/141723/using-log4net-with-dotnetnuke. And, it looks like the namespace is DotNetNuke.Instrumentation.
As for PortalSettings, that's the portal settings for your portal. I think that you'd need to reference DotNetNuke.Entities.Portals, and then use PortalController to retrieve the portal settings object.
Joe Craig's previous post helped me a lot.
So, in a 2sxc application, I now can log in the DNN event log (not the Windows one):
#using DotNetNuke.Services.Log.EventLog;
#using DotNetNuke.Entities.Portals;
#{
var aujourdhui = DateTime.Now;
var objEventLog = new EventLogController();
PortalSettings PortalSettings = new PortalSettings();
objEventLog.AddLog("Debug info", "Variable \"Aujourdhui\" contains: " + aujourdhui.ToString("dddd d MMMM yyyy"), PortalSettings, #Dnn.User.UserID, EventLogController.EventLogType.ADMIN_ALERT);
}
The only little problem is that this PortalSettings returns the first portal even if my 2sxc app runs on the second portal (id=1). I must be missing something. But for now and what I need (debugging), thats Ok for me!
Cross-posted on the MiniProfiler community.
I'm trying to throw MiniProfiler into my current stack. I think I'm mostly setup, but am missing the UI approach and would like recommendations on the best way to proceed.
Current Stack
SQL for DB (including MiniProfiler tables)
EF 6
WebAPI 2 API app
Angular 1.x. app for the UI (separate app, no MVC backing it) -- I think it's 1.5.x at this point.
So, the current method of RenderIncludes() isn't available to me.
What's the best method to include the JS files and set them up to retrieve the information from the SQL Server storage? I know that the files are included in the UI repo, but I didn't see docs for explicit configuration.
What I've Tried So Far -- Web API App
Installed the MiniProfiler and MiniProfiler.EF6 packages.
Web.Config -- Added Handler
(not sure if this is necessary):
<add name="MiniProfiler" path="mini-profiler-resources/*" verb="*" type="System.Web.Routing.UrlRoutingModule" resourceType="Unspecified" preCondition="integratedMode" />
Added a CORS filter to expose the MiniProfiler IDs to my client app:
public class AddMiniProfilerCORSHeaderFilter : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
actionExecutedContext.Response.Headers.Add("Access-Control-Expose-Headers", "X-MiniProfiler-Ids");
}
}
Add that filter as part of startup:
config.Filters.Add(new AddMiniProfilerCORSHeaderFilter());`
In Global.asax, added to Application_Start():
var connectionString = ConfigurationReader.GetConnectionString(Constants.ConfigSettings.CONNECTION_STRING_NAME);
MiniProfiler.Settings.Storage = new SqlServerStorage(connectionString);
MiniProfilerEF6.Initialize();
Update the begin/end requests:
protected void Application_BeginRequest()
{
if (Request.IsLocal || ConfigurationReader.GetAppSetting(Constants.ConfigSettings.USE_PROFILER, false))
{
var sessionId = Guid.NewGuid().ToString();
MiniProfiler.Start(sessionId);
}
}
protected void Application_EndRequest()
{
MiniProfiler.Stop();
}
What I've tried so far -- client (Angular) App
Snagged the UI files from the Github Repo
Copied the UI directory to my project's output
Reference the CSS:
<link rel="stylesheet" href="js/lib/miniprofiler/includes.css" />
Call the JavaScript
<script async type="text/javascript"
id="mini-profiler"
src="js/lib/miniprofiler/includes.js?v=1.0.0.0"
data-current-id=""
data-path="https://localhost:44378/api/profiler/"
data-children="true"
data-ids=""
data-version="1.0.0.0"
data-controls="true"
data-start-hidden="false"
data-trivial-milliseconds="5">
</script>
Current Status
When I do these things, it looks like it just can't find the appropriate WebAPI controller to render the result. If I can figure out where that controller is or replicate it (as I'm attempting to do currently) I think I'll be in business.
The RenderIncludes function results in a <script> tag being output to the page. It is defined in the UI Repo as include.partial.html and currently looks like this:
<script async type="text/javascript" id="mini-profiler"
src="{path}includes.js?v={version}" data-version="{version}"
data-path="{path}" data-current-id="{currentId}"
data-ids="{ids}" data-position="{position}"
data-trivial="{showTrivial}" data-children="{showChildren}"
data-max-traces="{maxTracesToShow}" data-controls="{showControls}"
data-authorized="{authorized}" data-toggle-shortcut="{toggleShortcut}"
data-start-hidden="{startHidden}" data-trivial-milliseconds="{trivialMilliseconds}">
</script>
This is the piece of Javascript that runs the rendering.
The RenderIncludes function is defined here. It does the following:
Makes sure that you have storage set up
Checks that current request is authorized to view results
Gets the Ids of the unviewed profiles for the current user
Takes the Ids along with any other params that you passed into the function and inserts them into the placeholders in the script defined in include.partial.html
Outputs this <script>
So if you cannot call RenderIncludes, there should be no reason why you cannot just put the script file in place, retrieve the unviewed Ids, but them along with any other setup values you want into the <script> tag, and output the tag.
The key lines of code for retrieving the Id values are:
var ids = authorized
? MiniProfiler.Settings.Storage.GetUnviewedIds(profiler.User)
: new List<Guid>();
ids.Add(profiler.Id);
where profiler is the current instance of MiniProfiler (run on the current request.
You will also probably need to make sure that you can handle the call that the script will make to /mini-profiler-resources/results (passing in the id of the profiler as a param). The guts of this is located here in the GetSingleProfilerResult(HttpContext context) function
I am trying to implement google custom search in an angular js website.
When I click on the search button it does not display me anything, but the url is updated to the url.
I have followed the steps mentioned in the documentation by google.
I am not sure what I am doing wrong?
My search bar is located on the home page as -
<gcse:searchbox-only enableAutoComplete="true" resultsUrl="#/searchresult" lr="lang_en" queryParameterName="search"></gcse:searchbox-only>
my search result has -
<gcse:searchresults-only lr="lang_en"></gcse:searchresults-only>
Any input is much appreciated.
Thanks,
You may have more than one problem happening at the same time...
1. Query Parameter mismatch
Your searchresults-only does not match the queryParameterName specified on gcse:searchbox-only.
Index.html
<gcse:searchresults-only queryParameterName="search"></gcse:searchresults-only>
Search.html
<gcse:searchresults-only queryParameterName="search"></gcse:searchresults-only>
2. Angular.js is blocking the flow of Google CSE
Under normal circumstances, Google Search Element will trigger an HTTP GET with the search parameter. However, since you are dealing with a one-page application, you may not see the query parameter. If that suspicion is true when you target resultsUrl="#/searchresult", then you have two options:
Force a HTTP GET on resultsUrl="http://YOURWEBSITE/searchresult". You may have to match routes, or something along those lines in order to catch the REST request (Ember.js is really easy to do so, but I haven't done in Angular.js yet.)
Use JQuery alongside Angular.js to get the input from the user on Index.html and manually trigger a search on search.html. How would you do it? For the index.html you would do something like below and for the results you would implement something like I answered in another post.
Index.html
<div>GSC SEARCH BUTTON HOOK: <strong><div id="search_button_hook">NOT ACTIVATED.</div></strong></div>
<div>GSC SEARCH TEXT: <strong><div id="search_text_hook"></div></strong></div>
<gcse:search ></gcse:search>
Index.js
//Hook a callback into the rendered Google Search. From my understanding, this is possible because the outermost rendered div has id of "___gcse_0".
window.__gcse = {
callback: googleCSELoaded
};
//When it renders, their initial customized function cseLoaded() is triggered which adds more hooks. I added comments to what each one does:
function googleCSELoaded() {
$(".gsc-search-button").click(function() {
$("#search_button_hook").text('HOOK ACTIVATED');
});
$("#gsc-i-id1").keydown(function(e) {
if (e.which == 13) {
$("#enter_keyboard_hook").text('HOOK ACTIVATED');
}
else{
$("#search_text_hook").text($("#gsc-i-id1").val());
}
});
}
(function() {
var cx = '001386805071419863133:cb1vfab8b4y';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = 'https://cse.google.com/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
I have a live version of the index.html code, but I don't make promises that will be permanently live since it is hosted in my NDSU FTP.
I'm reading source code of meanjs project to learn javascript and MEAN better. There is an expression:
<!--Embedding The User Object-->
<script type="text/javascript">
var user = {{ user | json | safe }};
</script>
I understand that it is sending the user record as a json object to the browser, but can't find 'safe' filter on google. Could anyone please point me to the right direction or explain what this is?
Yes, the user object is actually getting passed to the browser, and it actually displays in the source code. In practice, my deployed app has this in the source code (actual data generalized):
<!--Embedding The User Object-->
<script type="text/javascript">
var user = {"_id":"123abc456xyzetc","displayName":"First Last","provider":"local","username":"newguy","__v":0,"roles":["admin"],"email":"my#email.com","lastName":"Last","firstName":"First"};
</script>
As you can see, it actually dumps user information into the source code, which isn't the most secure way to develop an app. If you comment out or remove the line in your layout.server.view.html file (var user = {{ user | json | safe }};), then you can't really log in. It logs you in, then immediately kicks you out.
You'll notice, though, in your config > passport.js file that some information is removed before being passed back to the browser, starting at around line 14:
// Deserialize sessions
passport.deserializeUser(function(id, done) {
User.findOne({
_id: id
// The following line is removing sensitive data. In theory, you could remove other data using this same line.
}, '-salt -password -updated -created', function(err, user) {
done(err, user);
});
});
If you do decide to remove additional fields, though, be aware that this can break your app. I removed the user id, for example, and most of my app worked, but it broke some specific functions (I believe it was Articles, if I remember right).
I am new to dart and I have been trying to figure out how to use the googleapis library to update a calendars events, then display the calendar/events on a webpage.
So far I have this code that I was hoping would just change the #text id's text to a list of events from the selected calendars ID:
import 'dart:html';
import 'package:googleapis/calendar/v3.dart';
import 'package:googleapis_auth/auth_io.dart';
final _credentials = new ServiceAccountCredentials.fromJson(r'''
{
"private_key_id": "myprivatekeyid",
"private_key": "myprivatekey",
"client_email": "myclientemail",
"client_id": "myclientid",
"type": "service_account"
}
''');
const _SCOPES = const [CalendarApi.CalendarScope];
void main() {
clientViaServiceAccount(_credentials, _SCOPES).then((http_client) {
var calendar = new CalendarApi(http_client);
String adminPanelCalendarId = 'mycalendarID';
var event = calendar.events;
var events = event.list(adminPanelCalendarId);
events.then((showEvents) {
querySelector("#text2").text = showEvents.toString();
});
});
}
But nothing displays on the webpage. I think I am misunderstanding how to use client-side and server-side code in dart... Do I break up the file into multiple files? How would I go about updating a calendar and displaying it on a web page with dart?
I'm familiar with the browser package, but this is the first time I have written anything with server-side libraries(googleapis uses dart:io so I assume it's server-side? I cannot run the code in dartium).
If anybody could point me in the right direction, or provide an example as to how this could be accomplished, I would really appreciate it!
What you might be looking for is the hybrid flow. This produces two items
access credentials (for client side API access)
authorization code (for server side API access using the user credentials)
From the documentation:
Use case: A web application might want to get consent for accessing data on behalf of a user. The client part is a dynamic webapp which wants to open a popup which asks the user for consent. The webapp might want to use the credentials to make API calls, but the server may want to have offline access to user data as well.
The page Google+ Sign-In for server-side apps describes how this flow works.
Using the following code you can display the events of a calendar associated with the logged account. In this example i used createImplicitBrowserFlow ( see the documentation at https://pub.dartlang.org/packages/googleapis_auth ) with id and key from Google Cloud Console Project.
import 'dart:html';
import 'package:googleapis/calendar/v3.dart';
import 'package:googleapis_auth/auth_browser.dart' as auth;
var id = new auth.ClientId("<yourID>", "<yourKey>");
var scopes = [CalendarApi.CalendarScope];
void main() {
auth.createImplicitBrowserFlow(id, scopes).then((auth.BrowserOAuth2Flow flow) {
flow.clientViaUserConsent().then((auth.AuthClient client) {
var calendar = new CalendarApi(client);
String adminPanelCalendarId = 'primary';
var event = calendar.events;
var events = event.list(adminPanelCalendarId);
events.then((showEvents) {
showEvents.items.forEach((Event ev) { print(ev.summary); });
querySelector("#text2").text = showEvents.toString();
});
client.close();
flow.close();
});
});
}