summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorÁrni Dagur <arni@dagur.eu>2020-07-27 20:35:50 +0000
committerGitHub <noreply@github.com>2020-07-27 20:35:50 +0000
commit25684535e85a8bbb05b65b0da2304273d1d90ca0 (patch)
treeaad63588ac9eafe99ddd0d3ed847a3726d947271 /src
parentdc35e6044c249261dfc46eff831d5885a993eb0f (diff)
Update upstream library to 0.3.0, respond to API changes (#10)
* Update upstream library to 0.3.0, respond to API changes * Change pypi publishing criteria in CI * Create test to make sure the version numbers are the same everywhere
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs150
1 files changed, 108 insertions, 42 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 588f4e9..7839a42 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,8 +12,10 @@
12 12
13use adblock::blocker::BlockerError as RustBlockerError; 13use adblock::blocker::BlockerError as RustBlockerError;
14use adblock::blocker::BlockerResult as RustBlockerResult; 14use adblock::blocker::BlockerResult as RustBlockerResult;
15use adblock::cosmetic_filter_cache::HostnameSpecificResources as RustHostnameSpecificResources; 15use adblock::cosmetic_filter_cache::UrlSpecificResources as RustUrlSpecificResources;
16use adblock::engine::Engine as RustEngine; 16use adblock::engine::Engine as RustEngine;
17use adblock::lists::FilterFormat;
18use adblock::lists::FilterSet as RustFilterSet;
17use pyo3::class::PyObjectProtocol; 19use pyo3::class::PyObjectProtocol;
18use pyo3::exceptions::ValueError as PyValueError; 20use pyo3::exceptions::ValueError as PyValueError;
19use pyo3::prelude::*; 21use pyo3::prelude::*;
@@ -32,8 +34,9 @@ use std::io::{Read, Write};
32fn adblock(_py: Python<'_>, m: &PyModule) -> PyResult<()> { 34fn adblock(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
33 m.add("__version__", env!("CARGO_PKG_VERSION"))?; 35 m.add("__version__", env!("CARGO_PKG_VERSION"))?;
34 m.add_class::<Engine>()?; 36 m.add_class::<Engine>()?;
37 m.add_class::<FilterSet>()?;
35 m.add_class::<BlockerResult>()?; 38 m.add_class::<BlockerResult>()?;
36 m.add_class::<HostnameSpecificResources>()?; 39 m.add_class::<UrlSpecificResources>()?;
37 Ok(()) 40 Ok(())
38} 41}
39 42
@@ -163,10 +166,71 @@ impl Into<BlockerError> for RustBlockerError {
163 } 166 }
164} 167}
165 168
169fn filter_format_from_string(filter_format: &str) -> PyResult<FilterFormat> {
170 match filter_format {
171 "standard" => Ok(FilterFormat::Standard),
172 "hosts" => Ok(FilterFormat::Hosts),
173 _ => Err(PyErr::new::<PyValueError, _>("Invalid format value")),
174 }
175}
176
177/// Manages a set of rules to be added to an Engine.
178///
179/// To be able to efficiently handle special options like $badfilter, and to
180/// allow optimizations, all rules must be available when the Engine is first
181/// created. FilterSet allows assembling a compound list from multiple
182/// different sources before compiling the rules into an Engine.
183#[pyclass]
184#[text_signature = "($self, debug)"]
185#[derive(Clone)]
186pub struct FilterSet {
187 filter_set: RustFilterSet,
188}
189
190#[pymethods]
191impl FilterSet {
192 /// Creates a new `FilterSet`. The `debug` argument specifies whether or
193 /// not to save information about the original raw filter rules alongside
194 /// the more compact internal representation. If enabled, this information
195 /// will be passed to the corresponding Engine.
196 #[new]
197 #[args(debug = false)]
198 pub fn new(debug: bool) -> Self {
199 Self {
200 filter_set: RustFilterSet::new(debug),
201 }
202 }
203
204 /// Adds the contents of an entire filter list to this FilterSet. Filters
205 /// that cannot be parsed successfully are ignored.
206 ///
207 /// The format is a string containing either "standard" (ABP/uBO-style)
208 /// or "hosts".
209 #[text_signature = "($self, filter_list, format)"]
210 #[args(filter_list, format = "\"standard\"")]
211 pub fn add_filter_list(&mut self, filter_list: &str, format: &str) -> PyResult<()> {
212 let filter_format = filter_format_from_string(format)?;
213 self.filter_set.add_filter_list(filter_list, filter_format);
214 Ok(())
215 }
216
217 /// Adds a collection of filter rules to this FilterSet. Filters that
218 /// cannot be parsed successfully are ignored.
219 ///
220 /// The format is a string containing either "standard" (ABP/uBO-style)
221 /// or "hosts".
222 #[text_signature = "($self, filters, format)"]
223 #[args(filters, format = "\"standard\"")]
224 pub fn add_filters(&mut self, filters: Vec<String>, format: &str) -> PyResult<()> {
225 let filter_format = filter_format_from_string(format)?;
226 self.filter_set.add_filters(&filters, filter_format);
227 Ok(())
228 }
229}
166/// Contains cosmetic filter information intended to be injected into a 230/// Contains cosmetic filter information intended to be injected into a
167/// particular hostname. 231/// particular hostname.
168#[pyclass] 232#[pyclass]
169pub struct HostnameSpecificResources { 233pub struct UrlSpecificResources {
170 /// A set of any CSS selector on the page that should be hidden, i.e. 234 /// A set of any CSS selector on the page that should be hidden, i.e.
171 /// styled as `{ display: none !important; }`. 235 /// styled as `{ display: none !important; }`.
172 #[pyo3(get)] 236 #[pyo3(get)]
@@ -187,9 +251,9 @@ pub struct HostnameSpecificResources {
187 pub injected_script: String, 251 pub injected_script: String,
188} 252}
189 253
190impl Into<HostnameSpecificResources> for RustHostnameSpecificResources { 254impl Into<UrlSpecificResources> for RustUrlSpecificResources {
191 fn into(self) -> HostnameSpecificResources { 255 fn into(self) -> UrlSpecificResources {
192 HostnameSpecificResources { 256 UrlSpecificResources {
193 hide_selectors: self.hide_selectors, 257 hide_selectors: self.hide_selectors,
194 style_selectors: self.style_selectors, 258 style_selectors: self.style_selectors,
195 exceptions: self.exceptions, 259 exceptions: self.exceptions,
@@ -199,10 +263,10 @@ impl Into<HostnameSpecificResources> for RustHostnameSpecificResources {
199} 263}
200 264
201#[pyproto] 265#[pyproto]
202impl PyObjectProtocol for HostnameSpecificResources { 266impl PyObjectProtocol for UrlSpecificResources {
203 fn __repr__(&self) -> PyResult<String> { 267 fn __repr__(&self) -> PyResult<String> {
204 Ok(format!( 268 Ok(format!(
205 "HostnameSpecificResources<{} hide selectors, {} style selectors, {} exceptions, injected_javascript={:?}>", 269 "UrlSpecificResources<{} hide selectors, {} style selectors, {} exceptions, injected_javascript={:?}>",
206 self.hide_selectors.len(), 270 self.hide_selectors.len(),
207 self.style_selectors.len(), 271 self.style_selectors.len(),
208 self.exceptions.len(), 272 self.exceptions.len(),
@@ -231,7 +295,7 @@ impl PyObjectProtocol for HostnameSpecificResources {
231/// 295///
232/// [1]: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/ResourceType 296/// [1]: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/ResourceType
233#[pyclass] 297#[pyclass]
234#[text_signature = "($self, network_filters=None, load_network=True, load_cosmetic=False, debug=False)"] 298#[text_signature = "($self, filter_set, optimize)"]
235pub struct Engine { 299pub struct Engine {
236 engine: RustEngine, 300 engine: RustEngine,
237} 301}
@@ -240,21 +304,9 @@ pub struct Engine {
240impl Engine { 304impl Engine {
241 /// Create a new adblocking engine 305 /// Create a new adblocking engine
242 #[new] 306 #[new]
243 #[args(network_filters="None", load_network=true, load_cosmetic=false, debug=false)] 307 #[args(filter_set, optimize = true)]
244 pub fn new( 308 pub fn new(filter_set: FilterSet, optimize: bool) -> Self {
245 network_filters: Option<Vec<String>>, 309 let engine = RustEngine::from_filter_set(filter_set.filter_set, optimize);
246 load_network: bool,
247 load_cosmetic: bool,
248 debug: bool,
249 ) -> Self {
250 let filters = network_filters.unwrap_or(Vec::new());
251 let engine = RustEngine::from_rules_parametrised(
252 &filters,
253 load_network,
254 load_cosmetic,
255 debug,
256 true,
257 );
258 Self { engine } 310 Self { engine }
259 } 311 }
260 312
@@ -404,43 +456,57 @@ impl Engine {
404 self.deserialize(&data) 456 self.deserialize(&data)
405 } 457 }
406 458
407 /// Add the contents of a block list file to the blocking engine.
408 #[text_signature = "($self, filter_list)"]
409 pub fn add_filter_list(&mut self, filter_list: &str) {
410 self.engine.add_filter_list(filter_list);
411 }
412
413 /// Checks if the given filter exists in the blocking engine. 459 /// Checks if the given filter exists in the blocking engine.
414 #[text_signature = "($self, filter)"] 460 #[text_signature = "($self, filter)"]
415 pub fn filter_exists(&self, filter: &str) -> bool { 461 pub fn filter_exists(&self, filter: &str) -> bool {
416 self.engine.filter_exists(filter) 462 self.engine.filter_exists(filter)
417 } 463 }
418 464
419 /// Enable the given tags 465 /// Sets this engine's tags to be _only_ the ones provided in tags.
466 ///
467 /// Tags can be used to cheaply enable or disable network rules with a
468 /// corresponding $tag option.
420 #[text_signature = "($self, tags)"] 469 #[text_signature = "($self, tags)"]
421 pub fn tags_enable(&mut self, tags: Vec<&str>) { 470 pub fn use_tags(&mut self, tags: Vec<&str>) {
422 self.engine.tags_enable(&tags); 471 self.engine.use_tags(&tags);
423 } 472 }
424 473
425 /// Disable the given tags 474 /// Sets this engine's tags to additionally include the ones provided in
475 /// tags.
476 ///
477 /// Tags can be used to cheaply enable or disable network rules with a
478 /// corresponding $tag option.
426 #[text_signature = "($self, tags)"] 479 #[text_signature = "($self, tags)"]
427 pub fn tags_disable(&mut self, tags: Vec<&str>) { 480 pub fn enable_tags(&mut self, tags: Vec<&str>) {
428 self.engine.tags_disable(&tags); 481 self.engine.enable_tags(&tags);
429 } 482 }
430 483
431 /// Check if the given tag exists 484 /// Sets this engine's tags to no longer include the ones provided in
485 /// tags.
486 ///
487 /// Tags can be used to cheaply enable or disable network rules with a
488 /// corresponding $tag option.
489 #[text_signature = "($self, tags)"]
490 pub fn disable_tags(&mut self, tags: Vec<&str>) {
491 self.engine.disable_tags(&tags);
492 }
493
494 /// Checks if a given tag exists in this engine.
495 ///
496 /// Tags can be used to cheaply enable or disable network rules with a
497 /// corresponding $tag option.
432 #[text_signature = "($self, tag)"] 498 #[text_signature = "($self, tag)"]
433 pub fn tag_exists(&self, tag: &str) -> bool { 499 pub fn tag_exists(&self, tag: &str) -> bool {
434 self.engine.tag_exists(tag) 500 self.engine.tag_exists(tag)
435 } 501 }
436 502
437 /// Returns a set of cosmetic filter resources required for a particular 503 /// Returns a set of cosmetic filter resources required for a particular
438 /// hostname. Once this has been called, all CSS ids and classes on a 504 /// url. Once this has been called, all CSS ids and classes on a
439 /// page should be passed to hidden_class_id_selectors to obtain any 505 /// page should be passed to hidden_class_id_selectors to obtain any
440 /// stylesheets consisting of generic rules. 506 /// stylesheets consisting of generic rules.
441 #[text_signature = "($self, hostname)"] 507 #[text_signature = "($self, url)"]
442 pub fn hostname_cosmetic_resources(&self, hostname: &str) -> HostnameSpecificResources { 508 pub fn url_cosmetic_resources(&self, url: &str) -> UrlSpecificResources {
443 self.engine.hostname_cosmetic_resources(hostname).into() 509 self.engine.url_cosmetic_resources(url).into()
444 } 510 }
445 511
446 /// If any of the provided CSS classes or ids could cause a certain generic 512 /// If any of the provided CSS classes or ids could cause a certain generic
@@ -449,7 +515,7 @@ impl Engine {
449 /// referencing those classes or ids, provided that the corresponding rules 515 /// referencing those classes or ids, provided that the corresponding rules
450 /// are not excepted. 516 /// are not excepted.
451 /// 517 ///
452 /// Exceptions should be passed directly from HostnameSpecificResources. 518 /// Exceptions should be passed directly from UrlSpecificResources.
453 #[text_signature = "($self, classes, ids, exceptions)"] 519 #[text_signature = "($self, classes, ids, exceptions)"]
454 pub fn hidden_class_id_selectors( 520 pub fn hidden_class_id_selectors(
455 &self, 521 &self,