| Index: abp/filters/parser.py |
| =================================================================== |
| --- a/abp/filters/parser.py |
| +++ b/abp/filters/parser.py |
| @@ -46,33 +46,36 @@ |
| Exception.__init__(self, '{} in "{}"'.format(error, text)) |
| self.text = text |
| self.error = error |
| # Constants related to filters (see https://adblockplus.org/filters). |
| class SELECTOR_TYPE: # flake8: noqa (this is a namespace of constants). |
| """Selector type constants.""" |
| + |
| URL_PATTERN = 'url-pattern' # Normal URL patterns. |
| URL_REGEXP = 'url-regexp' # Regular expressions for URLs. |
| CSS = 'css' # CSS selectors for hiding filters. |
| XCSS = 'extended-css' # Extended CSS selectors (to emulate CSS4). |
| ABP_SIMPLE = 'abp-simple' # Simplified element hiding syntax. |
| class FILTER_ACTION: # flake8: noqa (this is a namespace of constants). |
| """Filter action constants.""" |
| + |
| BLOCK = 'block' # Block the request. |
| ALLOW = 'allow' # Allow the request (whitelist). |
| HIDE = 'hide' # Hide selected element(s). |
| SHOW = 'show' # Show selected element(s) (whitelist). |
| class FILTER_OPTION: # flake8: noqa (this is a namespace of constants). |
| """Filter option constants.""" |
| + |
| # Resource types. |
| OTHER = 'other' |
| SCRIPT = 'script' |
| IMAGE = 'image' |
| STYLESHEET = 'stylesheet' |
| OBJECT = 'object' |
| SUBDOCUMENT = 'subdocument' |
| DOCUMENT = 'document' |
| @@ -140,17 +143,17 @@ |
| Include = _line_type('Include', 'target', '%include {0.target}%') |
| METADATA_REGEXP = re.compile(r'\s*!\s*(.*?)\s*:\s*(.*)') |
| INCLUDE_REGEXP = re.compile(r'%include\s+(.+)%') |
| HEADER_REGEXP = re.compile(r'\[(Adblock(?:\s*Plus\s*[\d\.]+?)?)\]', flags=re.I) |
| HIDING_FILTER_REGEXP = re.compile(r'^([^/*|@"!]*?)#([@?])?#(.+)$') |
| FILTER_OPTIONS_REGEXP = re.compile( |
| - r'\$(~?[\w-]+(?:=[^,]+)?(?:,~?[\w-]+(?:=[^,]+)?)*)$' |
| + r'\$(~?[\w-]+(?:=[^,]+)?(?:,~?[\w-]+(?:=[^,]+)?)*)$', |
| ) |
| def _parse_instruction(text): |
| match = INCLUDE_REGEXP.match(text) |
| if not match: |
| raise ParseError('Unrecognized instruction', text) |
| return Include(match.group(1)) |
| @@ -192,18 +195,18 @@ |
| selector = selector[2:] |
| if '$' in selector: |
| opt_match = FILTER_OPTIONS_REGEXP.search(selector) |
| if opt_match: |
| selector = selector[:opt_match.start(0)] |
| options = _parse_filter_options(opt_match.group(1)) |
| - if (len(selector) > 1 and |
| - selector.startswith('/') and selector.endswith('/')): |
| + if (len(selector) > 1 |
| + and selector.startswith('/') and selector.endswith('/')): |
| selector = {'type': SELECTOR_TYPE.URL_REGEXP, 'value': selector[1:-1]} |
| else: |
| selector = {'type': SELECTOR_TYPE.URL_PATTERN, 'value': selector} |
| return Filter(text, selector, action, options) |
| def _parse_hiding_filter(text, domain, type_flag, selector_value): |
| @@ -273,19 +276,19 @@ |
| Parsed line (see `_line_type`). |
| Raises |
| ------ |
| ParseError |
| ParseError: If the line can't be parsed. |
| """ |
| - POSITIONS = {'body', 'start', 'metadata'} |
| - if position not in POSITIONS: |
| - raise ValueError('position should be one of {}'.format(POSITIONS)) |
| + positions = {'body', 'start', 'metadata'} |
| + if position not in positions: |
| + raise ValueError('position should be one of {}'.format(positions)) |
| if isinstance(line, type(b'')): |
| line = line.decode('utf-8') |
| stripped = line.strip() |
| if stripped == '': |
| return EmptyLine() |