Source

filmaster-api-sample / index.html

Full commit
<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    dir="{% if LANGUAGE_BIDI %}rtl{% else %}ltr{% endif %}"
    xml:lang="{% firstof LANGUAGE_CODE 'en' %}"
    lang="{% firstof LANGUAGE_CODE 'en' %}">
  <head>
    <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
    <title>Filmaster API sample - common movie recommendations</title>
    <link rel="stylesheet" type="text/css" href="css/style.css" />
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js"></script>
  </head>

<script type="text/javascript">
SERVICE_BASE = 'http://api.filmaster.pl'
Array.prototype.update_films = function(films) {
  for(var i=0; i<films.length; i++) {
    var k = 'permalink_'+films[i].permalink
    if(!this[k]) {
      this[k] = films[i];
      this.length++;
    }
  }
}

Array.prototype.intersection = function(films) {
  var result = []
  result.size = 0;
  for(var k in films) {
    if(k.indexOf('permalink_')!=0) continue;
    if(k in this) {
      result[k] = films[k]
      result.length++;
    }
  }
  return result;
}

Array.prototype.eachFilm = function(cb) {
  for(var k in this) {
    if(k.indexOf('permalink_')!=0) continue;
    cb(this[k]);
  }
}

recommendations = []

function selected_users() {
  return $('input.user').filter(function(i,v){return v.checked}).
                         map(function(i,v){return v.id.substring(5)});
}

function jsonp_uri(uri) {
  return SERVICE_BASE + uri + (uri.indexOf('?')>=0 ? '&' :'?')+'callback=?';
}

function show_common_recommendations() {
  var users = selected_users()
  if(users.length) {
    var common = recommendations[users[0]]
    for(var i=1; i<users.length; i++) {
      common = common.intersection(recommendations[users[i]])
    }
    $('#results li.film').each(function() {
      if(!common[this.id]) $(this).remove()
    })
        
    common.eachFilm(function(film) {
      var f = $('#permalink_'+film.permalink).get(0)
      if(!f)
        $('#results').append(create_film(film))
    })
  }
}

function fetch_recommendations(user, uri) {
  var inp = $('#user_'+user.username)
  var li = inp.parent('li').addClass('loading')
  
  $.getJSON(jsonp_uri(uri), null, function(data, status) {
    li.removeClass('loading')
    if(!recommendations[user.username]) 
      recommendations[user.username] = []
    if(recommendations[user.username].length < 100) {
      recommendations[user.username].update_films(data.objects)
      show_common_recommendations()

      if(data.paginator && data.paginator.next_uri && inp[0].checked)
        fetch_recommendations(user, data.paginator.next_uri);
    }
  });
}

function create_film(film) {
  var item = $("<li class='film'>")
  item.attr('id', 'permalink_'+film.permalink);
  $("<img class='poster'>").
    attr("src", 'http://filmaster.pl'+(film.image || 'img/default_poster.png')).appendTo(item)
  $("<h3>").append(
    $("<a>").
       attr('href', 'http://filmaster.pl/film/'+film.permalink).
       text(film.title_localized)
  ).appendTo(item);
  $("<p style='float:left' class='rating'>").text(Math.floor(film.guess_rating*10)/10).
    appendTo(item);
  $("<p class='info'>").text(
    film.title + ', ' + film.release_year + ', ' + film.directors[0].name + ' ' + film.directors[0].surname
  ).appendTo(item)
  return item
}

function add_user(user) {
    var u = $("<li>")
    var inp = $("<input type='checkbox' class='user'>").attr('id', 'user_'+user.username).appendTo(u);
    $("<label>").attr('for','user_'+user.username).text(user.username).appendTo(u);
    $('#users').append(u);
    inp.change(function() {
      if(this.checked)
        fetch_recommendations(user, user.recommendations_uri + '?include=guess_rating');
      else 
        show_common_recommendations();
    });
}

function fetch_collection(uri, cb) {
   uri = jsonp_uri(uri);
   $.getJSON(uri, null, function(data, status) {
       cb(data.objects);
       if(data.paginator && data.paginator.next_uri)
           fetch_collection(data.paginator.next_uri, cb);
   });
}

function fetch_user() {
  var username = $(this).val();
  var user_uri = jsonp_uri('/1.0/user/' + username + '/');
  $.getJSON(user_uri, null, function(data, status) {
    $('#users').empty();
    $('#results').empty();
    add_user(data);
    $('#users').append($('<li>').html('<i>and friends he follows:</i>'));
    $('#results').append($('<li>').html('<i>mark users to see their common movie recommendations...</i>'));
    fetch_collection('/1.0/user/' + username + '/following/?include=user', function(data) {
      $(data).each(function() {
        add_user(this.user)
      });
    });
  });
}

function init() {
  $('#username').change(fetch_user);
/*  
  add_user(profile);  
  $(friends).each(function(){add_user(this);});
  $('#users').sortable({update:function(ev, ui) {
    $('#results li.film').remove();
    show_common_recommendations();
  }} )
  $('#results').sortable()*/  
}
$(document).ready(init);
</script>
</head>

<body>
<div><a href="">Reload page</a> <a href="https://bitbucket.org/mrk/filmaster-api-sample" style="float:right">Source code</a>
</div>
<h1>Filmaster API sample - common movie recommendations</h1>

<div id="content">
<div>
  Enter filmaster username: <input type="text" id="username" />
</div>
<ul id="users">
</ul>
<ul id="results">
</ul>
</div>
</body>
</html>