2017-04-20 18:27:10 +00:00
|
|
|
/* globals getStyles, saveStyle, styleSectionsEqual */
|
2017-02-08 15:15:35 +00:00
|
|
|
'use strict';
|
|
|
|
|
2017-04-20 18:27:10 +00:00
|
|
|
// eslint-disable-next-line no-var
|
|
|
|
var updater = {
|
2017-02-08 15:15:35 +00:00
|
|
|
|
2017-04-20 18:27:10 +00:00
|
|
|
COUNT: 'count',
|
|
|
|
UPDATED: 'updated',
|
|
|
|
SKIPPED: 'skipped',
|
|
|
|
SKIPPED_SAME_MD5: 'up-to-date: MD5 is unchanged',
|
|
|
|
SKIPPED_SAME_CODE: 'up-to-date: code sections are unchanged',
|
|
|
|
SKIPPED_ERROR_MD5: 'error: MD5 is invalid',
|
|
|
|
SKIPPED_ERROR_JSON: 'error: JSON is invalid',
|
|
|
|
DONE: 'done',
|
2017-02-08 15:15:35 +00:00
|
|
|
|
2017-04-20 18:27:10 +00:00
|
|
|
lastUpdateTime: parseInt(localStorage.lastUpdateTime) || Date.now(),
|
2017-02-08 15:15:35 +00:00
|
|
|
|
2017-04-21 12:33:28 +00:00
|
|
|
checkAllStyles(observe = () => {}, {save = true} = {}) {
|
2017-04-20 18:27:10 +00:00
|
|
|
updater.resetInterval();
|
|
|
|
return new Promise(resolve => {
|
|
|
|
getStyles({}, styles => {
|
|
|
|
styles = styles.filter(style => style.updateUrl);
|
|
|
|
observe(updater.COUNT, styles.length);
|
|
|
|
Promise.all(styles.map(style =>
|
2017-04-21 12:33:28 +00:00
|
|
|
updater.checkStyle(style, observe, {save})
|
2017-04-20 18:27:10 +00:00
|
|
|
)).then(() => {
|
|
|
|
observe(updater.DONE);
|
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
});
|
2017-02-08 15:15:35 +00:00
|
|
|
});
|
2017-04-20 18:27:10 +00:00
|
|
|
},
|
|
|
|
|
2017-04-21 12:33:28 +00:00
|
|
|
checkStyle(style, observe = () => {}, {save = true} = {}) {
|
2017-04-20 18:27:10 +00:00
|
|
|
return download(style.md5Url)
|
|
|
|
.then(md5 =>
|
|
|
|
!md5 || md5.length != 32 ? Promise.reject(updater.SKIPPED_ERROR_MD5) :
|
|
|
|
md5 == style.originalMd5 ? Promise.reject(updater.SKIPPED_SAME_MD5) :
|
|
|
|
style.updateUrl)
|
|
|
|
.then(download)
|
|
|
|
.then(text => tryJSONparse(text))
|
|
|
|
.then(json =>
|
|
|
|
!updater.styleJSONseemsValid(json) ? Promise.reject(updater.SKIPPED_ERROR_JSON) :
|
|
|
|
styleSectionsEqual(json, style) ? Promise.reject(updater.SKIPPED_SAME_CODE) :
|
|
|
|
// keep the local name as it could've been customized by the user
|
|
|
|
Object.assign(json, {
|
|
|
|
id: style.id,
|
|
|
|
name: null,
|
2017-04-21 12:33:28 +00:00
|
|
|
reason: 'update',
|
|
|
|
}))
|
|
|
|
.then(json => save ? saveStyle(json) : json)
|
|
|
|
.then(saved => observe(updater.UPDATED, saved))
|
|
|
|
.catch(err => observe(updater.SKIPPED, style, err));
|
2017-04-20 18:27:10 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
styleJSONseemsValid(json) {
|
|
|
|
return json
|
|
|
|
&& json.sections
|
|
|
|
&& json.sections.length
|
|
|
|
&& typeof json.sections.every == 'function'
|
|
|
|
&& typeof json.sections[0].code == 'string';
|
|
|
|
},
|
|
|
|
|
|
|
|
schedule() {
|
|
|
|
const interval = prefs.get('updateInterval') * 60 * 60 * 1000;
|
2017-02-14 15:35:53 +00:00
|
|
|
if (interval) {
|
2017-04-20 18:27:10 +00:00
|
|
|
const elapsed = Math.max(0, Date.now() - updater.lastUpdateTime);
|
|
|
|
debounce(updater.checkAllStyles, Math.max(10e3, interval - elapsed));
|
|
|
|
} else if (debounce.timers) {
|
|
|
|
debounce.unregister(updater.checkAllStyles);
|
2017-02-14 15:35:53 +00:00
|
|
|
}
|
2017-04-20 18:27:10 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
resetInterval() {
|
|
|
|
localStorage.lastUpdateTime = updater.lastUpdateTime = Date.now();
|
|
|
|
updater.schedule();
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
updater.schedule();
|
|
|
|
prefs.subscribe(updater.schedule, ['updateInterval']);
|