Skip to content

Commit 3b80f23

Browse files
committed
2.0.0: Tons of improvements. Sync history (finally), get images from tmdb.
1 parent cbeb124 commit 3b80f23

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+10167
-502
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ build
1313
*.pem
1414
coverage
1515
app.zip
16-
config.json
16+
config.json
17+
.idea/

.jshintrc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
"latedef": true,
1212
"newcap": true,
1313
"noarg": true,
14-
"quotmark": "single",
1514
"regexp": true,
1615
"undef": true,
1716
"unused": true,

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,17 @@ To run tests
7171
npm test
7272
```
7373

74+
### Credits
75+
<h3 align="center">
76+
<a href="https://tegon.github.io/traktflix/">
77+
<img src="https://raw.githubusercontent.com/mrmamen/traktNRK/master/tmdb-api-logo.png" alt="TMDB" width="150">
78+
</a>
79+
<a href="https://tegon.github.io/traktflix/">
80+
<img src="https://raw.githubusercontent.com/mrmamen/traktNRK/master/trakt-api-logo.png" alt="TMDB" width="150">
81+
</a>
82+
</h3>
83+
84+
This product uses the TMDb API but is not endorsed or certified by TMDb. <br>
85+
This product uses the Trakt.tv API.
86+
7487
[LICENSE](LICENSE)

app/history-sync.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
6+
<link rel="stylesheet" type="text/css" href="styles/build/vendor.css">
7+
<link rel="stylesheet" type="text/css" href="styles/build/popup.css">
8+
</head>
9+
<body>
10+
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
11+
<header class="mdl-layout__header">
12+
<div class="mdl-layout__header-row">
13+
<span class="mdl-layout-title">NRK history sync</span>
14+
</div>
15+
</header>
16+
<main class="mdl-layout__content">
17+
<div class="page-content" id="viewing-activity-app"></div>
18+
</main>
19+
</div>
20+
<script type="text/javascript" src="scripts/build/vendor.js"></script>
21+
<script type="text/javascript" src="scripts/build/history-sync.js"></script>
22+
</body>
23+
</html>

app/manifest.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "__MSG_appName__",
33
"short_name": "__MSG_appShortName__",
4-
"version": "1.3.1",
4+
"version": "2.0.0",
55
"manifest_version": 2,
66
"description": "__MSG_appDescription__",
77
"icons": {
@@ -44,7 +44,9 @@
4444
"storage",
4545
"unlimitedStorage",
4646
"http://trakt.tv/*",
47-
"https://www.google-analytics.com/"
47+
"https://www.google-analytics.com/",
48+
"*://*.nrk.no/*",
49+
"notifications"
4850
],
4951
"web_accessible_resources": [
5052
"images/svg/*.svg"

app/scripts/src/background/background.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ var Analytics = require('./analytics.js');
44
var Oauth = require('../oauth.js');
55
var Settings = require('../settings.js');
66
var service = analytics.getService('traktNRK');
7+
var rollbar = require('../rollbar.js');
78
var tracker = service.getTracker(Settings.analyticsId);
89
Analytics.setTracker(tracker);
910

@@ -56,5 +57,13 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
5657
chrome.storage.local.clear(sendResponse);
5758
return true;
5859
break;
60+
case 'showErrorNotification':
61+
chrome.notifications.create({
62+
type: 'basic',
63+
iconUrl: 'images/traktflix-icon-128.png',
64+
title: 'An error has occurred :(',
65+
message: request.message
66+
});
67+
break;
5968
}
60-
});
69+
});

app/scripts/src/content/content-controller.js

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
var ItemParser = require('./item-parser.js');
44
var Search = require('./search.js');
55
var Scrobble = require('./scrobble.js');
6+
var Rollbar = require('../rollbar.js');
7+
var ChromeStorage = require('../chrome-storage.js');
68

79
function ContentController() {
810
this.item = null;
@@ -25,18 +27,20 @@ ContentController.prototype = {
2527
});
2628
},
2729

28-
onSearchError: function(status, response) {
30+
onSearchError: function(status, response, options) {
2931
this.sendAnalyticsEvent({ name: 'onSearchError', value: status + ' - ' + this.item.title });
30-
console.error('traktNRK: Search error', status, response, this.item.title);
32+
console.log('traktNRK: Search error', status, response, options, this.item.title);
33+
this.reportError('Search', status, response, options);
3134
},
3235

3336
onScrobbleSuccess: function() {
3437
this.sendAnalyticsEvent({ name: 'Scrobble', value: 'onSuccess' });
3538
},
3639

37-
onScrobbleError: function() {
40+
onScrobbleError: function(status, response, options) {
3841
this.sendAnalyticsEvent({ name: 'Scrobble', value: 'onError' });
39-
console.error('traktNRK: Scrobble error');
42+
console.log('traktNRK: Scrobble error', status, response, options);
43+
this.reportError('Scrobble', status, response, options);
4044
},
4145

4246
storeItem: function(item) {
@@ -94,10 +98,35 @@ ContentController.prototype = {
9498
});
9599
},
96100

101+
showErrorNotification: function(message) {
102+
chrome.runtime.sendMessage({ type: 'showErrorNotification', message: message });
103+
},
104+
105+
reportError: function(type, status, response, options) {
106+
if (status === 404) {
107+
this.showErrorNotification("Oh snap! We couldn't find what you're watching in Trakt.tv. However if you are logged into NRK, you can now sync your history.");
108+
Rollbar.info('traktNRK: ' + type + ' error. Did not find item.', this.item);
109+
} else if (status === 0) {
110+
// status 0 usually means an response without CORS
111+
// It could be a 401, so we check if the user has an access_token saved
112+
ChromeStorage.get(null, function(data) {
113+
if (!!data.access_token) {
114+
this.showErrorNotification("We couldn't talk to Trakt.tv servers. We're trying to fix it, please try again later");
115+
Rollbar.warning('traktflix: ' + type + ' error', { status: status, response: response, options: options });
116+
} else {
117+
this.showErrorNotification("Looks like you're not logged in. Please open the extension and login with your Trakt.tv account");
118+
}
119+
}.bind(this));
120+
} else {
121+
this.showErrorNotification("We couldn't talk to Trakt.tv servers. We're trying to fix it, please try again later");
122+
Rollbar.warning('traktflix: ' + type + ' error', { status: status, response: response, options: options });
123+
}
124+
},
125+
97126
getCurrentItem: function() {
98-
if (this.item && this.item.type === 'show') {
127+
if (this.item && this.scrobble && this.item.type === 'show') {
99128
return { item: this.scrobble.item.episode };
100-
} else if (this.item && this.item.type === 'movie') {
129+
} else if (this.item && this.scrobble && this.item.type === 'movie') {
101130
return { item: this.scrobble.item.movie };
102131
}
103132
}

app/scripts/src/content/content.js

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
var WatchEvents = require('./watch-events.js');
44
var ContentController = require('./content-controller.js');
5-
var Sync = require('./sync.js');
65
var controller = new ContentController();
7-
var sync = new Sync();
6+
var rollbar = require('../rollbar.js');
87

98
var events = new WatchEvents({
109
onPlay: controller.onPlay.bind(controller),
@@ -13,23 +12,9 @@ var events = new WatchEvents({
1312
});
1413

1514
events.startListeners();
16-
sync.needToSync(function(needToSync) {
17-
if (needToSync) {
18-
sync.start(function(success) {
19-
console.log('sync completed', success);
20-
});
21-
}
22-
});
2315

2416
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
2517
if (request.type == 'getCurrentItem') {
2618
sendResponse(controller.getCurrentItem());
2719
}
2820
});
29-
30-
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
31-
if (request.type == 'startSync') {
32-
sync.start(sendResponse);
33-
return true;
34-
}
35-
});

app/scripts/src/content/scrobble.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ function Scrobble(options) {
77
if (options.type === 'show') {
88
this.item = { episode: options.response };
99
} else {
10-
this.item = { movie: options.response.movie };
10+
var movie = options.response.movie || {};
11+
movie.type = 'movie';
12+
this.item = { movie: movie };
1113
}
1214

1315
this.onProgressChange();
@@ -19,8 +21,10 @@ function Scrobble(options) {
1921

2022
Scrobble.prototype = {
2123
startProgressTimeout: function() {
22-
this.progressChangeInterval = setInterval(function() {
24+
this.progressChangeInterval = setTimeout(function() {
2325
this.onProgressChange();
26+
clearTimeout(this.progressChangeInterval);
27+
this.startProgressTimeout();
2428
}.bind(this), 1000);
2529
},
2630

app/scripts/src/content/search.js

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,15 @@ function Search(options) {
1111

1212
Search.prototype = {
1313
getUrl: function() {
14-
return this.url + '?type=' + this.item.type + '&query=' + encodeURIComponent(this.item.title);
14+
return this.url + '/' + this.item.type + '?query=' + encodeURIComponent(this.item.title);
1515
},
1616

1717
getEpisodeUrl: function(slug) {
1818
if (this.item.episode) {
1919
return this.showsUrl + '/' + slug + '/seasons/' + this.item.season
20-
+ '/episodes/' + this.item.episode + '?extended=images';
20+
+ '/episodes/' + this.item.episode;
2121
} else {
22-
return this.showsUrl + '/' + slug + '/seasons/' + this.item.season
23-
+ '?extended=images';
22+
return this.showsUrl + '/' + slug + '/seasons/' + this.item.season;
2423
}
2524
},
2625

@@ -30,60 +29,56 @@ Search.prototype = {
3029
url: this.getUrl(),
3130
success: function(response) {
3231
var data = JSON.parse(response)[0];
33-
if (data == undefined) {
32+
if (data === undefined) {
3433
options.error.call(this, 404);
3534
} else {
3635
options.success.call(this, data);
3736
}
3837
},
39-
error: function(status, response) {
40-
options.error.call(this, status, response);
38+
error: function(status, response, opts) {
39+
options.error.call(this, status, response, opts);
4140
}
4241
});
4342
},
4443

45-
findEpisodeByTitle: function(response, options) {
44+
findEpisodeByTitle: function(show, response, options) {
4645
var episodes = JSON.parse(response);
4746
var episode;
4847

4948
for (var i = 0; i < episodes.length; i++) {
50-
if (episodes[i].title.toLowerCase() === this.item.epTitle.toLowerCase()) {
49+
if (this.item.epTitle && episodes[i].title && episodes[i].title.toLowerCase() === this.item.epTitle.toLowerCase()) {
5150
episode = episodes[i];
5251
break;
5352
}
5453
}
5554

5655
if (episode) {
57-
options.success.call(this, episode);
56+
options.success.call(this, Object.assign(episode, show));
5857
} else {
59-
options.error.call(this, 404, 'Episode not found.');
58+
options.error.call(this, 404, 'Episode not found.', {show: show, item: this.item});
6059
}
6160
},
6261

6362
findEpisode: function(options) {
6463
this.findItem({
6564
success: function(response) {
66-
if (!response) {
67-
options.error.call(this, "200", response);
68-
} else {
69-
Request.send({
70-
method: 'GET',
71-
url: this.getEpisodeUrl(response['show']['ids']['slug']),
72-
success: function(resp) {
73-
if (this.item.episode) {
74-
options.success.call(this, JSON.parse(resp));
75-
} else {
76-
this.findEpisodeByTitle(resp, options);
77-
}
78-
}.bind(this),
79-
error: function(st, resp) {
80-
options.error.call(this, st, resp);
65+
Request.send({
66+
method: 'GET',
67+
url: this.getEpisodeUrl(response['show']['ids']['slug']),
68+
success: function(resp) {
69+
if (this.item.episode) {
70+
options.success.call(this, Object.assign(JSON.parse(resp), response));
71+
} else {
72+
this.findEpisodeByTitle(response, resp, options);
8173
}
82-
});
83-
}
74+
}.bind(this),
75+
error: function(st, resp, opts) {
76+
options.error.call(this, st, resp, opts);
77+
}
78+
});
8479
}.bind(this),
85-
error: function(status, response) {
86-
options.error.call(this, status, response);
80+
error: function(status, response, opts) {
81+
options.error.call(this, status, response, opts);
8782
}
8883
});
8984
},

0 commit comments

Comments
 (0)