Index: lib/synchronizer.js |
=================================================================== |
--- a/lib/synchronizer.js |
+++ b/lib/synchronizer.js |
@@ -19,22 +19,20 @@ |
/** |
* @fileOverview Manages synchronization of filter subscriptions. |
*/ |
const {Downloader, Downloadable, |
MILLIS_IN_SECOND, MILLIS_IN_MINUTE, |
MILLIS_IN_HOUR, MILLIS_IN_DAY} = require("downloader"); |
-const {Filter} = require("filterClasses"); |
const {FilterStorage} = require("filterStorage"); |
const {FilterNotifier} = require("filterNotifier"); |
const {Prefs} = require("prefs"); |
const {Subscription, DownloadableSubscription} = require("subscriptionClasses"); |
-const {Utils} = require("utils"); |
const INITIAL_DELAY = 1 * MILLIS_IN_MINUTE; |
const CHECK_INTERVAL = 1 * MILLIS_IN_HOUR; |
const DEFAULT_EXPIRATION_INTERVAL = 5 * MILLIS_IN_DAY; |
/** |
* The object providing actual downloading functionality. |
* @type {Downloader} |
@@ -148,148 +146,91 @@ |
redirectCallback) |
{ |
let lines = responseText.split(/[\r\n]+/); |
let headerMatch = /\[Adblock(?:\s*Plus\s*([\d.]+)?)?\]/i.exec(lines[0]); |
if (!headerMatch) |
return errorCallback("synchronize_invalid_data"); |
let minVersion = headerMatch[1]; |
- // Don't remove parameter comments immediately but add them to a list first, |
- // they need to be considered in the checksum calculation. |
- let remove = []; |
- let params = { |
- redirect: null, |
- homepage: null, |
- title: null, |
- version: null, |
- expires: null |
- }; |
- for (let i = 0; i < lines.length; i++) |
+ let parser = DownloadableSubscription.parseDownload(); |
+ |
+ // Process filters |
+ for (let line of lines) |
+ parser.process(line); |
+ |
+ if (parser.redirect) |
{ |
- let match = /^\s*!\s*(\w+)\s*:\s*(.*)/.exec(lines[i]); |
- if (match) |
- { |
- let keyword = match[1].toLowerCase(); |
- let value = match[2]; |
- if (keyword in params) |
- { |
- params[keyword] = value; |
- remove.push(i); |
- } |
- else if (keyword == "checksum") |
- { |
- lines.splice(i--, 1); |
- let checksum = Utils.generateChecksum(lines); |
- if (checksum && checksum != value.replace(/=+$/, "")) |
- return errorCallback("synchronize_checksum_mismatch"); |
- } |
- } |
+ let {redirect} = parser; |
+ parser.delete(); |
+ return redirectCallback(redirect); |
} |
- if (params.redirect) |
- return redirectCallback(params.redirect); |
- |
// Handle redirects |
let subscription = Subscription.fromURL(downloadable.redirectURL || |
downloadable.url); |
if (downloadable.redirectURL && |
downloadable.redirectURL != downloadable.url) |
{ |
let oldSubscription = Subscription.fromURL(downloadable.url); |
subscription.title = oldSubscription.title; |
subscription.disabled = oldSubscription.disabled; |
subscription.lastCheck = oldSubscription.lastCheck; |
- let listed = (oldSubscription.url in FilterStorage.knownSubscriptions); |
+ let {listed} = oldSubscription; |
if (listed) |
FilterStorage.removeSubscription(oldSubscription); |
- delete Subscription.knownSubscriptions[oldSubscription.url]; |
- |
if (listed) |
FilterStorage.addSubscription(subscription); |
} |
// The download actually succeeded |
subscription.lastSuccess = subscription.lastDownload = Math.round( |
Date.now() / MILLIS_IN_SECOND |
); |
subscription.downloadStatus = "synchronize_ok"; |
subscription.downloadCount = downloadable.downloadCount; |
subscription.errors = 0; |
- // Remove lines containing parameters |
- for (let i = remove.length - 1; i >= 0; i--) |
- lines.splice(remove[i], 1); |
- |
// Process parameters |
- if (params.homepage) |
+ if (parser.homepage) |
{ |
let url; |
try |
{ |
- url = new URL(params.homepage); |
+ url = new URL(parser.homepage); |
} |
catch (e) |
{ |
url = null; |
} |
if (url && (url.protocol == "http:" || url.protocol == "https:")) |
subscription.homepage = url.href; |
} |
- if (params.title) |
- { |
- subscription.title = params.title; |
- subscription.fixedTitle = true; |
- } |
+ if (minVersion) |
+ subscription.requiredVersion = minVersion; |
else |
- subscription.fixedTitle = false; |
- |
- subscription.version = (params.version ? parseInt(params.version, 10) : 0); |
+ delete subscription.requiredVersion; |
let expirationInterval = DEFAULT_EXPIRATION_INTERVAL; |
- if (params.expires) |
- { |
- let match = /^(\d+)\s*(h)?/.exec(params.expires); |
- if (match) |
- { |
- let interval = parseInt(match[1], 10); |
- if (match[2]) |
- expirationInterval = interval * MILLIS_IN_HOUR; |
- else |
- expirationInterval = interval * MILLIS_IN_DAY; |
- } |
- } |
+ let expiration = parser.finalize(subscription); |
+ if (expiration != 0) |
+ expirationInterval = expiration; |
let [ |
softExpiration, |
hardExpiration |
] = downloader.processExpirationInterval(expirationInterval); |
subscription.softExpiration = Math.round(softExpiration / MILLIS_IN_SECOND); |
subscription.expires = Math.round(hardExpiration / MILLIS_IN_SECOND); |
- if (minVersion) |
- subscription.requiredVersion = minVersion; |
- else |
- delete subscription.requiredVersion; |
- |
- // Process filters |
- lines.shift(); |
- let filters = []; |
- for (let line of lines) |
- { |
- line = Filter.normalize(line); |
- if (line) |
- filters.push(Filter.fromText(line)); |
- } |
- |
- FilterStorage.updateSubscriptionFilters(subscription, filters); |
+ parser.delete(); |
return undefined; |
}, |
_onDownloadError(downloadable, downloadURL, error, channelStatus, |
responseStatus, redirectCallback) |
{ |
let subscription = Subscription.fromURL(downloadable.url); |
@@ -329,29 +270,29 @@ |
request.channel.loadFlags = request.channel.loadFlags | |
request.channel.INHIBIT_CACHING | |
request.channel.VALIDATE_ALWAYS; |
request.addEventListener("load", ev => |
{ |
if (onShutdown.done) |
return; |
- if (!(subscription.url in FilterStorage.knownSubscriptions)) |
+ if (!subscription.listed) |
return; |
let match = /^(\d+)(?:\s+(\S+))?$/.exec(request.responseText); |
if (match && match[1] == "301" && // Moved permanently |
match[2] && /^https?:\/\//i.test(match[2])) |
{ |
redirectCallback(match[2]); |
} |
else if (match && match[1] == "410") // Gone |
{ |
let data = "[Adblock]\n" + |
- subscription.filters.map(f => f.text).join("\n"); |
+ Array.from(subscription.filters, f => f.text).join("\n"); |
redirectCallback("data:text/plain," + encodeURIComponent(data)); |
} |
}, false); |
request.send(null); |
} |
} |
} |
}; |