Catching up on Facebook Quickly–Try #1

I had removed the facebook app from my phone, because it was taking too much time.  I dreamed of writing my own app that would let me catch up on facebook quickly, and a week at a time.  This afternoon, I got some time to play.  

Three hours Later

image

Research:

  • I had to go to developer.facebook.com, register, and create an application, to get an application ID.  (well, maybe I didn’t, but I would eventually.)
  • I tried going down the path of Heroku, hosting an app, git, python, etc – but once I found the .Net client, I was done.  (nuget: Facebook
    • I ran into problems where heroku’s git client would not present the right ssh key, and I couldn’t find the ssh command line that it had installed to tell it the right key to use.
  • To bypass authentication, I went to https://developers.facebook.com/tools/explorer and generated an access token from there; it needed the read_stream priviledge.   The token expires after an hour.
    • the url to query is “/me/home” (thank you stack overflow) to get the JSON that represents your newsfeed (most recent items first, looks like)

Then, I created an MVC app to do the querying.  The controller side, to be replaced eventually with more fancier login stuff:

var accessToken = "AAACEdEose0cBABI5wFnNe209ddAmRFpWOB9T9O8x2sCaNlc91ZB1u6gqqrxHseMvBKhuDHtkS3KY6KAlIz6Xc8Ps24nvIWKRF... etc";
var client = new FacebookClient(accessToken);
dynamic homeraw = client.Get("me/home");

That’s great, I have a dynamic object, but I’d rather have intellisense.  Enter json2csharp (thank you!!!!), creates me some classes, a little refactoring / renaming, and some hard coding: 

foreach (var dataraw in homeraw.data)
{
  var homeItem = new HomeItem()
  {
    id = dataraw.id,
    from = new From()
    {
      id = dataraw.@from.id,
      name = dataraw.@from.name,
    },
    message = dataraw.message,
    caption = dataraw.caption,
    name = dataraw.name,
...

And sent everything off to my view, which spits it out into html (the Acronym stuff is not shown here, but I built “SG” out of “Sunjeev Gulati”):

@foreach (var item in Model.Data.data) { <div class="infobubble"> <div>

<strong title="@item.from.name">@Model.AuthorAcroymn[item.from.id]</strong>:

@(item.message ?? item.caption ?? item.name) </div> @if (!String.IsNullOrEmpty(item.picture)) { <div> <img class="pic" src="@item.picture" /> </div> } </div> }

Added a little styling:

.infobubble 
{
    font-size: 12px;
    border: 1px solid gray;
    float: left;
    display: inline-block;
    padding: 2px;
    margin: 2px;
    word-wrap: break-word;
}

And now for some fun.  Reformatting things in jQuery to be more blocky:

    $(window).load(function () {
        $(".infobubble").each(function () {
            var width = $(this).width();
            var height = $(this).height();

            // determine if there's a picture in here somewhere
            var pic = $(this).find(".pic");
            if (pic.length > 0) {
                var picwidth = $(pic[0]).width();
                $(this).width(picwidth);
                width = $(this).width();
                height = $(this).height();
            } else {
                // no picture.  just text.  assume its already very wide
                // bring the width down till its closer to square
                for (var i = 0; i < 10; i++) {
                    if (width > height * 2.0) {
                        $(this).width(width / 2.0);
                        width = $(this).width();
                        height = $(this).height();
                    } else if (height > width * 2.0) {
                        $(this).height(height / 2.0);
                        width = $(this).width();
                        height = $(this).height();
                    } else {
                        break;
                    }
                }
            }
            $(this).data("width", width);
            $(this).data("height", height);
        });
        $("#container").masonry({ itemSelector: '.infobubble' });
    });

This does a few things:

  • If it has a picture, size to the picture.  This usually works (though the “WAL-MART” one at the bottom of the screenshot is an interesting example, I’ll have to check for for overly long text)
  • Otherwise, try to size it till its kinda-square.
  • Then use jquery.Masonry to fill the space.

Where to go from here

  • Use some pre-defined sizes so that Masonry has an easier time filling a wall?
  • Use photo pictures, but really small, to identify who wrote a post?
  • Deal with odd-sized things, or find a better algorithm for blockifying things.  Probably try standard widths like 50 100 200 and 400 and then move on.
  • Decide what to do with comments / likes, etc; support for other kinds of facebook items (only time will reveal them to me)
  • Going further back in time, rather than just a single call.    Try to make it infinite scrolling?  Or, call the service over and over till I have the data I want, re-sort it, and then display it?  While being respectful of their service?
  • Actually go through the pain of logging the user in to facebook.
  • Host the app somewhere?  I’m not sure if it violates any facebook laws, like maybe there’s one that says “you cannot write an app that replaces the newsfeed”?

If this app actually gets written, some of the features that would make it useful:

  • Enter a date range to view over (defaulting to the last time you were in)
  • Inline see comments (if a reasonable number, damn you Takei)
  • Filter down by person or type of post
  • Sort by person, size, photo.
  • Keep track of items seen or not-seen; Star items to look at later; mark all as read.
  • Automatic mute / filters.
  • Jump to item in facebook proper to go do something more with it.

Of course, that’s pie in the sky.   If you want a crack at it, go for it.   What I probably could do on short order:

  • Allow the user to enter the token in a textbox, so anybody could use it (without having to tackle the facebook login hurdle)
  • Host it somewhere for people to have fun with
  • Put the source on github

That would be “a good milestone”.    Maybe next time.

Nevertheless:  that was fun.

Tagged with: , ,
Posted in Code

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories
Tags
.net 3d 3d-printing 4k abc15 algorithms ames android anonymous types asp.net audio editing aws backup basecamp beatunes biorhythm bitcoin bittorrent blender blog boston marathon bpm c# caffeine campfire candycrush car carmax charity chiropractor cities-skylines clog clone codelouisville codepalousa coding coffee collaboration color run ComputerElbow ComputerVision configuration consulting cooking crash course crashplan crestwood cycling dabda dan dapper DataSet ddl diabetes dictation dotnetcore dotnetmud downtown e-cycling elite excel exercise expiration facebook feature-branching firefall flipflops Flow FL Studio focus food forecastle fortresscraft franklinplanner gadgets game-design games git github google docs google maps gopro gps grandpa greenshot hack half marathon headless health heart rate hiren ignew integration testing interop inventory ios ipad itunes javascript jobs karma kdf keyboards keys kittens lamont laptop lavalamp lego life lifehack linq linqtotwitter linux los angeles louisville mandelbulber massage therapy mastery-teaching maths merge metformin Minecraft miniature modeling monitor mud muhammad ali institute music mvc mycartracks netfabb nexus10 node nostalgia nutrition nwipe oldham county grand slam opal openjscad openscad owin pacedj paper mockup pepakura performance photoscan politics pomodoro postgresql powershell premiere prius process product-management project-management qa ReFS resharper review rmi roman road 5k RSI rubiks running samsung 700t sandals schedule scooter scribblelive selenium service shapeways sleep slic3r sneakersync snot software software-engineering solidoodle soylent spacegame speaking sql sqlite SSDT SSIS standing state-machine stayfocusd stonehearth sunset tablet teaching team teamcity teamtreehouse terraform tesla testing tfs time timelapse torque touch tracks trs80 Tuple tutor twitter ubuntu unit testing utilities video video editing visual studio vscode vsvim warp stabilizer windows 8 windows home server wordpress wpf xml
Archives
%d bloggers like this: