I am using the Youtube Javascript client to request a list of the recommendations for the OAuth'd user:
gapi.client.youtube.activities.list({
"part": "snippet",
"home": true,
"maxResults": 50
}).execute(function(data) {
// etc
});
This returns a load of recommendations, as expected, and the recommendations don't appear to change. However, the ID of the recommendation (data.items[k].id) changes (usually towards the end of the ID) each time I make the request.
When I was making a similar call for Google+, the IDs that come back are the same every time for posts etc.
So should these IDs be immutable (i.e. this is a bug in the API) or is my assumption that they are always the same invalid? The documentation says:
The ID that YouTube uses to uniquely identify the activity.
... which doesn't really help one way or the other.
If this is the case, how do you uniquely identify these items?
Assuming you want the video id, you need to specify contentDetails as the part.
gapi.client.youtube.activities.list({
"part": "snippet,contentDetails",
"home": true,
"maxResults": 50
}).execute(function(data) {
// etc
});
Related
I am trying to keep track of Outlook calendar events without the need to store information about them on my own systems. I decided to do this by adding the required ids as categories with their type of id before it as shown in the code sample below.
{
"#odata.etag": "",
"createdDateTime": "",
"categories": [
"ID1::abc123",
"ID2::def456"
]
}
I tried using the 'any' lambda operator and this works fine if I want to filter based on one category using the query below:
https://graph.microsoft.com/v1.0/me/events?$filter=categories/any(x:x%20eq%20'ID1::abc123')
What I need is a query that will check if an event has both ids so in this case only the events where ID1=abc123 and ID2=def456. I figured https://graph.microsoft.com/v1.0/me/events?$filter=categories/any(x:x%20eq%20'ID1::abc123')%20AND%20categories/any(x:x%20eq%20'ID2::def456') should do the trick but this keeps returning empty arrays.
Thanks in advance!
Since categories are available to the user (and this is going to look really strange in outlook), I would suggest you to use the transactionId on the events to store the external id. This will automatically deny your new event if you try to create a duplicate.
I know this isn’t the answer you were looking for, but using this solution will be much more feature proof.
In RestKit is it possible to use identificationAttributes that are actually not part of the JSON response?
My case is the following - I have a service that lists all articles for the currently logged-in user like http://example.com/json/articles.json
My problem is the following - since the application allows multiple users to login, I keep the articles in the database together with the userId for each article. If I set the articleMapping.identificationattributes = #["articleId"], then I have a problem if two users using the device have the same article - it will be overwritten regardless of the userId, because it is not part of the response.
To sum up the facts:
For the JSON request I do not send the userId, it is part of the
server session only, so I think that I cannot use RKRoute
I do the mapping of the article with the user manually after RestKit mapping.
I do not have the userId property as part of the JSON response, it exists only inside the ArticleManagedObject.
Is there a way to inform RestKit that during the mapping, it should check the articleId+userId combination as an identificator? I tried using identificationPredicate with no success.
EDIT:
An example response from the server, when UserA is logged in:
{
"data":{
"articles":[
{
"articleId":1,
"title":"Objective C Basics"
},
{
"articleId":2,
"title":"Xcode Basics"
}
]
}
}
and here is the response when UserB is logged in:
{
"data":{
"articles":[
{
"articleId":1,
"title":"Objective C Basics"
},
{
"articleId":3,
"title":"Java Basics"
}
]
}
}
If UserA logs in, everything is fine. But if UserB logs in from the same device, then article 1 is mapped to UserB, and from now on, the connection between UserA and article 1 is lost.
As I understand from your suggestion, the only solution is to return also the user id from the service, set RKUnionAssignmentPolicy and let RestKit take care of the mapping (currently I am manually making the mapping between articles and users after RestKit).
Another question that I have - is it possible to set the identificationAttributes or identificationPredicate so that it makes a separation between object article 1 for UserA and object article 1 for UserB.
You currently do the user to article mapping outside RestKit, this is fine, but you will need to modify this process a little.
To begin with, I'm assuming here that the article response is the full set of articles for the user. If not then things get more tricky and you'll need to modify the below to account:
Start by getting all of the existing articles for a user. With this we're going to look at what needs to be removed and what needs to be added.
As we iterate through the articles we have received we can check the existing articles for a match, if we find one we have no work to do. If we don't find a match we need to add the relationship to the existing set, which will be a union with any relationship to any other user.
Next we want to remove the list of new articles from the list of the existing articles to get the list of deletions, for these we just need to break the link, again leaving other users unchanged.
API calls https://www.googleapis.com/youtube/v3/videoCategories?part=snippet®ionCode=US&key=API_KEY can retrieve a list of available videoCategory for certain country.
For example, videoCategory id 43:
However, when i retrieve video by this videoCategory id 43, for example https://www.googleapis.com/youtube/v3/videos?part=snippet%2C+contentDetails&chart=mostPopular®ionCode=MY&videoCategoryId=43&key=API_KEY, i get error instead:
At the first glance, i thought it was due to assignable is false, but it's not the case, because some videoCategoryId which was assignable=false can retrieve videos too.
videoCategoryId id 30, assignable is false:
videoCategoryId 30 have no problem to get videos:
Search API is ok(some categories return only ~2 videos), for example this API calls, https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&maxResults=20&order=relevance&videoCategoryId=43&type=video&key=API_KEY:
I'm not sure it's bug or not. Because it's possible videoCategory id 43 is not under mostPopular chart and lead to this error. But how is it possible to detect and filter it out on videoCategories resource API? there's no flag to indicate this category cannot work with video resource API.
I ran into this as well, and it seems that the bug is that "Movies" and "Trailers" should be set as assignable. Per this, https://developers.google.com/youtube/v3/docs/videoCategories, if a category is assignable it has videos associated with it. So it makes sense that retrieving videos for non-assignable categories would fail, but it does not make sense that those two non-assignable categories do, in fact, have associated videos (although "Trailers" only returns one result, which is strange).
I suppose a temporary workaround is to just include assignable categories, and manually include movies and trailers.
I'm working on a project where we plan to send some data back to Desire2Learn. I've gotten pretty far, I can query the user list, I can get their profile id, get their profile, and then update said profile.
I noticed when looking through the documentation, that I if I call /d2l/api/lp/1.3/users/?OrgDefinedId=123456789 it returns just that one user as seen below.
[
{
"OrgId": "{{ORG_ID}}",
"UserId": 12345,
"FirstName": "Christopher",
"MiddleName": null,
"LastName": "Sterling",
"UserName": "csterli1",
"ExternalEmail": "{MY_EMAIL}",
"OrgDefinedId": "123456789",
"UniqueIdentifier": "{{UID}}",
"Activation": {
"IsActive": true
},
"DisplayName": "Chris Sterling"
}
]
The problem, I believe, that I've ran into is that in order for me to get the Profile ID, I can't call the url above, but instead, I have to call /d2l/api/lp/1.3/enrollments/orgUnits/{{ORG_ID}}/users/. That call there returns the Profile ID, but it also returns all users, in increments of 100.
What I am wondering is if there is a way that I can pass the ?OrgDefinedId to the enrollments method and have it return the user object?
If that isn't the case, I'm wondering, is there a better way to do what I am trying to do. It currently seems like I am going to be making a large number of calls to get all our users so we can get their profile id for a given user.
Thanks!
There is not currently a better filter on the enrollments calls, nor does the profile identifier appear in the administrative user data record returned from the .../users/ calls.
The GET classlist for orgunit call also returns data containing user profile identifiers, and it returns data in a JSON array rather than a paged set. The Enrollment.ClasstlistUser structure contains the LMS UserId (Identifier) and user profile ID (ProfileIdentifier) data and can also contain the OrgDefinedId property. In order to get back that last data, though, your LMS must be configured to provide org-defined IDs in the Classlist tool. If it's not, then to make the union between profile identifiers and org-defined identifiers, you'll need to use the LMS UserId as the common value, and make a series of calls to get back two data sets you can join together.
// This is a first attempt at using YouTube's v3 API. It doesn't require authentication.
getAutoGeneratedPlaylistData: function() {
gapi.client.setApiKey('{API_KEY}');
gapi.client.load('youtube', 'v3', function () {
var request = gapi.client.youtube.playlistItems.list({
part: 'contentDetails',
maxResults: 50,
playlistId: 'ALYL4kY05133rTMhTulSaXKj_Y6el9q0JH',
fields: 'items/contentDetails'
});
request.execute(function (response) {
console.log("Response:", response);
});
});
}
This code takes the playlistId of an auto-generated YouTube playlist and retrieves the first 50 items from it.
The provided response's contentDetails contains each video's ID.
It seems like if I want to retrieve all of the video information for an auto-generated playlist I will need to issue 2N requests to youtube? N requests to retrieve all of the video IDs from the playlist in sets of no more than 50. Once I have all of the video IDs... then I need to ask YouTube for video information for all of the videos. I can get data for 50 videos in one request... so that's another N requests to YouTube to retrieve all of the videos?
This seems like a poor design decision. Previously, using v2 API, if I was retrieving all of the information for a playlist I could be sent all the necessary information for the videos in the initial request.
Is this no longer possible using the V3 API? Am I supposed to incur O(2N) network costs...? Really?
What additional video information are you after? If you need publication date, title, description, thumbnails, position in the playlist, etc., then that is in the snippet of the playlistItem, not the contentDetails. In fact, the snippet also contains a resourceId, which in turn has the videoId, so you could ignore the contentDetails anyway and just do:
var request = gapi.client.youtube.playlistItems.list({
part: 'snippet',
maxResults: 50,
playlistId: 'ALYL4kY05133rTMhTulSaXKj_Y6el9q0JH'
});
(possibly using a fields parameter to only select those parts of the snippet you're after).
If you need video information in addition to the fields in the snippet, then you're correct that you'll have to make another set of calls (in batches of 50). This is actually a very good design decision. Nearly all use cases for playlist item requests never need more than the info in the snippet, so they can cut down significantly on sending a whole bunch of data to a whole bunch of apps that just ignore it. It does require that, in those use cases that need extra data, extra calls have to be made, but the efficiency of the entire system gets better (a very utilitarian engineering choice).