Skip to content
This repository has been archived by the owner on Oct 11, 2022. It is now read-only.

Commit

Permalink
Merge pull request #9 from tegon/viewing-activity
Browse files Browse the repository at this point in the history
Sync previous Viewing activity
  • Loading branch information
tegon committed Oct 27, 2015
2 parents 1c82cc4 + 4173f61 commit 508ae3f
Show file tree
Hide file tree
Showing 39 changed files with 1,435 additions and 109 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Expand Up @@ -9,8 +9,8 @@ package
build
*.log
.DS_Store
app/scripts/src/settings.js
*.crx
*.pem
coverage
app.zip
app.zip
config.json
2 changes: 0 additions & 2 deletions .travis.yml
Expand Up @@ -3,8 +3,6 @@ node_js:
- "0.10"
- "0.11"
- "0.12"
before_script:
- cp settings.js.dev app/scripts/src/settings.js
script: "npm test"
after_script:
- "cat ./coverage/**/lcov.info | ./node_modules/coveralls/bin/coveralls.js"
8 changes: 4 additions & 4 deletions README.md
Expand Up @@ -4,7 +4,7 @@
[![Build Status](https://travis-ci.org/tegon/traktflix.svg?branch=master)](https://travis-ci.org/tegon/traktflix)
[![Coverage Status](https://coveralls.io/repos/tegon/traktflix/badge.svg?branch=master&service=github)](https://coveralls.io/github/tegon/traktflix?branch=master)

[![download](ChromeWebStore_BadgeWBorder_v2_206x58.png)](https://chrome.google.com/webstore/detail/bmoemkaigjgcgjjnpmdgkifndiidkeji)
[![download](ChromeWebStore_BadgeWBorder_v2_206x58.png)](https://chrome.google.com/webstore/detail/bmoemkaigjgcgjjnpmdgkifndiidkeji?utm_source=github&utm_medium=readme& utm_campaign=repo)

###Table of Contents
* [What is Trakt?](#what-is-trakt)
Expand Down Expand Up @@ -41,9 +41,9 @@ In `Redirect uri:` put `https://{extensionId}.chromiumapp.org`

In `Javascript (cors) origins:` put `https://{extensionId}.chromiumapp.org` and `chrome-extension://{extensionId}`

Copy the `settings.js` example file and change Trakt.tv credentials:
Copy the `config.json` example file and change Trakt.tv credentials:
```bash
cp settings.js.dev app/scripts/src/settings.js
cp config.json.dev config.json
```

Use [nvm](https://github.com/creationix/nvm) to run in the correct version of node
Expand Down Expand Up @@ -73,4 +73,4 @@ To run tests
npm test
```

[LICENSE](LICENSE-MIT)
[LICENSE](LICENSE)
7 changes: 4 additions & 3 deletions app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "__MSG_appName__",
"short_name": "__MSG_appShortName__",
"version": "1.0.4.4575",
"version": "1.0.5",
"manifest_version": 2,
"description": "__MSG_appDescription__",
"icons": {
Expand All @@ -18,7 +18,7 @@
"content_scripts": [
{
"matches": [
"http://*.netflix.com/*"
"*://*.netflix.com/*"
],
"js": [
"scripts/build/content.js"
Expand All @@ -44,7 +44,8 @@
"storage",
"unlimitedStorage",
"http://trakt.tv/*",
"https://www.google-analytics.com/"
"https://www.google-analytics.com/",
"*://*.netflix.com/*"
],
"web_accessible_resources": [
"images/svg/*.svg"
Expand Down
12 changes: 10 additions & 2 deletions app/scripts/src/background/background.js
Expand Up @@ -44,8 +44,16 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
case 'sendEvent':
Analytics.sendEvent(request.name, request.value);
break;
case 'getCurrentToken':
chrome.storage.local.get('access_token', sendResponse);
case 'getStorageValue':
chrome.storage.local.get(request.key, sendResponse);
return true;
break;
case 'setStorageValue':
chrome.storage.local.set(request.value, sendResponse);
return true;
break;
case 'clearStorage':
chrome.storage.local.clear(sendResponse);
return true;
break;
}
Expand Down
35 changes: 35 additions & 0 deletions app/scripts/src/chrome-storage.js
@@ -0,0 +1,35 @@
'use strict';

function ChromeStorage() {};

// Returns if window is not content_script, which sometimes fails to call chrome.storage
// If it is, send a message so that background script handle chrome.storage calls
ChromeStorage.isAvailable = function() {
return !!chrome.tabs;
};

ChromeStorage.get = function(key, callback) {
if (ChromeStorage.isAvailable()) {
chrome.storage.local.get(key, callback);
} else {
chrome.runtime.sendMessage({ type: 'getStorageValue', key: key }, callback);
}
};

ChromeStorage.set = function(value, callback) {
if (ChromeStorage.isAvailable()) {
chrome.storage.local.set(value, callback);
} else {
chrome.runtime.sendMessage({ type: 'setStorageValue', value: value }, callback);
}
};

ChromeStorage.clear = function(callback) {
if (ChromeStorage.isAvailable()) {
chrome.storage.local.clear(callback);
} else {
chrome.runtime.sendMessage({ type: 'clearStorage' }, callback);
}
};

module.exports = ChromeStorage;
17 changes: 16 additions & 1 deletion app/scripts/src/content/content.js
Expand Up @@ -2,8 +2,9 @@

var WatchEvents = require('./watch-events.js');
var ContentController = require('./content-controller.js');

var Sync = require('./sync.js');
var controller = new ContentController();
var sync = new Sync();

var events = new WatchEvents({
onPlay: controller.onPlay.bind(controller),
Expand All @@ -12,9 +13,23 @@ var events = new WatchEvents({
});

events.startListeners();
sync.needToSync(function(needToSync) {
if (needToSync) {
sync.start(function(success) {
console.log('sync completed', success);
});
}
});

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.type == 'getCurrentItem') {
sendResponse(controller.getCurrentItem());
}
});

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.type == 'startSync') {
sync.start(sendResponse);
return true;
}
});
47 changes: 35 additions & 12 deletions app/scripts/src/content/search.js
Expand Up @@ -15,11 +15,16 @@ Search.prototype = {
},

getEpisodeUrl: function(slug) {
return this.showsUrl + '/' + slug + '/seasons/' + this.item.season
+ '/episodes/' + this.item.episode + '?extended=images';
if (this.item.episode) {
return this.showsUrl + '/' + slug + '/seasons/' + this.item.season
+ '/episodes/' + this.item.episode + '?extended=images';
} else {
return this.showsUrl + '/' + slug + '/seasons/' + this.item.season
+ '?extended=images';
}
},

findMovie: function(options) {
findItem: function(options) {
Request.send({
method: 'GET',
url: this.getUrl(),
Expand All @@ -33,19 +38,37 @@ Search.prototype = {
});
},

findEpisodeByTitle: function(response, options) {
var episodes = JSON.parse(response);
var episode;

for (var i = 0; i < episodes.length; i++) {
if (episodes[i].title === this.item.epTitle) {
episode = episodes[i];
break;
}
}

if (episode) {
options.success.call(this, episode);
} else {
options.error.call(this, 404, 'Episode not found.');
}
},

findEpisode: function(options) {
Request.send({
method: 'GET',
url: this.getUrl(),
this.findItem({
success: function(response) {
var data = JSON.parse(response)[0];

Request.send({
method: 'GET',
url: this.getEpisodeUrl(data['show']['ids']['slug']),
url: this.getEpisodeUrl(response['show']['ids']['slug']),
success: function(resp) {
options.success.call(this, JSON.parse(resp));
},
if (this.item.episode) {
options.success.call(this, JSON.parse(resp));
} else {
this.findEpisodeByTitle(resp, options);
}
}.bind(this),
error: function(st, resp) {
options.error.call(this, st, resp);
}
Expand All @@ -61,7 +84,7 @@ Search.prototype = {
if (this.item.type == 'show') {
this.findEpisode(options);
} else {
this.findMovie(options);
this.findItem(options);
}
}
};
Expand Down
94 changes: 94 additions & 0 deletions app/scripts/src/content/sync.js
@@ -0,0 +1,94 @@
'use strict';

var ViewingActivity = require('./viewing-activity.js');
var ViewingActivityParser = require('./viewing-activity-parser.js');
var WatchedHistory = require('./watched-history.js');
var ChromeStorage = require('../chrome-storage.js');
var Oauth = require('../oauth.js');
var async = require('async');

function Sync() {
this.history = new WatchedHistory();
};

Sync.prototype = {
needToSync: function(callback) {
Oauth.getUserInfo(function() {
ChromeStorage.get(null, function(data) {
if (data.auto_sync) {
var today = new Date();
today.setHours(0, 0, 0, 0);
var lastSync = new Date(data.synced_at);
lastSync.setHours(0, 0, 0, 0);
var needToSync = !data.synced_at || today > lastSync;
callback.call(this, needToSync);
} else {
callback.call(this, false);
}
});
}, function() {
callback.call(this, false);
});
},

start: function(callback) {
this.callback = callback;
this.onSyncStart();
},

onSyncStart: function() {
ChromeStorage.get('synced_at', function(data) {
ViewingActivity.list({
success: function(response) {
ViewingActivityParser.start({
data: response,
callback: this.syncActivities.bind(this),
syncedAt: data.synced_at
});
}.bind(this),
error: this.onError.bind(this)
});
}.bind(this));
},

syncActivities: function(activities) {
if (activities.length > 0) {
async.filter(activities, this.syncActivity.bind(this), function(activities) {
if (activities.length > 0) {
this.history.send(activities, this.onCompleted.bind(this));
} else {
this.onCompleted(true);
}
}.bind(this));
} else {
this.onCompleted(true);
}
},

onCompleted: function(success) {
if (success) {
var now = new Date();
ChromeStorage.set({ 'synced_at': now.toISOString() }, function() {});
}

this.callback.call(this, success);
},

syncActivity: function(activity, callback) {
this.history.include({
activity: activity,
success: function(include) {
callback(!include);
},
error: function(status, response) {
callback(true);
}
});
},

onError: function(status, response) {
console.error('traktflix: Sync error', status, response);
}
};

module.exports = Sync;

0 comments on commit 508ae3f

Please sign in to comment.