How to Delete a Google Site by its id - gdata-api

I am unable to find out how can I delete a Google Site given its ID. I guess I need to create the SiteEntry for that site and call delete() method, but no idea on how to create the SiteEntry with just the ID.
This is how I am creating the sites:
SitesService client = new SitesService("domain-AppName-v1");
client.setUserCredentials("adminUSer#domain.com", "password");
//Define Site
SiteEntry entry = new SiteEntry();
entry.setTitle(new PlainTextConstruct("Accounting 001"));
entry.setSummary(new PlainTextConstruct("Accounting 001"));
entry.getCategories().add(new Category(TagCategory.Scheme.TAG, "Course Sessions", null));
//Create the site
SiteEntry result = client.insert(new URL("https://sites.google.com/feeds/site/domain.com/"), entry);
//This Delete does not work
result.delete();
//Trying to setup the id in a SiteEntry, it doesn't work either
SiteEntry e = new SiteEntry();
e.setId(result.getId());
e.delete();

This turned out to be a stupid question.
First, https://developers.google.com/google-apps/sites/faq#DeleteSite states the API doesn't support deleting Sites yet, and they must be deleted manually via the web panel. This really sucks because I currently have hundreds of sites created with the API and it is a pain in the ass to delete them manually :-(
Second, siteEntry.delete() throws an Exception saying "delete not implemented", so I was wrong when adding that as working in the question code.
Finally, to retrieve a SiteEntry you must do like this:
SitesService client = <initialize the service>
SiteEntry site = client.getEntry(new URL(siteID), SiteEntry.class);

Related

Can't save object in Cloud Code

I'm having an issue when running a function in Cloud Code. It is supposed to check the existence of an object and, if it does exist, create a new user:
Parse.Cloud.define("createUser", function(request, response) {
// Query the existing company by id
var query = new Parse.Query(Parse.Object.extend("Company"));
query.equalTo("objectId", request.params.company.existing.id);
query.find().then(function(result){
var user = new Parse.User();
user.set("username", request.params.username);
user.set("password", request.params.username);
user.set("email", request.params.email);
user.set("permissions", ["User"]);
var company = result[0];
user.signUp(null, {
success: function(user){
// Asign company ACL for User write permission
var cACL = company.getACL();
cACL.setWriteAccess(user.id, true);
company.setACL(cACL);
// Save company
company.save();
console.log(company);
// Establish user-company relationship
var cRelation = user.relation("associated");
cRelation.add(company);
// Save user
user.save();
console.log(user);
// Finish
response.success(user);
},
error: function(user, error){
response.error(JSON.stringify({code: -8000, message: "User creation failed"}));
}
});
}, function(error){
response.error(JSON.stringify({code: -8001, message: "Invalid company"}));
});
});
I first query Parse for the existence of said object. If it does exist I create a new user with the parameters received. In the completion block of the user creation I assign the proper ACLs (to the company object) and later on save them. That's when I encounter the first issue: the ACLs are not saved (checked in the dashboard). I console.log the company for debugging purposes and it shows the ACLs are correctly set. So I assume it must be a saving problem.
NOTE: The user is created, but whatever I try to do later doesn't work.
Later on I add this object to a relationship previously defined in the dashboard, but I have the same problem with that: the relationship does not come up in the dashboard, even though when I console.log the object it shows that the relationship was properly set.
I'm lost here. I don't understand why this isn't working and I've read tons of online documentation and still can't find the answer.
Okay, after a day of work I finally found out my problem. I had ACLs set everywhere and I had no privilege for saving the objects I was trying to save. So saving was indeed failing.
I should note that if you are having the same problem I did, you can easily solve it using the Master Key. To do so, you need to call Parse.Cloud.useMasterKey() before executing any requests that must be authenticated.
This only works in Cloud Code, and you should definitely know what you are doing when you use the Master Key because it basically gives read and write privileges to anyone, everywhere, for everything. So make sure your logic is flawless because you might get big security problems if it's not used wisely. As Uncle Ben said: With great power comes great responsibility.
Hope this helps someone.

Sitefinity: Where can I find the master GUID for a content item?

I'm building a web service for a client that pulls data from the Sitefinity CMS. The problem is they want to pass in a Guid for the service and receive the info about this item. No problem except I only have been able to locate the "live" Guid for one Item (and that was by combing through the HTML in the back end).
I was going to look at the tables in SQL Server but I'm not sure which table to look at. The content items have several tables all related of course and there isn't any documentation on how to look at this. I can find plenty of documentation on querying the master Guid, but no place to find it.
Oh, and these are custom content types built by the Module Builder.
Any Help would be SOOOOO appreciated!
var master = DynamicModuleManager.GetManager().Lifecycle.GetMaster(<liveGuidHere>);
One of the biggest consumers of Sitefinity webservices is Sitefinity. The best place to start looking for that guid is to take a look at what web service calls are being made when you pull up your custom content item list in the backend. I used the chrome developer tools and check in the network tab.
One I found for a stores module made with module builder was something to the effect of http://www.testsite.com/Sitefinity/Services/DynamicModules/Data.svc/?managerType=Telerik.Sitefinity.DynamicModules.DynamicModuleManager&providerName=OpenAccessProvider&itemType=Telerik.Sitefinity.DynamicTypes.Model.Stores.Store&provider=OpenAccessProvider&sortExpression=LastModified%20DESC&skip=0&take=50
The json this returns is a list of all the masters with their ids (note in the list that the content items all have have a status of 0) http://www.sitefinity.com/documentation/documentationarticles/developers-guide/sitefinity-essentials/modules/content-lifecycle
When you go to Administration / Module Builder / Your Module, you will see a link to the API on the top right corner.
This link goes to a page full of API examples for your particular module which is kind of cool.
Basically you would have to find your item first using LINQ and the GetValue extension method.
Once you have the item you can get its ID or any other property.
using Telerik.Sitefinity.Utilities.TypeConverters;
using Telerik.Sitefinity.DynamicModules;
using Telerik.Sitefinity.Model;
....
var mgr = DynamicModuleManager.GetManager();
var countrymasters = from ctry in mgr.GetDataItems(TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.Destinations.Destination"))
where ctry.GetValue<string>("culture") == siteid &&
(ctry.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live && ctry.Visible == true)
select new
{
airport_cd = ctry.GetValue<string>("airport_cd"),
country_master_cd = ctry.GetValue<string>("country_master_cd")
};

Insert Moments on Googleplus with PHP: almost done... just an non-object error to solve

I am trying to post a moments on my Googleplus Business Page though a PHP script.
To call the Google APIs I am using service accounts.
The following code give this error "Fatal error: Call to a member function insert() on a non-object in (last Line)".... could you help me to solve this prob?
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_PlusService.php';
// Set your client id, service account name, and the path to your private key.
// For more information about obtaining these keys, visit:
// https://developers.google.com/console/help/#service_accountsconst CLIENT_ID = 'MYID';
const SERVICE_ACCOUNT_NAME = 'MYACCOUNT';
// Make sure you keep your key.p12 file in a secure location, and isn't
// readable by others.
const KEY_FILE = 'MYAUTHFILE';
// Load the key in PKCS 12 format (you need to download this from the
// Google API Console when the service account was created.
$client = new Google_Client();
$key = file_get_contents(KEY_FILE);
$client->setClientId(CLIENT_ID);
$client->setAssertionCredentials(new Google_AssertionCredentials(SERVICE_ACCOUNT_NAME,array('https://www.googleapis.com/auth/prediction'),$key));
// Create moment that does not have a URL.
$item_scope = new Google_ItemScope();
$item_scope->setId("MYGOOGLEPAGEID");
$item_scope->setType("http://schemas.google.com/AddActivity");
$item_scope->setName("The Google+ Platform");
$item_scope->setDescription("A page that describes just how awesome Google+ is!");
$item_scope->setImage("https://developers.google.com/+/plugins/snippet/examples/thing.png");
$moment_body = new Google_Moment();
$moment_body->setType("http://schemas.google.com/AddActivity");
$moment_body->setTarget($item_scope);
$momentResult = $plus->moments->insert('me', 'vault', $moment_body);
You can only write moments on behalf of an authenticated user when you use the https://www.googleapis.com/auth/plus.login scope. You can't use a service account to do this. More so you cannot authenticate as a Google+ Page so writing moments isn't possible in your scenario.
Do you think you might be able to edit your post to explain why you want to write moments on behalf of a Page? What is the goal that you are trying to achieve?
It seems you didn't initialize the Plus API Client:
$plus = new Google_PlusService($client);
You will also have to use the correct scope https://www.googleapis.com/auth/plus.login instead of https://www.googleapis.com/auth/prediction
And I'm not sure if writing moments will work with service accounts...

Connection String vs Data Service call

I have 2 separate MVC 3 websites (A & B), both with their own SQL Azure databases which may or may not be on the same server. Both are using Code First Entity Framework and will be deployed to windows azure.
Website A is considered the master website and database. This holds data of the clients using our software along with usernames and passwords. I want website B to connect to website A's database when user logs in or registers. Website B will also need to hit website A's database in order to get some of the client's data after the user is logged in.
Right now I just have this one website B hitting website A's database, but in the future I will have more of these websites like website B hitting the main database for the same reasons.
My question is what is the best way to send and receive data between these smaller websites and the master database?
At first I was just using 2 connection strings in website B with two different contexts(one for each db). I liked this because the object types all flowed together, there wasn't any converting to do.However, I wasn't sure if this was the best and most secure way to go.
Another option I have been looking at is oData Services. I do like the idea of having everything separated and just calling the service when needing data from the master database. The issue I am having though is transferring the data from the service into my model's objects. I am having to do nasty things like this foreach statement:
public ActionResult GetMovies()
{
var ctx = new MovieODataService.MovieContext(new Uri("http://localhost:54274/MovieService.svc/"));
DataServiceQuery<MovieODataService.Movie> query = ctx.Movies;
var response = query.Execute() as QueryOperationResponse<MovieODataService.Movie>;
var model = new MovieModel();
model.Movies = new List<Movie>();
foreach (var item in response)
{
model.Movies.Add(new Movie
{
Title = item.Title,
ReleaseDate = item.ReleaseDate
});
}
return View(model);
}
I am also open to any other suggestions. Thanks in advance!
OData is great for a lot of things, but where it really shines is in exposing rich queryability over (preferably) schematized information. That doesn't really feel like a great fit for authentication calls.
Have you looked at the more traditional authentication protocols, such as OAuth? That seems like a much better fit for what you're trying to achieve.

mod-rewrite in the eZ Publish Framework

I'm currently using the eZ Framework as part of my new job.
mod-rewrites are handled in 2 sections of the GUI admin interface:
1 - URL translator
2 - URL wildcard
The URL translator essentially handles single rewrites
The URL wildcard is... as the name suggests meant to be wildcard, so can handle *
At the moment, when a new competition is created a new "URL translator" needs to be added. This gets ugly when there are 25 competitions and 15 are old and out of date.
This is what the data entry person has to enter at the moment for a new competition:
URL = /places/competitions/the-name-of-the-comp/process
TO = competition/process
We have tried writing a wildcard catch all, so new comps don't have to be entered as a single rewrite:
URL = /places/*/process
To = competition/process
But, as you may have guessed, it is not working.
If anyone is an eZ Publishing master and knows if this can be done i would be very appreciative.
Thanks,
John

Resources