Showing posts with label activities. Show all posts
Showing posts with label activities. Show all posts

Monday, February 25, 2008

Playlist Loading/Shuffling

Sorry it's been so long since my last post. I took a trip up to New York for an OpenSocial Hackathon (which I'll discuss in a later post,) but I just had this thought mulling around my head and felt like writing it down.

I probably use my media player (WMP, Songbird, AmaroK, etc) more than any other program on my computer. No matter what I'm doing (coding, web-surfing, doc writing, or all three,) I'm usually listening to music. I'll pick a playlist, either from my list of pre-made playlists, or just throw one together at the drop of a hat. However, I really hate how most modern shuffles absolutely fail at "shuffling" my songs. On my n800, GP2X, and ipod before that, I could tell that there was no list order, but that the player literally just selected a random song from the list, and played it. Yeah, it's fast, but it's lazy, and kind of infuriating. A few days ago, on WMP, it actually played the same song twice. As far as randomness goes, that's technically random, but I don't like random, I want shuffled.

When you're playing a card game, you don't reshuffle the deck every time someone puts a card down (though that could really screw up your magician friend's magic trick.) No, you wait until the deck has been fully uncovered (or the hand ends.) 

Along with that, even though WMP loads a playlist, it "shuffles" it, but it's pretty lazy as well. That's why when the playlist ends, I coudl theoretically listen to the same song twice. Even along with that, though, sometimes it'll get into blocks where I hear all of an artist's songs right in a row, which is frustrating as well.

I don't have any code at the moment, but it would really be nice if there was a good shuffling algorithm that made sure that artists' songs were kept spread out, prevented playing the same song close to itself, and, in general, made my most commonly performed task a little bit nicer.

Wednesday, December 12, 2007

OpenSocial Activities Retrieval

NOTE: This code and post was written for an older version of Opensocial. I make no guarantees as to it's validity in later versions.

I know I missed my post last week, but I plan to make up for it with two this week. I've been working on some stuff that I shouldn't be blogging about (company secrets, nothing major, I just have to keep it hush-hush) for the past week, hence nothing major to talk about. However! I did get some fun stuff taken care of yesterday, so now I have something worth posting.

I've been talking a lot with Arne Roomann-Kurrik, a Google employee, and he's been helping me through the problems I've been running into. Yesterday, the two of us discovered (more like he knew and I found out) how retrieving activities work.

Before we begin, there is a major limitation to what you can do. Your application can only retrieve activities it has created. This immediately limits you, as a developer, but just having the functionality provides you with a lot. I'd like to be able to access all of a user's activities, but I can also see why a social networking site would prefer if developers didn't have access to a user's every move.

Alright, now onto the fun stuff. Last post, I mentioned how to create an activity, so I won't go into detail on that again, save to say that you should always remember that duplicate entries won't be posted twice. When you want to load the activities from a user's update feed, you need to make a FetchActivitiesRequest. To do that, you set up a standard DataRequest...


var req = opensocial.newDataRequest();

...add the FetchActivitiesRequest...

req.add(req.newFetchActivitiesRequest("VIEWER"), "viewer_activities");

...and make the request...

req.send(showActivities);

Now, the important things to note are that "viewer_activities" is the variable that the resultant data will be stored in, and that "showActivities" is the method that will be called with said resultant data. Also, I have the request asking for the viewer's activities, but "OWNER" works just as well, even if they aren't the same (i.e. you can view a friend's activities if they are the owner but you are the viewer.)

When we get to the "showActivities" function, things get a little bit stranger. Yes, you do have to pull the data that was sent back, like so...


var response = data.get("viewer_activities").getData();

But the data needs to be segmented further before it is useable. When it is set to viewer_activities, it's actually a collection (opensocial collection), with the two keys: "actvity" and "requestedStream". There's no need to pull them both out if you don't need one, but I did for the sake of science. Here's how you do that.

var activities = response["activities"];
var stream = response["requestedStream"];


Mindblowing, I know. I'm not going to bother with the stream at all, mostly because it's boring, save to say that for some reason, even if you create two different streams, and post events to them, when you retrieve the events, they will claim only to belong to the first. Kind of weird, but it's something I felt I should mention.

Anyways, there are a few ways you can retrieve the data from the activities object. Like "viewer_activities", it is a collection of the activities. If you want every single entry, just use:

activities.each(printActivity)

That will call the printActivity function once with every entry in actvities. Here's my printActivity, it's pretty basic:

function printActivity(activity)
{
document.getElementById("gadgetdiv").innerHTML += activity.getField(opensocial.Activity.Field.TITLE) + "
";
};


You can also use the array (and my preferred) method. Simply convert the collection into an array using:

activities = activities.asArray()

And then you have an array, which you can use indexes with. Hooray!

Also, according to Arne (and the documentation), you can also use the getById function of the collection, but there's no way to get an array of ids, and getById needs the full activity ID. That number, at least in Orkut (where I've been testing) is 20 digits, so you better know it beforehand if you want to use it.

Other than that, that's all it takes to retrieve Activities in OpenSocial! Just remember what you're limited to, and have fun!

Wednesday, November 28, 2007

OpenSocial Activity Posting

NOTE: This code and post was written for an older version of Opensocial. I make no guarantees as to it's validity in later versions.

There are four APIs to opensocial: Javascript, Activities, People, and Persistence. The last three haven't been released yet, but the Javascript one already implements some of the features that they will support. For example. the People API will let you retrieve a specific person, or a specific person's friends. That can already be done (mostly, you can't get a person by ID yet) in the Javascript API. I ran through what could be done with people pretty quickly, and was able to get a demo up using persistence as well, but activities have been puzzling me.


The Activities Data API describes how you will be able to create, retrive, update, and delete activities. That sounds sweet. Except for the fact that right now, with the Javascript API, the only thing you can do is create activities. Even doing that is kind of confusing, so I'm going to go through what I've learned so far.

Before you can even think about creating an event, you have to create a stream. You do this with opensocial.newStream. The first parameter, folder, has apparently already been deprecated, so I've just been putting "null" for it. Title, the second parameter, is apparently the title of the stream (real big surprise.) I've done some tests, and if you use newStream with the title of an already existing stream, it still creates a new stream. I'm not sure what it does to the old stream, but activities that have already been posted to a person's update feed aren't removed. The tests were part of a demo app I'm working on, so they're not in their own test apps. Once I get them seperated, I'll post a link to them. Finally, you can post a map of optional parameters. Right now, the only two fields that interest me are USER_ID, and FAVICON_URL. I haven't tested FAVICON_URL yet, to see how well it works, but USER_ID got me really excited. When I was first working with the activities, I thought that I could only post updates to my own update feed (which is sort of redundant, but it is the default if no USER_ID is specified.) All you have to do is specify the USER_ID, and any activities posted to that stream will go on that user's update feed. SO, here's the line of code that I use to create my stream.


var activitystream = opensocial.newStream(null, title, { "USER_ID": friendId });
"title" is a variable containing whatever I want the stream to be titled. "friendId" contains the id of the friend whose feed the activities will be posted to.


Alright then, the stream is set up. Now you get to create the event. That's accomplished with opensocial.newActivity. It has three parameters as well. The first one, stream, is the stream variable you just set up. The second, title, is the most important. It is what will show up on the update feed. Also, since the optional parameters don't seem to be doing jack at the moment, it's ALL the person who recieves this activity will see. Here's how you set up the activity.


var activity = opensocial.newActivity(activitystream, text_to_display, null)

I just leave opt_params as null, since they're pretty useless now.


Almost done! You've set up the stream and the activity, and even told the activity what stream it's going to be posted to. Now, all you have to do is let it loose. This is done using the opensocial.requestCreateActivity method. It has, beleive it or not, THREE PARAMETERS. The first is the activty variable, which has the stream variable, which swallowed the fly...etc. The second is the "priority" of the posting. There are only two options (at least at the moment), opensocial.CreateActivityPriority.HIGH, and opensocial.CreateActivityPriority.LOW. HIGH means that if the stream you wrote to doesn't exist, the activity will still be posted. If you choose LOW, and the stream doesn't exist, the activity will not be posted. Supposedly, there is a chance that using HIGH will navigate away from the current page (your opensocial gadget,) but I've never had that happen to me, and I've only been using HIGH. The third parameter is a function to be called when the activity has been posted. It's optional, but I've been using it to verify that the operation completed. Here's the last line of code you need.


opensocial.requestCreateActivity(activity, opensocial.CreateActivityPriority.HIGH, callbackFunction);


There you have it, the longest explanation of three lines of code ever. ;-P At least now you can post updates to your friend's update feeds. One other little caveat I should mention, if the title of the activity is identical to another activity in the same stream, it will not be re-posted. My guess is that changing the opt_params might allow this to happen, but I haven't tested it yet.

As far as programmatically accessing streams/activities, I'm totally scoobied at the moment. After I post this, I'm going to check the DataRequest methods, and see how much I can/can't do with them, but for now, I'll leave you with being able to post activities. Catch youse later.