Skip to content

Commit

Permalink
#799 Custom filters
Browse files Browse the repository at this point in the history
  • Loading branch information
Mizzick committed Aug 2, 2017
1 parent 49c763e commit ec7d661
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 11 deletions.
15 changes: 15 additions & 0 deletions Extension/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@
"options_update_antibanner_filters": {
"message": "Check for filter updates"
},
"options_add_custom_filter": {
"message": "Add custom filter"
},
"options_edit_antibanner_filters": {
"message": "All filters"
},
Expand Down Expand Up @@ -542,6 +545,18 @@
"alert_popup_filter_enabled_text": {
"message": "\u00ab$1\u00bb has been activated automatically"
},
"alert_popup_custom_filter_added_title": {
"message": "Custom filter downloaded"
},
"alert_popup_custom_filter_added_text": {
"message": "Custom filter downloaded successfully"
},
"alert_popup_custom_filter_error_title": {
"message": "Custom filter error"
},
"alert_popup_custom_filter_error_text": {
"message": "Custom filter downloading error"
},
"filter_download_title": {
"message": "Filters database is loading..."
},
Expand Down
3 changes: 3 additions & 0 deletions Extension/lib/content-message-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@
case 'checkAntiBannerFiltersUpdate':
adguard.ui.checkFiltersUpdates();
break;
case 'addCustomFilter':
adguard.ui.addCustomFilter(message.url);
break;
case 'changeDefaultWhiteListMode':
adguard.whitelist.changeDefaultWhiteListMode(message.enabled);
break;
Expand Down
101 changes: 91 additions & 10 deletions Extension/lib/filter/antibanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,22 +231,31 @@ adguard.antiBannerService = (function (adguard) {
/**
* Select filters for update. It depends on the time of last update.
* @param forceUpdate Force update flag.
* @returns {Array}
* @returns object
*/
function selectFilterIdsToUpdate(forceUpdate) {
var filterIds = [];
var customFilterIds = [];
var filters = adguard.subscriptions.getFilters();
for (var i = 0; i < filters.length; i++) {
var filter = filters[i];
if (filter.installed && filter.enabled) {
// Check filters update period (or forceUpdate flag)
var needUpdate = forceUpdate || (!filter.lastCheckTime || (Date.now() - filter.lastCheckTime) >= UPDATE_FILTERS_PERIOD);
if (needUpdate) {
filterIds.push(filter.filterId);
if (filter.customUrl) {
customFilterIds.push(filter.filterId);
} else {
filterIds.push(filter.filterId);
}
}
}
}
return filterIds;

return {
filterIds: filterIds,
customFilterIds: customFilterIds
};
}

/**
Expand Down Expand Up @@ -274,16 +283,19 @@ adguard.antiBannerService = (function (adguard) {
adguard.console.info("Start checking filters updates");

// Select filters for update
var filterIdsToUpdate = selectFilterIdsToUpdate(forceUpdate);
var toUpdate = selectFilterIdsToUpdate(forceUpdate);
var filterIdsToUpdate = toUpdate.filterIds;
var customFilterIdsToUpdate = toUpdate.customFilterIds;

if (filterIdsToUpdate.length === 0) {
var totalToUpdate = filterIdsToUpdate.length + customFilterIdsToUpdate.length;
if (totalToUpdate === 0) {
if (successCallback) {
successCallback([]);
return;
}
}

adguard.console.info("Checking updates for {0} filters", filterIdsToUpdate.length);
adguard.console.info("Checking updates for {0} filters", totalToUpdate);

// Load filters with changed version
var loadFiltersFromBackendCallback = function (filterMetadataList) {
Expand All @@ -296,7 +308,10 @@ adguard.antiBannerService = (function (adguard) {
filters.push(filter);
}
}
successCallback(filters);

updateCustomFilters(customFilterIdsToUpdate, function (customFilters) {
successCallback(filters.concat(customFilters));
});
} else {
errorCallback();
}
Expand Down Expand Up @@ -326,6 +341,42 @@ adguard.antiBannerService = (function (adguard) {
loadFiltersMetadataFromBackend(filterIdsToUpdate, onLoadFilterMetadataList);
};

/**
* Update filters with custom urls
*
* @param customFilterIds
* @param callback
*/
function updateCustomFilters (customFilterIds, callback) {
if (customFilterIds.length === 0) {
callback([]);
return;
}

var dfds = [];
var filters = [];
for (var i = 0; i < customFilterIds.length; i++) {
var filter = adguard.subscriptions.getFilter(customFilterIds[i]);
filters.push(filter);

dfds.push((function (filterUrl) {
var dfd = new adguard.utils.Promise();

adguard.subscriptions.updateCustomFilter(filterUrl, function () {
dfd.resolve();
});

return dfd;
})(filter.customUrl));

}

adguard.utils.Promise.all(dfds).then(function () {
adguard.console.info("Custom filters updated");
callback(filters);
});
}

/**
* Resets all filters versions
*/
Expand Down Expand Up @@ -1462,9 +1513,7 @@ adguard.filters = (function (adguard) {
var filterMetadata = findFilterMetadataBySubscriptionUrl(subscriptionUrl);

if (filterMetadata) {

addAndEnableFilters([filterMetadata.filterId]);

} else {

// Load filter rules
Expand All @@ -1477,6 +1526,36 @@ adguard.filters = (function (adguard) {
}
};

/**
* Loads filter rules from url, then tries to parse header to filter metadata
* and adds filter object to subscriptions from it.
* These custom filters will have special attribute customUrl, from there it could be downloaded and updated.
*
* @param url custom url, there rules are
* @param successCallback
* @param errorCallback
*/
var loadCustomFilter = function (url, successCallback, errorCallback) {
adguard.console.info('Downloading custom filter from {0}', url);

adguard.subscriptions.updateCustomFilter(url, function (filterId) {
if (filterId) {
antiBannerService.addAntiBannerFilter(filterId, function (success) {
if (success) {
enableFilter(filterId);

adguard.console.info('Custom filter downloaded and enabled');
successCallback();
} else {
errorCallback();
}
});
} else {
errorCallback();
}
});
};

return {

start: start,
Expand All @@ -1497,7 +1576,9 @@ adguard.filters = (function (adguard) {
removeFilter: removeFilter,

findFilterMetadataBySubscriptionUrl: findFilterMetadataBySubscriptionUrl,
processAbpSubscriptionUrl: processAbpSubscriptionUrl
processAbpSubscriptionUrl: processAbpSubscriptionUrl,

loadCustomFilter: loadCustomFilter
};

})(adguard);
96 changes: 95 additions & 1 deletion Extension/lib/filter/subscription.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,99 @@ adguard.subscriptions = (function (adguard) {
return new SubscriptionFilter(filterId, groupId, defaultName, defaultDescription, homepage, version, timeUpdated, displayNumber, languages, expires, subscriptionUrl);
};

/**
* Parses filter metadata from rules header
*
* @param rules
* @returns object
*/
var parseFilterDataFromHeader = function (rules) {
function parseTag(tagName) {
var result = '';

//Look up only 50 first lines
for (var i = 0; i < 50; i++) {
var r = rules[i];

var search = '! ' + tagName + ': ';
var indexOf = r.indexOf(search);
if (indexOf >= 0) {
result = r.substring(indexOf + search.length);
}
}

return result;
}

return {
name: parseTag('Title'),
description: parseTag('Description'),
homepage: parseTag('Homepage'),
version: parseTag('Version'),
timeUpdated: parseTag('TimeUpdated'),
expires: parseTag('Expires')
}
};

var addFilterId = function () {
var max = 0;
filters.forEach(function (f) {
if (f.filterId > max) {
max = f.filterId;
}
});

return max >= 1000 ? max + 1 : 1000;
};

/**
* Adds or updates custom filter
*
* @param url subscriptionUrl
* @param callback
*/
var updateCustomFilter = function (url, callback) {

adguard.backend.loadFilterRulesBySubscriptionUrl(url, function (rules) {
//Check if filter from this url was added before
var filter = filters.find(function (f) {
return f.customUrl === url;
});

if (!filter) {
var filterData = parseFilterDataFromHeader(rules);

var filterId = addFilterId();
var groupId = 0;
var defaultName = filterData.name;
var defaultDescription = filterData.description;
var homepage = filterData.homepage;
var version = filterData.version;
var timeUpdated = parseTimeUpdated(filterData.timeUpdated);
var expires = filterData.expires - 0;
var subscriptionUrl = url;
var languages = [];
var displayNumber = 0;

filter = new SubscriptionFilter(filterId, groupId, defaultName, defaultDescription, homepage, version, timeUpdated, displayNumber, languages, expires, subscriptionUrl);
filter.loaded = true;
//custom filters have special field
filter.customUrl = url;

filters.push(filter);
filtersMap[filter.filterId] = filter;
}

adguard.rulesStorage.write(filter.filterId, rules, function () {
callback(filter.filterId);
});

}, function (request, cause) {
adguard.console.error("Error download filter by url {0}, cause: {1} {2}", url, request.statusText, cause || "");
callback();
});
};

/**
* Load groups and filters metadata
*
Expand Down Expand Up @@ -287,7 +380,8 @@ adguard.subscriptions = (function (adguard) {
getGroups: getGroups,
getFilters: getFilters,
getFilter: getFilter,
createSubscriptionFilterFromJSON: createSubscriptionFilterFromJSON
createSubscriptionFilterFromJSON: createSubscriptionFilterFromJSON,
updateCustomFilter: updateCustomFilter
};

})(adguard);
Expand Down
9 changes: 9 additions & 0 deletions Extension/lib/pages/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,14 @@ var AntiBannerFilters = function (options) {
});
}

function addCustomFilter(e) {
e.preventDefault();

var url = $('#customFilterUrl').val();
contentPage.sendMessage({type: 'addCustomFilter', url: url}, function () {
});
}

function setLastUpdatedTimeText(lastUpdateTime) {
if (lastUpdateTime && lastUpdateTime > loadedFiltersInfo.lastUpdateTime) {
loadedFiltersInfo.lastUpdateTime = lastUpdateTime;
Expand Down Expand Up @@ -788,6 +796,7 @@ var AntiBannerFilters = function (options) {
// Bind events
$(document).on('change', '.filters-list [name="filterId"]', toggleFilterState);
$('#updateAntiBannerFilters').on('click', updateAntiBannerFilters);
$('#addCustomFilter').on('click', addCustomFilter);

updateRulesCountInfo(options.rulesInfo);

Expand Down
Loading

0 comments on commit ec7d661

Please sign in to comment.