diff --git a/.eslintrc b/.eslintrc index 5d99470eee..ea7cbfed5e 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,11 +1,14 @@ { - "extends": "xo", + "extends": [ + "xo/browser", + "xo/esnext" + ], "rules": { - "indent": ["error", 4], - "space-before-function-paren": ["error", "never"] - }, - "env": { - "browser": true, - "jquery": true - } + "indent": ["error", 4], + "space-before-function-paren": ["error", "never"] + }, + "env": { + "browser": true, + "jquery": true + } } diff --git a/.github/check_version.py b/.github/check_version.py index 1e23985b7a..1df2484d3f 100644 --- a/.github/check_version.py +++ b/.github/check_version.py @@ -32,13 +32,23 @@ def __init__(self, version_string): version_string = version_string[1:] self.version = tuple(map(int, version_string.split('.'))) - def __cmp__(self, other): - if self.version == other.version: - return 0 - if self.version > other.version: - return 1 - if self.version < other.version: - return -1 + def __eq__(self, other): + return self.version == other.version + + def __ne__(self, other): + return self.version != other.version + + def __lt__(self, other): + return self.version < other.version + + def __le__(self, other): + return self.version <= other.version + + def __gt__(self, other): + return self.version > other.version + + def __ge__(self, other): + return self.version >= other.version def __str__(self): return str('.'.join(map(str, self.version))) @@ -70,7 +80,7 @@ def search_file_for_version(): if proc > 0: print('Failed to fetch') - proc = subprocess.Popen(['git', 'describe', '--tags', '--abbrev=0', 'master'], stdout=subprocess.PIPE) + proc = subprocess.Popen(['git', 'describe', '--tags', '--abbrev=0', 'master'], stdout=subprocess.PIPE, universal_newlines=True) (output, err) = proc.communicate() latest_tag = output.strip() if err or not latest_tag: diff --git a/.gitignore b/.gitignore index b8255f4e2f..b79c0cd9d3 100644 --- a/.gitignore +++ b/.gitignore @@ -84,4 +84,4 @@ yarn-error.log # Contrib # ###################### -contrib/ +/contrib/ diff --git a/.travis.yml b/.travis.yml index 2ea842f132..ae4729e2e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,8 +12,6 @@ install: false script: false jobs: fast_finish: true - allow_failures: - - python: '3.6' include: # test stage + frontend tests start here - stage: test @@ -70,21 +68,20 @@ jobs: after_failure: - cat ./dredd/data/Logs/application.log # dredd tests (py3.6) start here - # @FIXME: Disabled because they take too long. Enable when Medusa can *actually* start on Python 3. - # - name: 'Dredd tests (py3.6)' - # python: '3.6' - # install: - # - pip install --upgrade pip - # - pip install dredd_hooks - # - pip install 'PyYAML<4' - # - pip install six - # - nvm install v10.7.0 - # - 'curl -o- -L https://yarnpkg.com/install.sh | bash' - # - 'export PATH="$HOME/.yarn/bin:$PATH" && yarn install --ignore-scripts' - # script: - # - yarn test-api - # after_failure: - # - cat ./dredd/data/Logs/application.log + - name: 'Dredd tests (py3.6)' + python: '3.6' + install: + - pip install --upgrade pip + - pip install dredd_hooks + - pip install 'PyYAML<4' + - pip install six + - nvm install v10.7.0 + - 'curl -o- -L https://yarnpkg.com/install.sh | bash' + - 'export PATH="$HOME/.yarn/bin:$PATH" && yarn install --ignore-scripts' + script: + - yarn test-api + after_failure: + - cat ./dredd/data/Logs/application.log notifications: slack: secure: >- diff --git a/CHANGELOG.md b/CHANGELOG.md index d9e35897c4..563d01a4f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +## 0.3.0 (2019-03-13) + +#### New Features +- Added support for Python 3 (>= 3.5.0) ([#4982](https://github.com/pymedusa/Medusa/pull/4982)) +- Added feature to search episodes early or late compared to their scheduled airdate ([#5874](https://github.com/pymedusa/Medusa/pull/5874)) +- Added per show required/preferred words exclude option ([#4982](https://github.com/pymedusa/Medusa/pull/6033)) + +#### Improvements +- Vueified the partial mako template showheader.mako into show-header.vue ([#6189](https://github.com/pymedusa/Medusa/pull/6189)) + +#### Fixes +- Fixed saving newznab provider API key ([#5918](https://github.com/pymedusa/Medusa/pull/5918)) +- Fixed permanent Docker update message ([#6018](https://github.com/pymedusa/Medusa/pull/6018)) + +----- + ## 0.2.14 (2018-12-19) #### New Features @@ -17,7 +33,7 @@ - Fixed mis-mapped proper search interval config option of 24 hours, added 30 minutes ([#5896](https://github.com/pymedusa/Medusa/pull/5896)) - Fixed config - search settings, test nzb client connectivity ([#5897](https://github.com/pymedusa/Medusa/pull/5897)) - Fixed adding an episode to the my anidb list on post processing when enabled ([#5897](https://github.com/pymedusa/Medusa/pull/5897)) -- Fixed creating banner and fanart from metadata. Any metadata images in the shows folder other then the poster, will now also become visible in medusa ([#5808](https://github.com/pymedusa/Medusa/pull/5808)) +- Fixed creating banner and fanart from metadata. Any metadata images in the shows folder other then the poster, will now also become visible in Medusa ([#5808](https://github.com/pymedusa/Medusa/pull/5808)) ----- @@ -32,6 +48,7 @@ - Fixed adding anime release group when adding show ([#5749](https://github.com/pymedusa/Medusa/pull/5749)) - Fixed Pushover debug log causing BraceException ([#5759](https://github.com/pymedusa/Medusa/pull/5759)) - Fixed torrent method Downloadstation not selected after restart ([#5761](https://github.com/pymedusa/Medusa/pull/5761)) +- Fixed changing show location, should now also utilise the option 'CREATE_MISSING_SHOW_DIRS' ([#5795](https://github.com/pymedusa/Medusa/pull/5795)) ----- diff --git a/Dockerfile b/Dockerfile index cf1680dcbf..de85921a80 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM lsiobase/alpine.python:3.8 +FROM lsiobase/alpine.python:3.9 MAINTAINER a10kiloham # set version label diff --git a/dredd/api-description.yml b/dredd/api-description.yml index e411a939e0..6d48df42cd 100644 --- a/dredd/api-description.yml +++ b/dredd/api-description.yml @@ -36,7 +36,6 @@ paths: required: true description: Only id (with indexer information) should be specified schema: - $ref: '#/definitions/Series' example: id: tvdb: 301824 @@ -451,7 +450,6 @@ paths: in: body required: true schema: - $ref: '#/definitions/Operation' example: type: ARCHIVE_EPISODES responses: @@ -558,12 +556,14 @@ paths: 200: description: The alias information schema: {} + x-disabled: true x-request: path-params: id: "${stash['alias-id']}" 400: $ref: '#/responses/error' description: Invalid field + x-disabled: true x-request: path-params: id: "${stash['alias-id']}" @@ -586,6 +586,7 @@ paths: description: The alias information schema: $ref: '#/definitions/Alias' + x-disabled: true x-request: path-params: id: "${stash['alias-id']}" @@ -738,7 +739,6 @@ paths: in: body required: true schema: - $ref: '#/definitions/Operation' example: type: REFRESH responses: @@ -941,6 +941,9 @@ definitions: type: string description: "Air time" example: "Thursday 8:00 PM" + airsFormatValid: + type: boolean + description: "Tests the airs format" language: type: string description: Language code @@ -948,11 +951,40 @@ definitions: showType: type: string enum: [series, anime, sports] - akas: + imdbInfo: type: object - description: Also known as - additionalProperties: - type: string + description: "Object with additional show information retrieved from imdb" + properties: + akas: + type: string + certificates: + type: string + countries: + type: string + countryCodes: + type: string + genres: + type: string + imdbId: + type: string + imdbInfoId: + type: integer + indexer: + type: integer + indexerId: + type: integer + lastUpdate: + type: integer + plot: + type: string + rating: + type: string + runtimes: + type: integer + title: + type: string + votes: + type: integer year: type: object properties: @@ -1028,6 +1060,9 @@ definitions: type: string description: Series home folder example: "/library/My Series" + locationValid: + type: boolean + description: Result of a stat on the configured location qualities: type: object description: Qualities settings @@ -1091,6 +1126,15 @@ definitions: description: Required release words items: type: string + requiredWordsExclude: + type: boolean + description: Exclude required words from global required words list + ignoredWordsExclude: + type: boolean + description: Exclude ignored words from global ignored words list + airdateOffset: + type: integer + description: Amount of hours we want to start searching early (-1) or late (1) for new episodes seasons: type: array description: Episodes grouped by season. Available in detailed view. @@ -1105,6 +1149,20 @@ definitions: minimum: 0 maximum: 10000 description: Total number of episodes. Available in detailed view + size: + type: integer + description: Show size on disk calculated from the shows configured location + showQueueStatus: + type: array + description: Array of objects with information on the different queues used for operations on a show. + items: + type: object + xemNumbering: + type: array + description: Array of objects with xem indexer to scene mappings + items: + type: object + example: '"xemNumbering": [{"source": {"season": 6, "episode": 34}, "destination": {"season": 2, "episode": 16}}' Episode: type: object properties: @@ -2122,7 +2180,6 @@ definitions: x-nullable: true type: type: string - enum: [null, local] x-nullable: true example: series: tvdb301824 diff --git a/dredd/dredd_hook.py b/dredd/dredd_hook.py index 06e0eeb459..811a1a99ee 100644 --- a/dredd/dredd_hook.py +++ b/dredd/dredd_hook.py @@ -1,19 +1,23 @@ #!/usr/bin/env python # coding=utf-8 """Dredd hook.""" -from __future__ import absolute_import -from __future__ import print_function from __future__ import unicode_literals import io import json +import os +import sys + +sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), '../ext'))) +if sys.version_info[0] == 2: + sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), '../ext2'))) + from collections import Mapping +from configparser import ConfigParser import dredd_hooks as hooks -import six from six import string_types -from six.moves.configparser import RawConfigParser from six.moves.urllib.parse import parse_qs, urlencode, urlparse import yaml @@ -163,13 +167,13 @@ def start(): os.makedirs(data_dir) os.chdir(data_dir) - config = RawConfigParser() + config = ConfigParser() config.read('config.ini') config.add_section('General') config.set('General', 'web_username', stash['web-username']) config.set('General', 'web_password', stash['web-password']) config.set('General', 'api_key', stash['api-key']) - with io.open('config.ini', 'w' if six.PY3 else 'wb') as configfile: + with io.open('config.ini', 'w', encoding='utf-8') as configfile: config.write(configfile) sys.path.insert(1, app_dir) diff --git a/ext/adba/__init__.py b/ext/adba/__init__.py index 1276600696..771639dd9e 100644 --- a/ext/adba/__init__.py +++ b/ext/adba/__init__.py @@ -18,13 +18,12 @@ import logging import logging.handlers import os +import sys import threading - +from configparser import ConfigParser from datetime import timedelta -from time import time, sleep -import sys +from time import sleep, time -from configparser import ConfigParser from six.moves.queue import Queue from .aniDBlink import AniDBLink @@ -154,7 +153,7 @@ def callback_wrapper(resp): if callback: callback(resp) - logger.debug("handling(" + str(self.counter) + "-" + str(self.link.delay) + ") command " + str(command.command)) + logger.debug("handling({counter}-{delay}) command {command}".format(counter=self.counter, delay=self.link.delay, command=command.command)) # make live request command.authorize(self.mode, self.link.new_tag(), self.link.session, callback_wrapper) @@ -177,10 +176,10 @@ def callback_wrapper(resp): def authed(self, reAuthenticate=False): self.lock.acquire() - authed = (self.link.session is not None) + authed = (self.link.session not in (None, '')) if not authed and (reAuthenticate or self.keepAlive): self._reAuthenticate() - authed = (self.link.session is not None) + authed = (self.link.session not in (None, '')) self.lock.release() return authed @@ -256,6 +255,8 @@ def auth(self, username, password, nat=None, mtu=None, callback=None): if timeelapsed < timeoutduration: # we are logged in and within timeout so set up session key and assume valid self.link.session = config.get('DEFAULT', 'sessionkey') + if not self.link.session: + needauth = True else: needauth = True else: @@ -268,16 +269,16 @@ def auth(self, username, password, nat=None, mtu=None, callback=None): logger.debug('No valid session, so authenticating') try: self.handle(AuthCommand(username, password, 3, self.clientname, self.clientver, nat, 1, 'utf8', mtu), callback) - except Exception as e: - logger.debug('Auth command with exception %s', e) + except Exception as error: + logger.debug('Auth command with exception %r', error) # we force a config file with logged out to ensure a known state if an exception occurs, forcing us to log in again - config['DEFAULT'] = {'loggedin': 'yes', 'sessionkey': self.link.session, 'exception': str(e), + config['DEFAULT'] = {'loggedin': 'yes', 'sessionkey': str(self.link.session or ''), 'exception': str(error), 'lastcommandtime': repr(time())} with open(self.SessionFile, 'w') as configfile: config.write(configfile) - return e + return error logger.debug('Successfully authenticated and recording session details') - config['DEFAULT'] = {'loggedin': 'yes', 'sessionkey': self.link.session, 'lastcommandtime': repr(time())} + config['DEFAULT'] = {'loggedin': 'yes', 'sessionkey': str(self.link.session or ''), 'lastcommandtime': repr(time())} with open(self.SessionFile, 'w') as configfile: config.write(configfile) return diff --git a/ext/adba/aniDBAbstracter.py b/ext/adba/aniDBAbstracter.py index 252c65cee8..93851fc406 100644 --- a/ext/adba/aniDBAbstracter.py +++ b/ext/adba/aniDBAbstracter.py @@ -166,7 +166,7 @@ def get_groups(self): self.rawData = self.aniDB.groupstatus(aid=self.aid) self.release_groups = [] for line in self.rawData.datalines: - self.release_groups.append({"name": line["name"].decode("utf-8"), + self.release_groups.append({"name": line["name"], "rating": line["rating"], "range": line["episode_range"] }) diff --git a/ext/adba/aniDBfileInfo.py b/ext/adba/aniDBfileInfo.py index c44c916046..1a31275fac 100644 --- a/ext/adba/aniDBfileInfo.py +++ b/ext/adba/aniDBfileInfo.py @@ -19,8 +19,8 @@ import hashlib import logging -import pickle import os +import pickle import requests import sys import time @@ -132,8 +132,7 @@ def read_xml_into_etree(filePath): if not get_anime_titles_xml(filePath): return - f = open(filePath, "r") - xml_a_setree = etree.ElementTree(file=f) + xml_a_setree = etree.ElementTree().parse(filePath) return xml_a_setree diff --git a/ext/adba/aniDBlink.py b/ext/adba/aniDBlink.py index 8bf2d208cb..ff6d2c0535 100644 --- a/ext/adba/aniDBlink.py +++ b/ext/adba/aniDBlink.py @@ -124,16 +124,16 @@ def run(self): cmd = self._cmd_dequeue(resp) resp = resp.resolve(cmd) resp.parse() - if resp.rescode in (b'200', b'201'): - self.session = resp.attrs[b'sesskey'] - if resp.rescode in (b'209',): + if resp.rescode in ('200', '201'): + self.session = resp.attrs['sesskey'] + if resp.rescode in ('209',): logger.error("sorry encryption is not supported") raise AniDBError() # self.crypt=aes(md5(resp.req.apipassword+resp.attrs['salt']).digest()) - if resp.rescode in (b'203', b'403', b'500', b'501', b'503', b'506'): + if resp.rescode in ('203', '403', '500', '501', '503', '506'): self.session = None self.crypt = None - if resp.rescode in (b'504', b'555'): + if resp.rescode in ('504', '555'): self.banned = True logger.critical(("AniDB API informs that user or client is banned:", resp.resstr)) resp.handle() @@ -213,20 +213,20 @@ def _send(self, command): command.started = time() data = command.raw_data() - self.sock.sendto(bytes(data, b"ASCII"), self.target) - if command.command == b'AUTH': + self.sock.sendto(bytes(data, "ASCII"), self.target) + if command.command == 'AUTH': logger.debug("NetIO > sensitive data is not logged!") def new_tag(self): if not len(self.tags): - maxtag = b"T000" + maxtag = "T000" else: maxtag = max(self.tags) - newtag = b"T%03d" % (int(maxtag[1:]) + 1) + newtag = "T%03d" % (int(maxtag[1:]) + 1) return newtag def request(self, command): - if not (self.session and command.session) and command.command not in (b'AUTH', b'PING', b'ENCRYPT'): + if not (self.session and command.session) and command.command not in ('AUTH', 'PING', 'ENCRYPT'): raise AniDBMustAuthError("You must be authed to execute commands besides AUTH and PING") command.started = time() self._cmd_queue(command) diff --git a/ext/adba/aniDBresponses.py b/ext/adba/aniDBresponses.py index 5b3e6d99ce..45e07fc129 100644 --- a/ext/adba/aniDBresponses.py +++ b/ext/adba/aniDBresponses.py @@ -30,6 +30,8 @@ def __init__(self, data): @staticmethod def parse(data): + data = data.decode('utf-8') + resline = data.split('\n', 1)[0] lines = data.split('\n')[1:-1] diff --git a/ext/certifi/__init__.py b/ext/certifi/__init__.py index 50f2e1301f..632db8e132 100644 --- a/ext/certifi/__init__.py +++ b/ext/certifi/__init__.py @@ -1,3 +1,3 @@ -from .core import where, old_where +from .core import where -__version__ = "2018.10.15" +__version__ = "2019.03.09" diff --git a/ext/certifi/cacert.pem b/ext/certifi/cacert.pem index e75d85b38a..84636dde7d 100644 --- a/ext/certifi/cacert.pem +++ b/ext/certifi/cacert.pem @@ -4268,3 +4268,391 @@ rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV 57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 -----END CERTIFICATE----- + +# Issuer: CN=GTS Root R1 O=Google Trust Services LLC +# Subject: CN=GTS Root R1 O=Google Trust Services LLC +# Label: "GTS Root R1" +# Serial: 146587175971765017618439757810265552097 +# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85 +# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8 +# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX +mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 +zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P +fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc +vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 +Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp +zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO +Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW +k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ +DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF +lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW +Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 +d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z +XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR +gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 +d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv +J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg +DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM ++SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy +F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 +SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws +E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R2 O=Google Trust Services LLC +# Subject: CN=GTS Root R2 O=Google Trust Services LLC +# Label: "GTS Root R2" +# Serial: 146587176055767053814479386953112547951 +# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b +# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d +# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv +CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg +GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu +XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd +re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu +PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 +mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K +8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj +x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR +nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 +kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok +twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp +8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT +vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT +z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA +pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb +pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB +R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R +RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk +0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC +5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF +izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn +yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R3 O=Google Trust Services LLC +# Subject: CN=GTS Root R3 O=Google Trust Services LLC +# Label: "GTS Root R3" +# Serial: 146587176140553309517047991083707763997 +# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25 +# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5 +# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5 +-----BEGIN CERTIFICATE----- +MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A +DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk +fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA +njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R4 O=Google Trust Services LLC +# Subject: CN=GTS Root R4 O=Google Trust Services LLC +# Label: "GTS Root R4" +# Serial: 146587176229350439916519468929765261721 +# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26 +# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb +# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd +-----BEGIN CERTIFICATE----- +MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l +xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 +CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx +sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Global G2 Root O=UniTrust +# Subject: CN=UCA Global G2 Root O=UniTrust +# Label: "UCA Global G2 Root" +# Serial: 124779693093741543919145257850076631279 +# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 +# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a +# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Extended Validation Root O=UniTrust +# Subject: CN=UCA Extended Validation Root O=UniTrust +# Label: "UCA Extended Validation Root" +# Serial: 106100277556486529736699587978573607008 +# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 +# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a +# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- + +# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Label: "Certigna Root CA" +# Serial: 269714418870597844693661054334862075617 +# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 +# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 +# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign Root CA - G1" +# Serial: 235931866688319308814040 +# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac +# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c +# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign ECC Root CA - G3" +# Serial: 287880440101571086945156 +# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40 +# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1 +# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Label: "emSign Root CA - C1" +# Serial: 825510296613316004955058 +# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68 +# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01 +# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Label: "emSign ECC Root CA - C3" +# Serial: 582948710642506000014504 +# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5 +# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66 +# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3 +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Label: "Hongkong Post Root CA 3" +# Serial: 46170865288971385588281144162979347873371282084 +# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 +# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 +# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 +-----BEGIN CERTIFICATE----- +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 +mpv0 +-----END CERTIFICATE----- diff --git a/ext/certifi/core.py b/ext/certifi/core.py index eab9d1d178..7271acf40e 100644 --- a/ext/certifi/core.py +++ b/ext/certifi/core.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # -*- coding: utf-8 -*- """ @@ -8,30 +7,9 @@ This module returns the installation location of cacert.pem. """ import os -import warnings - - -class DeprecatedBundleWarning(DeprecationWarning): - """ - The weak security bundle is being deprecated. Please bother your service - provider to get them to stop using cross-signed roots. - """ def where(): f = os.path.dirname(__file__) return os.path.join(f, 'cacert.pem') - - -def old_where(): - warnings.warn( - "The weak security bundle has been removed. certifi.old_where() is now an alias " - "of certifi.where(). Please update your code to use certifi.where() instead. " - "certifi.old_where() will be removed in 2018.", - DeprecatedBundleWarning - ) - return where() - -if __name__ == '__main__': - print(where()) diff --git a/ext/configparser.pth b/ext/configparser.pth deleted file mode 100644 index 781f5d2a63..0000000000 --- a/ext/configparser.pth +++ /dev/null @@ -1 +0,0 @@ -import sys, types, os;has_mfs = sys.version_info > (3, 5);p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('backports',));importlib = has_mfs and __import__('importlib.util');has_mfs and __import__('importlib.machinery');m = has_mfs and sys.modules.setdefault('backports', importlib.util.module_from_spec(importlib.machinery.PathFinder.find_spec('backports', [os.path.dirname(p)])));m = m or sys.modules.setdefault('backports', types.ModuleType('backports'));mp = (m or []) and m.__dict__.setdefault('__path__',[]);(p not in mp) and mp.append(p) diff --git a/ext/dateutil/_version.py b/ext/dateutil/_version.py index d3ce85616b..670d7ab7de 100644 --- a/ext/dateutil/_version.py +++ b/ext/dateutil/_version.py @@ -1,4 +1,4 @@ # coding: utf-8 # file generated by setuptools_scm # don't change, don't track in version control -version = '2.7.5' +version = '2.8.0' diff --git a/ext/dateutil/parser/_parser.py b/ext/dateutil/parser/_parser.py index 9d2bb795cf..0da0f3e6b9 100644 --- a/ext/dateutil/parser/_parser.py +++ b/ext/dateutil/parser/_parser.py @@ -40,7 +40,7 @@ from io import StringIO import six -from six import binary_type, integer_types, text_type +from six import integer_types, text_type from decimal import Decimal @@ -63,7 +63,7 @@ def __init__(self, instream): if six.PY2: # In Python 2, we can't duck type properly because unicode has # a 'decode' function, and we'd be double-decoding - if isinstance(instream, (binary_type, bytearray)): + if isinstance(instream, (bytes, bytearray)): instream = instream.decode() else: if getattr(instream, 'decode', None) is not None: @@ -291,7 +291,7 @@ class parserinfo(object): ("s", "second", "seconds")] AMPM = [("am", "a"), ("pm", "p")] - UTCZONE = ["UTC", "GMT", "Z"] + UTCZONE = ["UTC", "GMT", "Z", "z"] PERTAIN = ["of"] TZOFFSET = {} # TODO: ERA = ["AD", "BC", "CE", "BCE", "Stardate", @@ -388,7 +388,8 @@ def validate(self, res): if res.year is not None: res.year = self.convertyear(res.year, res.century_specified) - if res.tzoffset == 0 and not res.tzname or res.tzname == 'Z': + if ((res.tzoffset == 0 and not res.tzname) or + (res.tzname == 'Z' or res.tzname == 'z')): res.tzname = "UTC" res.tzoffset = 0 elif res.tzoffset != 0 and res.tzname and self.utczone(res.tzname): @@ -1060,7 +1061,8 @@ def _could_be_tzname(self, hour, tzname, tzoffset, token): tzname is None and tzoffset is None and len(token) <= 5 and - all(x in string.ascii_uppercase for x in token)) + (all(x in string.ascii_uppercase for x in token) + or token in self.info.UTCZONE)) def _ampm_valid(self, hour, ampm, fuzzy): """ diff --git a/ext/dateutil/parser/isoparser.py b/ext/dateutil/parser/isoparser.py index cd27f93d96..e3cf6d8c55 100644 --- a/ext/dateutil/parser/isoparser.py +++ b/ext/dateutil/parser/isoparser.py @@ -88,10 +88,12 @@ def isoparse(self, dt_str): - ``hh`` - ``hh:mm`` or ``hhmm`` - ``hh:mm:ss`` or ``hhmmss`` - - ``hh:mm:ss.sss`` or ``hh:mm:ss.ssssss`` (3-6 sub-second digits) + - ``hh:mm:ss.ssssss`` (Up to 6 sub-second digits) Midnight is a special case for `hh`, as the standard supports both - 00:00 and 24:00 as a representation. + 00:00 and 24:00 as a representation. The decimal separator can be + either a dot or a comma. + .. caution:: @@ -137,6 +139,10 @@ def isoparse(self, dt_str): else: raise ValueError('String contains unknown ISO components') + if len(components) > 3 and components[3] == 24: + components[3] = 0 + return datetime(*components) + timedelta(days=1) + return datetime(*components) @_takes_ascii @@ -167,7 +173,10 @@ def parse_isotime(self, timestr): :return: Returns a :class:`datetime.time` object """ - return time(*self._parse_isotime(timestr)) + components = self._parse_isotime(timestr) + if components[0] == 24: + components[0] = 0 + return time(*components) @_takes_ascii def parse_tzstr(self, tzstr, zero_as_utc=True): @@ -190,10 +199,9 @@ def parse_tzstr(self, tzstr, zero_as_utc=True): return self._parse_tzstr(tzstr, zero_as_utc=zero_as_utc) # Constants - _MICROSECOND_END_REGEX = re.compile(b'[-+Z]+') _DATE_SEP = b'-' _TIME_SEP = b':' - _MICRO_SEP = b'.' + _FRACTION_REGEX = re.compile(b'[\\.,]([0-9]+)') def _parse_isodate(self, dt_str): try: @@ -333,7 +341,7 @@ def _parse_isotime(self, timestr): while pos < len_str and comp < 5: comp += 1 - if timestr[pos:pos + 1] in b'-+Z': + if timestr[pos:pos + 1] in b'-+Zz': # Detect time zone boundary components[-1] = self._parse_tzstr(timestr[pos:]) pos = len_str @@ -348,16 +356,14 @@ def _parse_isotime(self, timestr): pos += 1 if comp == 3: - # Microsecond - if timestr[pos:pos + 1] != self._MICRO_SEP: + # Fraction of a second + frac = self._FRACTION_REGEX.match(timestr[pos:]) + if not frac: continue - pos += 1 - us_str = self._MICROSECOND_END_REGEX.split(timestr[pos:pos + 6], - 1)[0] - + us_str = frac.group(1)[:6] # Truncate to microseconds components[comp] = int(us_str) * 10**(6 - len(us_str)) - pos += len(us_str) + pos += len(frac.group()) if pos < len_str: raise ValueError('Unused components in ISO string') @@ -366,12 +372,11 @@ def _parse_isotime(self, timestr): # Standard supports 00:00 and 24:00 as representations of midnight if any(component != 0 for component in components[1:4]): raise ValueError('Hour may only be 24 at 24:00:00.000') - components[0] = 0 return components def _parse_tzstr(self, tzstr, zero_as_utc=True): - if tzstr == b'Z': + if tzstr == b'Z' or tzstr == b'z': return tz.tzutc() if len(tzstr) not in {3, 5, 6}: diff --git a/ext/dateutil/relativedelta.py b/ext/dateutil/relativedelta.py index 1e0d616532..c65c66e66e 100644 --- a/ext/dateutil/relativedelta.py +++ b/ext/dateutil/relativedelta.py @@ -17,8 +17,12 @@ class relativedelta(object): """ - The relativedelta type is based on the specification of the excellent - work done by M.-A. Lemburg in his + The relativedelta type is designed to be applied to an existing datetime and + can replace specific components of that datetime, or represents an interval + of time. + + It is based on the specification of the excellent work done by M.-A. Lemburg + in his `mx.DateTime `_ extension. However, notice that this type does *NOT* implement the same algorithm as his work. Do *NOT* expect it to behave like mx.DateTime's counterpart. @@ -45,13 +49,15 @@ class relativedelta(object): with the information in the relativedelta. weekday: - One of the weekday instances (MO, TU, etc). These - instances may receive a parameter N, specifying the Nth - weekday, which could be positive or negative (like MO(+1) - or MO(-2). Not specifying it is the same as specifying - +1. You can also use an integer, where 0=MO. Notice that - if the calculated date is already Monday, for example, - using MO(1) or MO(-1) won't change the day. + One of the weekday instances (MO, TU, etc) available in the + relativedelta module. These instances may receive a parameter N, + specifying the Nth weekday, which could be positive or negative + (like MO(+1) or MO(-2)). Not specifying it is the same as specifying + +1. You can also use an integer, where 0=MO. This argument is always + relative e.g. if the calculated date is already Monday, using MO(1) + or MO(-1) won't change the day. To effectively make it absolute, use + it in combination with the day argument (e.g. day=1, MO(1) for first + Monday of the month). leapdays: Will add given days to the date found, if year is a leap @@ -82,9 +88,12 @@ class relativedelta(object): For example + >>> from datetime import datetime + >>> from dateutil.relativedelta import relativedelta, MO >>> dt = datetime(2018, 4, 9, 13, 37, 0) >>> delta = relativedelta(hours=25, day=1, weekday=MO(1)) - datetime(2018, 4, 2, 14, 37, 0) + >>> dt + delta + datetime.datetime(2018, 4, 2, 14, 37) First, the day is set to 1 (the first of the month), then 25 hours are added, to get to the 2nd day and 14th hour, finally the @@ -276,7 +285,7 @@ def normalized(self): values for the relative attributes. >>> relativedelta(days=1.5, hours=2).normalized() - relativedelta(days=1, hours=14) + relativedelta(days=+1, hours=+14) :return: Returns a :class:`dateutil.relativedelta.relativedelta` object. diff --git a/ext/dateutil/rrule.py b/ext/dateutil/rrule.py index 8e9c2af184..20a0c4ac3e 100644 --- a/ext/dateutil/rrule.py +++ b/ext/dateutil/rrule.py @@ -353,20 +353,26 @@ class rrule(rrulebase): from calendar.firstweekday(), and may be modified by calendar.setfirstweekday(). :param count: - How many occurrences will be generated. + If given, this determines how many occurrences will be generated. .. note:: - As of version 2.5.0, the use of the ``until`` keyword together - with the ``count`` keyword is deprecated per RFC-5545 Sec. 3.3.10. + As of version 2.5.0, the use of the keyword ``until`` in conjunction + with ``count`` is deprecated, to make sure ``dateutil`` is fully + compliant with `RFC-5545 Sec. 3.3.10 `_. Therefore, ``until`` and ``count`` + **must not** occur in the same call to ``rrule``. :param until: - If given, this must be a datetime instance, that will specify the + If given, this must be a datetime instance specifying the upper-bound limit of the recurrence. The last recurrence in the rule is the greatest datetime that is less than or equal to the value specified in the ``until`` parameter. .. note:: - As of version 2.5.0, the use of the ``until`` keyword together - with the ``count`` keyword is deprecated per RFC-5545 Sec. 3.3.10. + As of version 2.5.0, the use of the keyword ``until`` in conjunction + with ``count`` is deprecated, to make sure ``dateutil`` is fully + compliant with `RFC-5545 Sec. 3.3.10 `_. Therefore, ``until`` and ``count`` + **must not** occur in the same call to ``rrule``. :param bysetpos: If given, it must be either an integer, or a sequence of integers, positive or negative. Each given integer will specify an occurrence @@ -429,7 +435,7 @@ def __init__(self, freq, dtstart=None, if not dtstart: if until and until.tzinfo: dtstart = datetime.datetime.now(tz=until.tzinfo).replace(microsecond=0) - else: + else: dtstart = datetime.datetime.now().replace(microsecond=0) elif not isinstance(dtstart, datetime.datetime): dtstart = datetime.datetime.fromordinal(dtstart.toordinal()) @@ -1406,7 +1412,52 @@ def _iter(self): self._len = total + + class _rrulestr(object): + """ Parses a string representation of a recurrence rule or set of + recurrence rules. + + :param s: + Required, a string defining one or more recurrence rules. + + :param dtstart: + If given, used as the default recurrence start if not specified in the + rule string. + + :param cache: + If set ``True`` caching of results will be enabled, improving + performance of multiple queries considerably. + + :param unfold: + If set ``True`` indicates that a rule string is split over more + than one line and should be joined before processing. + + :param forceset: + If set ``True`` forces a :class:`dateutil.rrule.rruleset` to + be returned. + + :param compatible: + If set ``True`` forces ``unfold`` and ``forceset`` to be ``True``. + + :param ignoretz: + If set ``True``, time zones in parsed strings are ignored and a naive + :class:`datetime.datetime` object is returned. + + :param tzids: + If given, a callable or mapping used to retrieve a + :class:`datetime.tzinfo` from a string representation. + Defaults to :func:`dateutil.tz.gettz`. + + :param tzinfos: + Additional time zone names / aliases which may be present in a string + representation. See :func:`dateutil.parser.parse` for more + information. + + :return: + Returns a :class:`dateutil.rrule.rruleset` or + :class:`dateutil.rrule.rrule` + """ _freq_map = {"YEARLY": YEARLY, "MONTHLY": MONTHLY, @@ -1508,6 +1559,58 @@ def _parse_rfc_rrule(self, line, raise ValueError("invalid '%s': %s" % (name, value)) return rrule(dtstart=dtstart, cache=cache, **rrkwargs) + def _parse_date_value(self, date_value, parms, rule_tzids, + ignoretz, tzids, tzinfos): + global parser + if not parser: + from dateutil import parser + + datevals = [] + value_found = False + TZID = None + + for parm in parms: + if parm.startswith("TZID="): + try: + tzkey = rule_tzids[parm.split('TZID=')[-1]] + except KeyError: + continue + if tzids is None: + from . import tz + tzlookup = tz.gettz + elif callable(tzids): + tzlookup = tzids + else: + tzlookup = getattr(tzids, 'get', None) + if tzlookup is None: + msg = ('tzids must be a callable, mapping, or None, ' + 'not %s' % tzids) + raise ValueError(msg) + + TZID = tzlookup(tzkey) + continue + + # RFC 5445 3.8.2.4: The VALUE parameter is optional, but may be found + # only once. + if parm not in {"VALUE=DATE-TIME", "VALUE=DATE"}: + raise ValueError("unsupported parm: " + parm) + else: + if value_found: + msg = ("Duplicate value parameter found in: " + parm) + raise ValueError(msg) + value_found = True + + for datestr in date_value.split(','): + date = parser.parse(datestr, ignoretz=ignoretz, tzinfos=tzinfos) + if TZID is not None: + if date.tzinfo is None: + date = date.replace(tzinfo=TZID) + else: + raise ValueError('DTSTART/EXDATE specifies multiple timezone') + datevals.append(date) + + return datevals + def _parse_rfc(self, s, dtstart=None, cache=False, @@ -1580,54 +1683,18 @@ def _parse_rfc(self, s, raise ValueError("unsupported EXRULE parm: "+parm) exrulevals.append(value) elif name == "EXDATE": - for parm in parms: - if parm != "VALUE=DATE-TIME": - raise ValueError("unsupported EXDATE parm: "+parm) - exdatevals.append(value) + exdatevals.extend( + self._parse_date_value(value, parms, + TZID_NAMES, ignoretz, + tzids, tzinfos) + ) elif name == "DTSTART": - # RFC 5445 3.8.2.4: The VALUE parameter is optional, but - # may be found only once. - value_found = False - TZID = None - valid_values = {"VALUE=DATE-TIME", "VALUE=DATE"} - for parm in parms: - if parm.startswith("TZID="): - try: - tzkey = TZID_NAMES[parm.split('TZID=')[-1]] - except KeyError: - continue - if tzids is None: - from . import tz - tzlookup = tz.gettz - elif callable(tzids): - tzlookup = tzids - else: - tzlookup = getattr(tzids, 'get', None) - if tzlookup is None: - msg = ('tzids must be a callable, ' + - 'mapping, or None, ' + - 'not %s' % tzids) - raise ValueError(msg) - - TZID = tzlookup(tzkey) - continue - if parm not in valid_values: - raise ValueError("unsupported DTSTART parm: "+parm) - else: - if value_found: - msg = ("Duplicate value parameter found in " + - "DTSTART: " + parm) - raise ValueError(msg) - value_found = True - if not parser: - from dateutil import parser - dtstart = parser.parse(value, ignoretz=ignoretz, - tzinfos=tzinfos) - if TZID is not None: - if dtstart.tzinfo is None: - dtstart = dtstart.replace(tzinfo=TZID) - else: - raise ValueError('DTSTART specifies multiple timezones') + dtvals = self._parse_date_value(value, parms, TZID_NAMES, + ignoretz, tzids, tzinfos) + if len(dtvals) != 1: + raise ValueError("Multiple DTSTART values specified:" + + value) + dtstart = dtvals[0] else: raise ValueError("unsupported property: "+name) if (forceset or len(rrulevals) > 1 or rdatevals @@ -1649,10 +1716,7 @@ def _parse_rfc(self, s, ignoretz=ignoretz, tzinfos=tzinfos)) for value in exdatevals: - for datestr in value.split(','): - rset.exdate(parser.parse(datestr, - ignoretz=ignoretz, - tzinfos=tzinfos)) + rset.exdate(value) if compatible and dtstart: rset.rdate(dtstart) return rset diff --git a/ext/dateutil/test/conftest.py b/ext/dateutil/test/conftest.py new file mode 100644 index 0000000000..78ed70acb3 --- /dev/null +++ b/ext/dateutil/test/conftest.py @@ -0,0 +1,41 @@ +import os +import pytest + + +# Configure pytest to ignore xfailing tests +# See: https://stackoverflow.com/a/53198349/467366 +def pytest_collection_modifyitems(items): + for item in items: + marker_getter = getattr(item, 'get_closest_marker', None) + + # Python 3.3 support + if marker_getter is None: + marker_getter = item.get_marker + + marker = marker_getter('xfail') + + # Need to query the args because conditional xfail tests still have + # the xfail mark even if they are not expected to fail + if marker and (not marker.args or marker.args[0]): + item.add_marker(pytest.mark.no_cover) + + +def set_tzpath(): + """ + Sets the TZPATH variable if it's specified in an environment variable. + """ + tzpath = os.environ.get('DATEUTIL_TZPATH', None) + + if tzpath is None: + return + + path_components = tzpath.split(':') + + print("Setting TZPATH to {}".format(path_components)) + + from dateutil import tz + tz.TZPATHS.clear() + tz.TZPATHS.extend(path_components) + + +set_tzpath() diff --git a/ext/dateutil/test/test_easter.py b/ext/dateutil/test/test_easter.py index eeb094ee26..cf2ec7f287 100644 --- a/ext/dateutil/test/test_easter.py +++ b/ext/dateutil/test/test_easter.py @@ -2,7 +2,7 @@ from dateutil.easter import EASTER_WESTERN, EASTER_ORTHODOX, EASTER_JULIAN from datetime import date -import unittest +import pytest # List of easters between 1990 and 2050 western_easter_dates = [ @@ -73,23 +73,21 @@ ] -class EasterTest(unittest.TestCase): - def testEasterWestern(self): - for easter_date in western_easter_dates: - self.assertEqual(easter_date, - easter(easter_date.year, EASTER_WESTERN)) +@pytest.mark.parametrize("easter_date", western_easter_dates) +def test_easter_western(easter_date): + assert easter_date == easter(easter_date.year, EASTER_WESTERN) - def testEasterOrthodox(self): - for easter_date in orthodox_easter_dates: - self.assertEqual(easter_date, - easter(easter_date.year, EASTER_ORTHODOX)) - def testEasterJulian(self): - for easter_date in julian_easter_dates: - self.assertEqual(easter_date, - easter(easter_date.year, EASTER_JULIAN)) +@pytest.mark.parametrize("easter_date", orthodox_easter_dates) +def test_easter_orthodox(easter_date): + assert easter_date == easter(easter_date.year, EASTER_ORTHODOX) - def testEasterBadMethod(self): - # Invalid methods raise ValueError - with self.assertRaises(ValueError): - easter(1975, 4) + +@pytest.mark.parametrize("easter_date", julian_easter_dates) +def test_easter_julian(easter_date): + assert easter_date == easter(easter_date.year, EASTER_JULIAN) + + +def test_easter_bad_method(): + with pytest.raises(ValueError): + easter(1975, 4) diff --git a/ext/dateutil/test/test_import_star.py b/ext/dateutil/test/test_import_star.py index 8e66f38aa3..2fb7098128 100644 --- a/ext/dateutil/test/test_import_star.py +++ b/ext/dateutil/test/test_import_star.py @@ -1,8 +1,8 @@ """Test for the "import *" functionality. -As imort * can be only done at module level, it has been added in a separate file +As import * can be only done at module level, it has been added in a separate file """ -import unittest +import pytest prev_locals = list(locals()) from dateutil import * @@ -10,24 +10,24 @@ if name not in prev_locals} new_locals.pop('prev_locals') -class ImportStarTest(unittest.TestCase): - """ Test that `from dateutil import *` adds the modules in __all__ locally""" - def testImportedModules(self): - import dateutil.easter - import dateutil.parser - import dateutil.relativedelta - import dateutil.rrule - import dateutil.tz - import dateutil.utils - import dateutil.zoneinfo +@pytest.mark.import_star +def test_imported_modules(): + """ Test that `from dateutil import *` adds modules in __all__ locally """ + import dateutil.easter + import dateutil.parser + import dateutil.relativedelta + import dateutil.rrule + import dateutil.tz + import dateutil.utils + import dateutil.zoneinfo - self.assertEquals(dateutil.easter, new_locals.pop("easter")) - self.assertEquals(dateutil.parser, new_locals.pop("parser")) - self.assertEquals(dateutil.relativedelta, new_locals.pop("relativedelta")) - self.assertEquals(dateutil.rrule, new_locals.pop("rrule")) - self.assertEquals(dateutil.tz, new_locals.pop("tz")) - self.assertEquals(dateutil.utils, new_locals.pop("utils")) - self.assertEquals(dateutil.zoneinfo, new_locals.pop("zoneinfo")) + assert dateutil.easter == new_locals.pop("easter") + assert dateutil.parser == new_locals.pop("parser") + assert dateutil.relativedelta == new_locals.pop("relativedelta") + assert dateutil.rrule == new_locals.pop("rrule") + assert dateutil.tz == new_locals.pop("tz") + assert dateutil.utils == new_locals.pop("utils") + assert dateutil.zoneinfo == new_locals.pop("zoneinfo") - self.assertFalse(new_locals) + assert not new_locals diff --git a/ext/dateutil/test/test_isoparser.py b/ext/dateutil/test/test_isoparser.py index 28c1bf7657..ecd6e84a36 100644 --- a/ext/dateutil/test/test_isoparser.py +++ b/ext/dateutil/test/test_isoparser.py @@ -120,7 +120,8 @@ def test_ymd_hms(dt, date_fmt, time_fmt, tzoffset): DATETIMES = [datetime(2017, 11, 27, 6, 14, 30, 123456)] @pytest.mark.parametrize('dt', tuple(DATETIMES)) @pytest.mark.parametrize('date_fmt', YMD_FMTS) -@pytest.mark.parametrize('time_fmt', (x + '.%f' for x in HMS_FMTS)) +@pytest.mark.parametrize('time_fmt', (x + sep + '%f' for x in HMS_FMTS + for sep in '.,')) @pytest.mark.parametrize('tzoffset', TZOFFSETS) @pytest.mark.parametrize('precision', list(range(3, 7))) def test_ymd_hms_micro(dt, date_fmt, time_fmt, tzoffset, precision): @@ -129,6 +130,15 @@ def test_ymd_hms_micro(dt, date_fmt, time_fmt, tzoffset, precision): _isoparse_date_and_time(dt, date_fmt, time_fmt, tzoffset, precision) +### +# Truncation of extra digits beyond microsecond precision +@pytest.mark.parametrize('dt_str', [ + '2018-07-03T14:07:00.123456000001', + '2018-07-03T14:07:00.123456999999', +]) +def test_extra_subsecond_digits(dt_str): + assert isoparse(dt_str) == datetime(2018, 7, 3, 14, 7, 0, 123456) + @pytest.mark.parametrize('tzoffset', FULL_TZOFFSETS) def test_full_tzoffsets(tzoffset): dt = datetime(2017, 11, 27, 6, 14, 30, 123456) @@ -139,15 +149,15 @@ def test_full_tzoffsets(tzoffset): @pytest.mark.parametrize('dt_str', [ '2014-04-11T00', - '2014-04-11T24', + '2014-04-10T24', '2014-04-11T00:00', - '2014-04-11T24:00', + '2014-04-10T24:00', '2014-04-11T00:00:00', - '2014-04-11T24:00:00', + '2014-04-10T24:00:00', '2014-04-11T00:00:00.000', - '2014-04-11T24:00:00.000', + '2014-04-10T24:00:00.000', '2014-04-11T00:00:00.000000', - '2014-04-11T24:00:00.000000'] + '2014-04-10T24:00:00.000000'] ) def test_datetime_midnight(dt_str): assert isoparse(dt_str) == datetime(2014, 4, 11, 0, 0, 0, 0) @@ -218,6 +228,8 @@ def test_iso_ordinal(isoord, dt_expected): (b'20140204T123015.224', datetime(2014, 2, 4, 12, 30, 15, 224000)), (b'2014-02-04T12:30:15.224Z', datetime(2014, 2, 4, 12, 30, 15, 224000, tz.tzutc())), + (b'2014-02-04T12:30:15.224z', datetime(2014, 2, 4, 12, 30, 15, 224000, + tz.tzutc())), (b'2014-02-04T12:30:15.224+05:00', datetime(2014, 2, 4, 12, 30, 15, 224000, tzinfo=tz.tzoffset(None, timedelta(hours=5))))]) @@ -263,12 +275,15 @@ def test_iso_raises(isostr, exception): isoparse(isostr) -@pytest.mark.parametrize('sep_act,valid_sep', [ - ('C', 'T'), - ('T', 'C') +@pytest.mark.parametrize('sep_act, valid_sep, exception', [ + ('T', 'C', ValueError), + ('C', 'T', ValueError), ]) -def test_iso_raises_sep(sep_act, valid_sep): +def test_iso_with_sep_raises(sep_act, valid_sep, exception): + parser = isoparser(sep=valid_sep) isostr = '2012-04-25' + sep_act + '01:25:00' + with pytest.raises(exception): + parser.isoparse(isostr) @pytest.mark.xfail() @@ -367,7 +382,7 @@ def test_parse_isodate(d, dt_fmt, as_bytes): d_str = d.strftime(dt_fmt) if isinstance(d_str, six.text_type) and as_bytes: d_str = d_str.encode('ascii') - elif isinstance(d_str, six.binary_type) and not as_bytes: + elif isinstance(d_str, bytes) and not as_bytes: d_str = d_str.decode('ascii') iparser = isoparser() @@ -441,29 +456,48 @@ def test_isotime(time_val, time_fmt, as_bytes): tstr = time_val.strftime(time_fmt) if isinstance(time_val, six.text_type) and as_bytes: tstr = tstr.encode('ascii') - elif isinstance(time_val, six.binary_type) and not as_bytes: + elif isinstance(time_val, bytes) and not as_bytes: tstr = tstr.decode('ascii') iparser = isoparser() assert iparser.parse_isotime(tstr) == time_val + +@pytest.mark.parametrize('isostr', [ + '24:00', + '2400', + '24:00:00', + '240000', + '24:00:00.000', + '24:00:00,000', + '24:00:00.000000', + '24:00:00,000000', +]) +def test_isotime_midnight(isostr): + iparser = isoparser() + assert iparser.parse_isotime(isostr) == time(0, 0, 0, 0) + + @pytest.mark.parametrize('isostr,exception', [ ('3', ValueError), # ISO string too short ('14時30分15秒', ValueError), # Not ASCII ('14_30_15', ValueError), # Invalid separators ('1430:15', ValueError), # Inconsistent separator use - ('14:30:15.3684000309', ValueError), # Too much us precision ('25', ValueError), # Invalid hours ('25:15', ValueError), # Invalid hours ('14:60', ValueError), # Invalid minutes ('14:59:61', ValueError), # Invalid seconds - ('14:30:15.3446830500', ValueError), # No sign in time zone + ('14:30:15.34468305:00', ValueError), # No sign in time zone ('14:30:15+', ValueError), # Time zone too short ('14:30:15+1234567', ValueError), # Time zone invalid ('14:59:59+25:00', ValueError), # Invalid tz hours ('14:59:59+12:62', ValueError), # Invalid tz minutes ('14:59:30_344583', ValueError), # Invalid microsecond separator + ('24:01', ValueError), # 24 used for non-midnight time + ('24:00:01', ValueError), # 24 used for non-midnight time + ('24:00:00.001', ValueError), # 24 used for non-midnight time + ('24:00:00.000001', ValueError), # 24 used for non-midnight time ]) def test_isotime_raises(isostr, exception): iparser = isoparser() diff --git a/ext/dateutil/test/test_parser.py b/ext/dateutil/test/test_parser.py index f8c2072040..dcaa7cc03c 100644 --- a/ext/dateutil/test/test_parser.py +++ b/ext/dateutil/test/test_parser.py @@ -14,7 +14,7 @@ from ._common import TZEnvContext from six import assertRaisesRegex, PY3 -from six.moves import StringIO +from io import StringIO import pytest @@ -27,6 +27,130 @@ except ValueError: PLATFORM_HAS_DASH_D = False +# Parser test cases using no keyword arguments. Format: (parsable_text, expected_datetime, assertion_message) +PARSER_TEST_CASES = [ + ("Thu Sep 25 10:36:28 2003", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"), + ("Thu Sep 25 2003", datetime(2003, 9, 25), "date command format strip"), + ("2003-09-25T10:49:41", datetime(2003, 9, 25, 10, 49, 41), "iso format strip"), + ("2003-09-25T10:49", datetime(2003, 9, 25, 10, 49), "iso format strip"), + ("2003-09-25T10", datetime(2003, 9, 25, 10), "iso format strip"), + ("2003-09-25", datetime(2003, 9, 25), "iso format strip"), + ("20030925T104941", datetime(2003, 9, 25, 10, 49, 41), "iso stripped format strip"), + ("20030925T1049", datetime(2003, 9, 25, 10, 49, 0), "iso stripped format strip"), + ("20030925T10", datetime(2003, 9, 25, 10), "iso stripped format strip"), + ("20030925", datetime(2003, 9, 25), "iso stripped format strip"), + ("2003-09-25 10:49:41,502", datetime(2003, 9, 25, 10, 49, 41, 502000), "python logger format"), + ("199709020908", datetime(1997, 9, 2, 9, 8), "no separator"), + ("19970902090807", datetime(1997, 9, 2, 9, 8, 7), "no separator"), + ("2003-09-25", datetime(2003, 9, 25), "date with dash"), + ("09-25-2003", datetime(2003, 9, 25), "date with dash"), + ("25-09-2003", datetime(2003, 9, 25), "date with dash"), + ("10-09-2003", datetime(2003, 10, 9), "date with dash"), + ("10-09-03", datetime(2003, 10, 9), "date with dash"), + ("2003.09.25", datetime(2003, 9, 25), "date with dot"), + ("09.25.2003", datetime(2003, 9, 25), "date with dot"), + ("25.09.2003", datetime(2003, 9, 25), "date with dot"), + ("10.09.2003", datetime(2003, 10, 9), "date with dot"), + ("10.09.03", datetime(2003, 10, 9), "date with dot"), + ("2003/09/25", datetime(2003, 9, 25), "date with slash"), + ("09/25/2003", datetime(2003, 9, 25), "date with slash"), + ("25/09/2003", datetime(2003, 9, 25), "date with slash"), + ("10/09/2003", datetime(2003, 10, 9), "date with slash"), + ("10/09/03", datetime(2003, 10, 9), "date with slash"), + ("2003 09 25", datetime(2003, 9, 25), "date with space"), + ("09 25 2003", datetime(2003, 9, 25), "date with space"), + ("25 09 2003", datetime(2003, 9, 25), "date with space"), + ("10 09 2003", datetime(2003, 10, 9), "date with space"), + ("10 09 03", datetime(2003, 10, 9), "date with space"), + ("25 09 03", datetime(2003, 9, 25), "date with space"), + ("03 25 Sep", datetime(2003, 9, 25), "strangely ordered date"), + ("25 03 Sep", datetime(2025, 9, 3), "strangely ordered date"), + (" July 4 , 1976 12:01:02 am ", datetime(1976, 7, 4, 0, 1, 2), "extra space"), + ("Wed, July 10, '96", datetime(1996, 7, 10, 0, 0), "random format"), + ("1996.July.10 AD 12:08 PM", datetime(1996, 7, 10, 12, 8), "random format"), + ("July 4, 1976", datetime(1976, 7, 4), "random format"), + ("7 4 1976", datetime(1976, 7, 4), "random format"), + ("4 jul 1976", datetime(1976, 7, 4), "random format"), + ("7-4-76", datetime(1976, 7, 4), "random format"), + ("19760704", datetime(1976, 7, 4), "random format"), + ("0:01:02 on July 4, 1976", datetime(1976, 7, 4, 0, 1, 2), "random format"), + ("0:01:02 on July 4, 1976", datetime(1976, 7, 4, 0, 1, 2), "random format"), + ("July 4, 1976 12:01:02 am", datetime(1976, 7, 4, 0, 1, 2), "random format"), + ("Mon Jan 2 04:24:27 1995", datetime(1995, 1, 2, 4, 24, 27), "random format"), + ("04.04.95 00:22", datetime(1995, 4, 4, 0, 22), "random format"), + ("Jan 1 1999 11:23:34.578", datetime(1999, 1, 1, 11, 23, 34, 578000), "random format"), + ("950404 122212", datetime(1995, 4, 4, 12, 22, 12), "random format"), + ("3rd of May 2001", datetime(2001, 5, 3), "random format"), + ("5th of March 2001", datetime(2001, 3, 5), "random format"), + ("1st of May 2003", datetime(2003, 5, 1), "random format"), + ('0099-01-01T00:00:00', datetime(99, 1, 1, 0, 0), "99 ad"), + ('0031-01-01T00:00:00', datetime(31, 1, 1, 0, 0), "31 ad"), + ("20080227T21:26:01.123456789", datetime(2008, 2, 27, 21, 26, 1, 123456), "high precision seconds"), + ('13NOV2017', datetime(2017, 11, 13), "dBY (See GH360)"), + ('0003-03-04', datetime(3, 3, 4), "pre 12 year same month (See GH PR #293)"), + ('December.0031.30', datetime(31, 12, 30), "BYd corner case (GH#687)") +] + + +@pytest.mark.parametrize("parsable_text,expected_datetime,assertion_message", PARSER_TEST_CASES) +def test_parser(parsable_text, expected_datetime, assertion_message): + assert parse(parsable_text) == expected_datetime, assertion_message + + +# Parser test cases using datetime(2003, 9, 25) as a default. +# Format: (parsable_text, expected_datetime, assertion_message) +PARSER_DEFAULT_TEST_CASES = [ + ("Thu Sep 25 10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"), + ("Thu Sep 10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"), + ("Thu 10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"), + ("Sep 10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"), + ("10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"), + ("10:36", datetime(2003, 9, 25, 10, 36), "date command format strip"), + ("Sep 2003", datetime(2003, 9, 25), "date command format strip"), + ("Sep", datetime(2003, 9, 25), "date command format strip"), + ("2003", datetime(2003, 9, 25), "date command format strip"), + ("10h36m28.5s", datetime(2003, 9, 25, 10, 36, 28, 500000), "hour with letters"), + ("10h36m28s", datetime(2003, 9, 25, 10, 36, 28), "hour with letters strip"), + ("10h36m", datetime(2003, 9, 25, 10, 36), "hour with letters strip"), + ("10h", datetime(2003, 9, 25, 10), "hour with letters strip"), + ("10 h 36", datetime(2003, 9, 25, 10, 36), "hour with letters strip"), + ("10 h 36.5", datetime(2003, 9, 25, 10, 36, 30), "hour with letter strip"), + ("36 m 5", datetime(2003, 9, 25, 0, 36, 5), "hour with letters spaces"), + ("36 m 5 s", datetime(2003, 9, 25, 0, 36, 5), "minute with letters spaces"), + ("36 m 05", datetime(2003, 9, 25, 0, 36, 5), "minute with letters spaces"), + ("36 m 05 s", datetime(2003, 9, 25, 0, 36, 5), "minutes with letters spaces"), + ("10h am", datetime(2003, 9, 25, 10), "hour am pm"), + ("10h pm", datetime(2003, 9, 25, 22), "hour am pm"), + ("10am", datetime(2003, 9, 25, 10), "hour am pm"), + ("10pm", datetime(2003, 9, 25, 22), "hour am pm"), + ("10:00 am", datetime(2003, 9, 25, 10), "hour am pm"), + ("10:00 pm", datetime(2003, 9, 25, 22), "hour am pm"), + ("10:00am", datetime(2003, 9, 25, 10), "hour am pm"), + ("10:00pm", datetime(2003, 9, 25, 22), "hour am pm"), + ("10:00a.m", datetime(2003, 9, 25, 10), "hour am pm"), + ("10:00p.m", datetime(2003, 9, 25, 22), "hour am pm"), + ("10:00a.m.", datetime(2003, 9, 25, 10), "hour am pm"), + ("10:00p.m.", datetime(2003, 9, 25, 22), "hour am pm"), + ("Wed", datetime(2003, 10, 1), "weekday alone"), + ("Wednesday", datetime(2003, 10, 1), "long weekday"), + ("October", datetime(2003, 10, 25), "long month"), + ("31-Dec-00", datetime(2000, 12, 31), "zero year"), + ("0:01:02", datetime(2003, 9, 25, 0, 1, 2), "random format"), + ("12h 01m02s am", datetime(2003, 9, 25, 0, 1, 2), "random format"), + ("12:08 PM", datetime(2003, 9, 25, 12, 8), "random format"), + ("01h02m03", datetime(2003, 9, 25, 1, 2, 3), "random format"), + ("01h02", datetime(2003, 9, 25, 1, 2), "random format"), + ("01h02s", datetime(2003, 9, 25, 1, 0, 2), "random format"), + ("01m02", datetime(2003, 9, 25, 0, 1, 2), "random format"), + ("01m02h", datetime(2003, 9, 25, 2, 1), "random format"), + ("2004 10 Apr 11h30m", datetime(2004, 4, 10, 11, 30), "random format") +] + + +@pytest.mark.parametrize("parsable_text,expected_datetime,assertion_message", PARSER_DEFAULT_TEST_CASES) +def test_parser_default(parsable_text, expected_datetime, assertion_message): + assert parse(parsable_text, default=datetime(2003, 9, 25)) == expected_datetime, assertion_message + class TestFormat(unittest.TestCase): @@ -56,30 +180,20 @@ def test_ybd(self): self.assertEqual(res, actual) -class ParserTest(unittest.TestCase): - - def setUp(self): - self.tzinfos = {"BRST": -10800} - self.brsttz = tzoffset("BRST", -10800) - self.default = datetime(2003, 9, 25) - - # Parser should be able to handle bytestring and unicode - self.uni_str = '2014-05-01 08:00:00' - self.str_str = self.uni_str.encode() - - def testEmptyString(self): - with self.assertRaises(ValueError): +class TestInputFormats(object): + def test_empty_string_invalid(self): + with pytest.raises(ValueError): parse('') - def testNone(self): - with self.assertRaises(TypeError): + def test_none_invalid(self): + with pytest.raises(TypeError): parse(None) - def testInvalidType(self): - with self.assertRaises(TypeError): + def test_int_invalid(self): + with pytest.raises(TypeError): parse(13) - def testDuckTyping(self): + def test_duck_typing(self): # We want to support arbitrary classes that implement the stream # interface. @@ -92,24 +206,48 @@ def read(self, *args, **kwargs): dstr = StringPassThrough(StringIO('2014 January 19')) - self.assertEqual(parse(dstr), datetime(2014, 1, 19)) + res = parse(dstr) + expected = datetime(2014, 1, 19) + assert res == expected - def testParseStream(self): + def test_parse_stream(self): dstr = StringIO('2014 January 19') - self.assertEqual(parse(dstr), datetime(2014, 1, 19)) + res = parse(dstr) + expected = datetime(2014, 1, 19) + assert res == expected + + def test_parse_str(self): + # Parser should be able to handle bytestring and unicode + uni_str = '2014-05-01 08:00:00' + bytes_str = uni_str.encode() + + res = parse(bytes_str) + expected = parse(uni_str) + assert res == expected + + def test_parse_bytes(self): + res = parse(b'2014 January 19') + expected = datetime(2014, 1, 19) + assert res == expected + + def test_parse_bytearray(self): + # GH#417 + res = parse(bytearray(b'2014 January 19')) + expected = datetime(2014, 1, 19) + assert res == expected - def testParseStr(self): - self.assertEqual(parse(self.str_str), - parse(self.uni_str)) - def testParseBytes(self): - self.assertEqual(parse(b'2014 January 19'), datetime(2014, 1, 19)) +class ParserTest(unittest.TestCase): - def testParseBytearray(self): - # GH #417 - self.assertEqual(parse(bytearray(b'2014 January 19')), - datetime(2014, 1, 19)) + def setUp(self): + self.tzinfos = {"BRST": -10800} + self.brsttz = tzoffset("BRST", -10800) + self.default = datetime(2003, 9, 25) + + # Parser should be able to handle bytestring and unicode + self.uni_str = '2014-05-01 08:00:00' + self.str_str = self.uni_str.encode() def testParserParseStr(self): from dateutil.parser import parser @@ -170,55 +308,12 @@ def testDateCommandFormatWithLong(self): tzinfos={"BRST": long(-10800)}), datetime(2003, 9, 25, 10, 36, 28, tzinfo=self.brsttz)) + def testDateCommandFormatIgnoreTz(self): self.assertEqual(parse("Thu Sep 25 10:36:28 BRST 2003", ignoretz=True), datetime(2003, 9, 25, 10, 36, 28)) - def testDateCommandFormatStrip1(self): - self.assertEqual(parse("Thu Sep 25 10:36:28 2003"), - datetime(2003, 9, 25, 10, 36, 28)) - - def testDateCommandFormatStrip2(self): - self.assertEqual(parse("Thu Sep 25 10:36:28", default=self.default), - datetime(2003, 9, 25, 10, 36, 28)) - - def testDateCommandFormatStrip3(self): - self.assertEqual(parse("Thu Sep 10:36:28", default=self.default), - datetime(2003, 9, 25, 10, 36, 28)) - - def testDateCommandFormatStrip4(self): - self.assertEqual(parse("Thu 10:36:28", default=self.default), - datetime(2003, 9, 25, 10, 36, 28)) - - def testDateCommandFormatStrip5(self): - self.assertEqual(parse("Sep 10:36:28", default=self.default), - datetime(2003, 9, 25, 10, 36, 28)) - - def testDateCommandFormatStrip6(self): - self.assertEqual(parse("10:36:28", default=self.default), - datetime(2003, 9, 25, 10, 36, 28)) - - def testDateCommandFormatStrip7(self): - self.assertEqual(parse("10:36", default=self.default), - datetime(2003, 9, 25, 10, 36)) - - def testDateCommandFormatStrip8(self): - self.assertEqual(parse("Thu Sep 25 2003"), - datetime(2003, 9, 25)) - - def testDateCommandFormatStrip10(self): - self.assertEqual(parse("Sep 2003", default=self.default), - datetime(2003, 9, 25)) - - def testDateCommandFormatStrip11(self): - self.assertEqual(parse("Sep", default=self.default), - datetime(2003, 9, 25)) - - def testDateCommandFormatStrip12(self): - self.assertEqual(parse("2003", default=self.default), - datetime(2003, 9, 25)) - def testDateRCommandFormat(self): self.assertEqual(parse("Thu, 25 Sep 2003 10:49:41 -0300"), datetime(2003, 9, 25, 10, 49, 41, @@ -235,20 +330,9 @@ def testISOFormatStrip1(self): tzinfo=self.brsttz)) def testISOFormatStrip2(self): - self.assertEqual(parse("2003-09-25T10:49:41"), - datetime(2003, 9, 25, 10, 49, 41)) - - def testISOFormatStrip3(self): - self.assertEqual(parse("2003-09-25T10:49"), - datetime(2003, 9, 25, 10, 49)) - - def testISOFormatStrip4(self): - self.assertEqual(parse("2003-09-25T10"), - datetime(2003, 9, 25, 10)) - - def testISOFormatStrip5(self): - self.assertEqual(parse("2003-09-25"), - datetime(2003, 9, 25)) + self.assertEqual(parse("2003-09-25T10:49:41+03:00"), + datetime(2003, 9, 25, 10, 49, 41, + tzinfo=tzoffset(None, 10800))) def testISOStrippedFormat(self): self.assertEqual(parse("20030925T104941.5-0300"), @@ -261,197 +345,42 @@ def testISOStrippedFormatStrip1(self): tzinfo=self.brsttz)) def testISOStrippedFormatStrip2(self): - self.assertEqual(parse("20030925T104941"), - datetime(2003, 9, 25, 10, 49, 41)) - - def testISOStrippedFormatStrip3(self): - self.assertEqual(parse("20030925T1049"), - datetime(2003, 9, 25, 10, 49, 0)) - - def testISOStrippedFormatStrip4(self): - self.assertEqual(parse("20030925T10"), - datetime(2003, 9, 25, 10)) - - def testISOStrippedFormatStrip5(self): - self.assertEqual(parse("20030925"), - datetime(2003, 9, 25)) - - def testPythonLoggerFormat(self): - self.assertEqual(parse("2003-09-25 10:49:41,502"), - datetime(2003, 9, 25, 10, 49, 41, 502000)) - - def testNoSeparator1(self): - self.assertEqual(parse("199709020908"), - datetime(1997, 9, 2, 9, 8)) - - def testNoSeparator2(self): - self.assertEqual(parse("19970902090807"), - datetime(1997, 9, 2, 9, 8, 7)) - - def testDateWithDash1(self): - self.assertEqual(parse("2003-09-25"), - datetime(2003, 9, 25)) - - def testDateWithDash6(self): - self.assertEqual(parse("09-25-2003"), - datetime(2003, 9, 25)) - - def testDateWithDash7(self): - self.assertEqual(parse("25-09-2003"), - datetime(2003, 9, 25)) + self.assertEqual(parse("20030925T104941+0300"), + datetime(2003, 9, 25, 10, 49, 41, + tzinfo=tzoffset(None, 10800))) def testDateWithDash8(self): self.assertEqual(parse("10-09-2003", dayfirst=True), datetime(2003, 9, 10)) - def testDateWithDash9(self): - self.assertEqual(parse("10-09-2003"), - datetime(2003, 10, 9)) - - def testDateWithDash10(self): - self.assertEqual(parse("10-09-03"), - datetime(2003, 10, 9)) - def testDateWithDash11(self): self.assertEqual(parse("10-09-03", yearfirst=True), datetime(2010, 9, 3)) - def testDateWithDot1(self): - self.assertEqual(parse("2003.09.25"), - datetime(2003, 9, 25)) - - def testDateWithDot6(self): - self.assertEqual(parse("09.25.2003"), - datetime(2003, 9, 25)) - - def testDateWithDot7(self): - self.assertEqual(parse("25.09.2003"), - datetime(2003, 9, 25)) - def testDateWithDot8(self): self.assertEqual(parse("10.09.2003", dayfirst=True), datetime(2003, 9, 10)) - def testDateWithDot9(self): - self.assertEqual(parse("10.09.2003"), - datetime(2003, 10, 9)) - - def testDateWithDot10(self): - self.assertEqual(parse("10.09.03"), - datetime(2003, 10, 9)) - def testDateWithDot11(self): self.assertEqual(parse("10.09.03", yearfirst=True), datetime(2010, 9, 3)) - def testDateWithSlash1(self): - self.assertEqual(parse("2003/09/25"), - datetime(2003, 9, 25)) - - def testDateWithSlash6(self): - self.assertEqual(parse("09/25/2003"), - datetime(2003, 9, 25)) - - def testDateWithSlash7(self): - self.assertEqual(parse("25/09/2003"), - datetime(2003, 9, 25)) - def testDateWithSlash8(self): self.assertEqual(parse("10/09/2003", dayfirst=True), datetime(2003, 9, 10)) - def testDateWithSlash9(self): - self.assertEqual(parse("10/09/2003"), - datetime(2003, 10, 9)) - - def testDateWithSlash10(self): - self.assertEqual(parse("10/09/03"), - datetime(2003, 10, 9)) - def testDateWithSlash11(self): self.assertEqual(parse("10/09/03", yearfirst=True), datetime(2010, 9, 3)) - def testDateWithSpace1(self): - self.assertEqual(parse("2003 09 25"), - datetime(2003, 9, 25)) - - def testDateWithSpace6(self): - self.assertEqual(parse("09 25 2003"), - datetime(2003, 9, 25)) - - def testDateWithSpace7(self): - self.assertEqual(parse("25 09 2003"), - datetime(2003, 9, 25)) - def testDateWithSpace8(self): self.assertEqual(parse("10 09 2003", dayfirst=True), datetime(2003, 9, 10)) - def testDateWithSpace9(self): - self.assertEqual(parse("10 09 2003"), - datetime(2003, 10, 9)) - - def testDateWithSpace10(self): - self.assertEqual(parse("10 09 03"), - datetime(2003, 10, 9)) - def testDateWithSpace11(self): self.assertEqual(parse("10 09 03", yearfirst=True), datetime(2010, 9, 3)) - def testDateWithSpace12(self): - self.assertEqual(parse("25 09 03"), - datetime(2003, 9, 25)) - - def testStrangelyOrderedDate1(self): - self.assertEqual(parse("03 25 Sep"), - datetime(2003, 9, 25)) - - def testStrangelyOrderedDate3(self): - self.assertEqual(parse("25 03 Sep"), - datetime(2025, 9, 3)) - - def testHourWithLetters(self): - self.assertEqual(parse("10h36m28.5s", default=self.default), - datetime(2003, 9, 25, 10, 36, 28, 500000)) - - def testHourWithLettersStrip1(self): - self.assertEqual(parse("10h36m28s", default=self.default), - datetime(2003, 9, 25, 10, 36, 28)) - - def testHourWithLettersStrip2(self): - self.assertEqual(parse("10h36m", default=self.default), - datetime(2003, 9, 25, 10, 36)) - - def testHourWithLettersStrip3(self): - self.assertEqual(parse("10h", default=self.default), - datetime(2003, 9, 25, 10)) - - def testHourWithLettersStrip4(self): - self.assertEqual(parse("10 h 36", default=self.default), - datetime(2003, 9, 25, 10, 36)) - - def testHourWithLetterStrip5(self): - self.assertEqual(parse("10 h 36.5", default=self.default), - datetime(2003, 9, 25, 10, 36, 30)) - - def testMinuteWithLettersSpaces1(self): - self.assertEqual(parse("36 m 5", default=self.default), - datetime(2003, 9, 25, 0, 36, 5)) - - def testMinuteWithLettersSpaces2(self): - self.assertEqual(parse("36 m 5 s", default=self.default), - datetime(2003, 9, 25, 0, 36, 5)) - - def testMinuteWithLettersSpaces3(self): - self.assertEqual(parse("36 m 05", default=self.default), - datetime(2003, 9, 25, 0, 36, 5)) - - def testMinuteWithLettersSpaces4(self): - self.assertEqual(parse("36 m 05 s", default=self.default), - datetime(2003, 9, 25, 0, 36, 5)) - def testAMPMNoHour(self): with self.assertRaises(ValueError): parse("AM") @@ -459,54 +388,6 @@ def testAMPMNoHour(self): with self.assertRaises(ValueError): parse("Jan 20, 2015 PM") - def testHourAmPm1(self): - self.assertEqual(parse("10h am", default=self.default), - datetime(2003, 9, 25, 10)) - - def testHourAmPm2(self): - self.assertEqual(parse("10h pm", default=self.default), - datetime(2003, 9, 25, 22)) - - def testHourAmPm3(self): - self.assertEqual(parse("10am", default=self.default), - datetime(2003, 9, 25, 10)) - - def testHourAmPm4(self): - self.assertEqual(parse("10pm", default=self.default), - datetime(2003, 9, 25, 22)) - - def testHourAmPm5(self): - self.assertEqual(parse("10:00 am", default=self.default), - datetime(2003, 9, 25, 10)) - - def testHourAmPm6(self): - self.assertEqual(parse("10:00 pm", default=self.default), - datetime(2003, 9, 25, 22)) - - def testHourAmPm7(self): - self.assertEqual(parse("10:00am", default=self.default), - datetime(2003, 9, 25, 10)) - - def testHourAmPm8(self): - self.assertEqual(parse("10:00pm", default=self.default), - datetime(2003, 9, 25, 22)) - - def testHourAmPm9(self): - self.assertEqual(parse("10:00a.m", default=self.default), - datetime(2003, 9, 25, 10)) - - def testHourAmPm10(self): - self.assertEqual(parse("10:00p.m", default=self.default), - datetime(2003, 9, 25, 22)) - - def testHourAmPm11(self): - self.assertEqual(parse("10:00a.m.", default=self.default), - datetime(2003, 9, 25, 10)) - - def testHourAmPm12(self): - self.assertEqual(parse("10:00p.m.", default=self.default), - datetime(2003, 9, 25, 22)) - def testAMPMRange(self): with self.assertRaises(ValueError): parse("13:44 AM") @@ -520,22 +401,6 @@ def testPertain(self): self.assertEqual(parse("Sep of 03", default=self.default), datetime(2003, 9, 25)) - def testWeekdayAlone(self): - self.assertEqual(parse("Wed", default=self.default), - datetime(2003, 10, 1)) - - def testLongWeekday(self): - self.assertEqual(parse("Wednesday", default=self.default), - datetime(2003, 10, 1)) - - def testLongMonth(self): - self.assertEqual(parse("October", default=self.default), - datetime(2003, 10, 25)) - - def testZeroYear(self): - self.assertEqual(parse("31-Dec-00", default=self.default), - datetime(2000, 12, 31)) - def testFuzzy(self): s = "Today is 25 of September of 2003, exactly " \ "at 10:49:41 with timezone -03:00." @@ -578,23 +443,11 @@ def testFuzzyIgnoreAMPM(self): res = parse(s1, fuzzy=True) self.assertEqual(res, datetime(1945, 1, 29, 14, 45)) - def testExtraSpace(self): - self.assertEqual(parse(" July 4 , 1976 12:01:02 am "), - datetime(1976, 7, 4, 0, 1, 2)) - - def testRandomFormat1(self): - self.assertEqual(parse("Wed, July 10, '96"), - datetime(1996, 7, 10, 0, 0)) - def testRandomFormat2(self): self.assertEqual(parse("1996.07.10 AD at 15:08:56 PDT", ignoretz=True), datetime(1996, 7, 10, 15, 8, 56)) - def testRandomFormat3(self): - self.assertEqual(parse("1996.July.10 AD 12:08 PM"), - datetime(1996, 7, 10, 12, 8)) - def testRandomFormat4(self): self.assertEqual(parse("Tuesday, April 12, 1952 AD 3:30:42pm PST", ignoretz=True), @@ -615,121 +468,30 @@ def testRandomFormat7(self): ignoretz=True), datetime(1994, 11, 5, 8, 15, 30)) - def testRandomFormat8(self): - self.assertEqual(parse("July 4, 1976"), datetime(1976, 7, 4)) - - def testRandomFormat9(self): - self.assertEqual(parse("7 4 1976"), datetime(1976, 7, 4)) - - def testRandomFormat10(self): - self.assertEqual(parse("4 jul 1976"), datetime(1976, 7, 4)) - - def testRandomFormat11(self): - self.assertEqual(parse("7-4-76"), datetime(1976, 7, 4)) - - def testRandomFormat12(self): - self.assertEqual(parse("19760704"), datetime(1976, 7, 4)) - - def testRandomFormat13(self): - self.assertEqual(parse("0:01:02", default=self.default), - datetime(2003, 9, 25, 0, 1, 2)) - - def testRandomFormat14(self): - self.assertEqual(parse("12h 01m02s am", default=self.default), - datetime(2003, 9, 25, 0, 1, 2)) - - def testRandomFormat15(self): - self.assertEqual(parse("0:01:02 on July 4, 1976"), - datetime(1976, 7, 4, 0, 1, 2)) - - def testRandomFormat16(self): - self.assertEqual(parse("0:01:02 on July 4, 1976"), - datetime(1976, 7, 4, 0, 1, 2)) - def testRandomFormat17(self): self.assertEqual(parse("1976-07-04T00:01:02Z", ignoretz=True), datetime(1976, 7, 4, 0, 1, 2)) def testRandomFormat18(self): - self.assertEqual(parse("July 4, 1976 12:01:02 am"), - datetime(1976, 7, 4, 0, 1, 2)) - - def testRandomFormat19(self): - self.assertEqual(parse("Mon Jan 2 04:24:27 1995"), - datetime(1995, 1, 2, 4, 24, 27)) + self.assertEqual(parse("1986-07-05T08:15:30z", + ignoretz=True), + datetime(1986, 7, 5, 8, 15, 30)) def testRandomFormat20(self): self.assertEqual(parse("Tue Apr 4 00:22:12 PDT 1995", ignoretz=True), datetime(1995, 4, 4, 0, 22, 12)) - def testRandomFormat21(self): - self.assertEqual(parse("04.04.95 00:22"), - datetime(1995, 4, 4, 0, 22)) - - def testRandomFormat22(self): - self.assertEqual(parse("Jan 1 1999 11:23:34.578"), - datetime(1999, 1, 1, 11, 23, 34, 578000)) - - def testRandomFormat23(self): - self.assertEqual(parse("950404 122212"), - datetime(1995, 4, 4, 12, 22, 12)) - def testRandomFormat24(self): self.assertEqual(parse("0:00 PM, PST", default=self.default, ignoretz=True), datetime(2003, 9, 25, 12, 0)) - def testRandomFormat25(self): - self.assertEqual(parse("12:08 PM", default=self.default), - datetime(2003, 9, 25, 12, 8)) - def testRandomFormat26(self): with pytest.warns(UnknownTimezoneWarning): res = parse("5:50 A.M. on June 13, 1990") self.assertEqual(res, datetime(1990, 6, 13, 5, 50)) - def testRandomFormat27(self): - self.assertEqual(parse("3rd of May 2001"), datetime(2001, 5, 3)) - - def testRandomFormat28(self): - self.assertEqual(parse("5th of March 2001"), datetime(2001, 3, 5)) - - def testRandomFormat29(self): - self.assertEqual(parse("1st of May 2003"), datetime(2003, 5, 1)) - - def testRandomFormat30(self): - self.assertEqual(parse("01h02m03", default=self.default), - datetime(2003, 9, 25, 1, 2, 3)) - - def testRandomFormat31(self): - self.assertEqual(parse("01h02", default=self.default), - datetime(2003, 9, 25, 1, 2)) - - def testRandomFormat32(self): - self.assertEqual(parse("01h02s", default=self.default), - datetime(2003, 9, 25, 1, 0, 2)) - - def testRandomFormat33(self): - self.assertEqual(parse("01m02", default=self.default), - datetime(2003, 9, 25, 0, 1, 2)) - - def testRandomFormat34(self): - self.assertEqual(parse("01m02h", default=self.default), - datetime(2003, 9, 25, 2, 1)) - - def testRandomFormat35(self): - self.assertEqual(parse("2004 10 Apr 11h30m", default=self.default), - datetime(2004, 4, 10, 11, 30)) - - def test_99_ad(self): - self.assertEqual(parse('0099-01-01T00:00:00'), - datetime(99, 1, 1, 0, 0)) - - def test_31_ad(self): - self.assertEqual(parse('0031-01-01T00:00:00'), - datetime(31, 1, 1, 0, 0)) - def testInvalidDay(self): with self.assertRaises(ValueError): parse("Feb 30, 2007") @@ -802,10 +564,6 @@ def testMicrosecondPrecisionErrorReturns(self): dt = datetime(2008, 2, 27, 21, 26, 1, ms) self.assertEqual(parse(dt.isoformat()), dt) - def testHighPrecisionSeconds(self): - self.assertEqual(parse("20080227T21:26:01.123456789"), - datetime(2008, 2, 27, 21, 26, 1, 123456)) - def testCustomParserInfo(self): # Custom parser info wasn't working, as Michael Elsdörfer discovered. from dateutil.parser import parserinfo, parser @@ -900,12 +658,6 @@ def test_idx_check(self): res = parse(dtstr, fuzzy=True) self.assertEqual(res, datetime(2017, 7, 17, 6, 15)) - def test_dBY(self): - # See GH360 - dtstr = '13NOV2017' - res = parse(dtstr) - self.assertEqual(res, datetime(2017, 11, 13)) - def test_hmBY(self): # See GH#483 dtstr = '02:17NOV2017' @@ -923,11 +675,6 @@ def test_era_trailing_year(self): res = parse(dstr) assert res.year == 2001, res - def test_pre_12_year_same_month(self): - # See GH PR #293 - dtstr = '0003-03-04' - assert parse(dtstr) == datetime(3, 3, 4) - class TestParseUnimplementedCases(object): @pytest.mark.xfail @@ -1036,6 +783,7 @@ def test_unambiguous_YYYYMM(self): expected = datetime(2017, 12, 1) assert res == expected + @pytest.mark.skipif(IS_WIN, reason='Windows does not use TZ var') def test_parse_unambiguous_nonexistent_local(): # When dates are specified "EST" even when they should be "EDT" in the @@ -1106,9 +854,3 @@ def test_decimal_error(value): # constructed with an invalid value with pytest.raises(ValueError): parse(value) - - -def test_BYd_corner_case(): - # GH#687 - res = parse('December.0031.30') - assert res == datetime(31, 12, 30) diff --git a/ext/dateutil/test/test_relativedelta.py b/ext/dateutil/test/test_relativedelta.py index 70cb543a4b..89cc808d2c 100644 --- a/ext/dateutil/test/test_relativedelta.py +++ b/ext/dateutil/test/test_relativedelta.py @@ -125,6 +125,14 @@ def testNextWenesdayNotToday(self): self.assertEqual(self.today+relativedelta(days=+1, weekday=WE), date(2003, 9, 24)) + def testAddMoreThan12Months(self): + self.assertEqual(date(2003, 12, 1) + relativedelta(months=+13), + date(2005, 1, 1)) + + def testAddNegativeMonths(self): + self.assertEqual(date(2003, 1, 1) + relativedelta(months=-2), + date(2002, 11, 1)) + def test15thISOYearWeek(self): self.assertEqual(date(2003, 1, 1) + relativedelta(day=4, weeks=+14, weekday=MO(-1)), @@ -350,6 +358,16 @@ def testRelativeDeltaFractionalMonth(self): with self.assertRaises(ValueError): relativedelta(months=1.5) + def testRelativeDeltaInvalidDatetimeObject(self): + with self.assertRaises(TypeError): + relativedelta(dt1='2018-01-01', dt2='2018-01-02') + + with self.assertRaises(TypeError): + relativedelta(dt1=datetime(2018, 1, 1), dt2='2018-01-02') + + with self.assertRaises(TypeError): + relativedelta(dt1='2018-01-01', dt2=datetime(2018, 1, 2)) + def testRelativeDeltaFractionalAbsolutes(self): # Fractional absolute values will soon be unsupported, # check for the deprecation warning. diff --git a/ext/dateutil/test/test_rrule.py b/ext/dateutil/test/test_rrule.py index cd08ce29dd..9dfa5444b3 100644 --- a/ext/dateutil/test/test_rrule.py +++ b/ext/dateutil/test/test_rrule.py @@ -2853,6 +2853,74 @@ def testStrSetExDate(self): datetime(1997, 9, 9, 9, 0), datetime(1997, 9, 16, 9, 0)]) + def testStrSetExDateMultiple(self): + rrstr = ("DTSTART:19970902T090000\n" + "RRULE:FREQ=YEARLY;COUNT=6;BYDAY=TU,TH\n" + "EXDATE:19970904T090000,19970911T090000,19970918T090000\n") + + rr = rrulestr(rrstr) + assert list(rr) == [datetime(1997, 9, 2, 9, 0), + datetime(1997, 9, 9, 9, 0), + datetime(1997, 9, 16, 9, 0)] + + def testStrSetExDateWithTZID(self): + BXL = tz.gettz('Europe/Brussels') + rr = rrulestr("DTSTART;TZID=Europe/Brussels:19970902T090000\n" + "RRULE:FREQ=YEARLY;COUNT=6;BYDAY=TU,TH\n" + "EXDATE;TZID=Europe/Brussels:19970904T090000\n" + "EXDATE;TZID=Europe/Brussels:19970911T090000\n" + "EXDATE;TZID=Europe/Brussels:19970918T090000\n") + + assert list(rr) == [datetime(1997, 9, 2, 9, 0, tzinfo=BXL), + datetime(1997, 9, 9, 9, 0, tzinfo=BXL), + datetime(1997, 9, 16, 9, 0, tzinfo=BXL)] + + def testStrSetExDateValueDateTimeNoTZID(self): + rrstr = '\n'.join([ + "DTSTART:19970902T090000", + "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH", + "EXDATE;VALUE=DATE-TIME:19970902T090000", + "EXDATE;VALUE=DATE-TIME:19970909T090000", + ]) + + rr = rrulestr(rrstr) + assert list(rr) == [datetime(1997, 9, 4, 9), datetime(1997, 9, 11, 9)] + + def testStrSetExDateValueMixDateTimeNoTZID(self): + rrstr = '\n'.join([ + "DTSTART:19970902T090000", + "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH", + "EXDATE;VALUE=DATE-TIME:19970902T090000", + "EXDATE:19970909T090000", + ]) + + rr = rrulestr(rrstr) + assert list(rr) == [datetime(1997, 9, 4, 9), datetime(1997, 9, 11, 9)] + + def testStrSetExDateValueDateTimeWithTZID(self): + BXL = tz.gettz('Europe/Brussels') + rrstr = '\n'.join([ + "DTSTART;VALUE=DATE-TIME;TZID=Europe/Brussels:19970902T090000", + "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH", + "EXDATE;VALUE=DATE-TIME;TZID=Europe/Brussels:19970902T090000", + "EXDATE;VALUE=DATE-TIME;TZID=Europe/Brussels:19970909T090000", + ]) + + rr = rrulestr(rrstr) + assert list(rr) == [datetime(1997, 9, 4, 9, tzinfo=BXL), + datetime(1997, 9, 11, 9, tzinfo=BXL)] + + def testStrSetExDateValueDate(self): + rrstr = '\n'.join([ + "DTSTART;VALUE=DATE:19970902", + "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH", + "EXDATE;VALUE=DATE:19970902", + "EXDATE;VALUE=DATE:19970909", + ]) + + rr = rrulestr(rrstr) + assert list(rr) == [datetime(1997, 9, 4), datetime(1997, 9, 11)] + def testStrSetDateAndExDate(self): self.assertEqual(list(rrulestr( "DTSTART:19970902T090000\n" @@ -2929,6 +2997,11 @@ def testStrValueDate(self): self.assertEqual(list(rr), [datetime(1997, 9, 2, 0, 0, 0), datetime(1998, 9, 2, 0, 0, 0)]) + def testStrMultipleDTStartComma(self): + with pytest.raises(ValueError): + rr = rrulestr("DTSTART:19970101T000000,19970202T000000\n" + "RRULE:FREQ=YEARLY;COUNT=1") + def testStrInvalidUntil(self): with self.assertRaises(ValueError): list(rrulestr("DTSTART:19970902T090000\n" diff --git a/ext/dateutil/test/test_tz.py b/ext/dateutil/test/test_tz.py index 54dfb1bd0c..bb0f4b7de7 100644 --- a/ext/dateutil/test/test_tz.py +++ b/ext/dateutil/test/test_tz.py @@ -8,12 +8,15 @@ from datetime import datetime, timedelta from datetime import time as dt_time from datetime import tzinfo -from six import BytesIO, StringIO +from six import PY2 +from io import BytesIO, StringIO import unittest import sys import base64 import copy +import gc +import weakref from functools import partial @@ -154,6 +157,8 @@ EST_TUPLE = ('EST', timedelta(hours=-5), timedelta(hours=0)) EDT_TUPLE = ('EDT', timedelta(hours=-4), timedelta(hours=1)) +SUPPORTS_SUB_MINUTE_OFFSETS = sys.version_info >= (3, 6) + ### # Helper functions @@ -731,6 +736,28 @@ def testTzOffsetSingletonDifferent(self): assert tz1 is tz2 + +@pytest.mark.smoke +@pytest.mark.tzoffset +def test_tzoffset_weakref(): + UTC1 = tz.tzoffset('UTC', 0) + UTC_ref = weakref.ref(tz.tzoffset('UTC', 0)) + UTC1 is UTC_ref() + del UTC1 + gc.collect() + + assert UTC_ref() is not None # Should be in the strong cache + assert UTC_ref() is tz.tzoffset('UTC', 0) + + # Fill the strong cache with other items + for offset in range(5,15): + tz.tzoffset('RandomZone', offset) + + gc.collect() + assert UTC_ref() is None + assert UTC_ref() is not tz.tzoffset('UTC', 0) + + @pytest.mark.tzoffset @pytest.mark.parametrize('args', [ ('UTC', 0), @@ -744,6 +771,25 @@ def test_tzoffset_singleton(args): assert tz1 is tz2 + +@pytest.mark.tzoffset +@pytest.mark.skipif(not SUPPORTS_SUB_MINUTE_OFFSETS, + reason='Sub-minute offsets not supported') +def test_tzoffset_sub_minute(): + delta = timedelta(hours=12, seconds=30) + test_datetime = datetime(2000, 1, 1, tzinfo=tz.tzoffset(None, delta)) + assert test_datetime.utcoffset() == delta + + +@pytest.mark.tzoffset +@pytest.mark.skipif(SUPPORTS_SUB_MINUTE_OFFSETS, + reason='Sub-minute offsets supported') +def test_tzoffset_sub_minute_rounding(): + delta = timedelta(hours=12, seconds=30) + test_date = datetime(2000, 1, 1, tzinfo=tz.tzoffset(None, delta)) + assert test_date.utcoffset() == timedelta(hours=12, minutes=1) + + @pytest.mark.tzlocal class TzLocalTest(unittest.TestCase): def testEquality(self): @@ -1037,6 +1083,25 @@ def testGettzCacheTzLocal(self): assert local1 is not local2 + +@pytest.mark.gettz +@pytest.mark.parametrize('badzone', [ + 'Fake.Region/Abcdefghijklmnop', # Violates several tz project name rules +]) +def test_gettz_badzone(badzone): + # Make sure passing a bad TZ string to gettz returns None (GH #800) + tzi = tz.gettz(badzone) + assert tzi is None + + +@pytest.mark.gettz +def test_gettz_badzone_unicode(): + # Make sure a unicode string can be passed to TZ (GH #802) + # When fixed, combine this with test_gettz_badzone + tzi = tz.gettz('🐼') + assert tzi is None + + @pytest.mark.gettz @pytest.mark.xfail(IS_WIN, reason='zoneinfo separately cached') def test_gettz_cache_clear(): @@ -1047,6 +1112,52 @@ def test_gettz_cache_clear(): assert NYC1 is not NYC2 +@pytest.mark.gettz +@pytest.mark.xfail(IS_WIN, reason='zoneinfo separately cached') +def test_gettz_set_cache_size(): + tz.gettz.cache_clear() + tz.gettz.set_cache_size(3) + + MONACO_ref = weakref.ref(tz.gettz('Europe/Monaco')) + EASTER_ref = weakref.ref(tz.gettz('Pacific/Easter')) + CURRIE_ref = weakref.ref(tz.gettz('Australia/Currie')) + + gc.collect() + + assert MONACO_ref() is not None + assert EASTER_ref() is not None + assert CURRIE_ref() is not None + + tz.gettz.set_cache_size(2) + gc.collect() + + assert MONACO_ref() is None + +@pytest.mark.xfail(IS_WIN, reason="Windows does not use system zoneinfo") +@pytest.mark.smoke +@pytest.mark.gettz +def test_gettz_weakref(): + tz.gettz.cache_clear() + tz.gettz.set_cache_size(2) + NYC1 = tz.gettz('America/New_York') + NYC_ref = weakref.ref(tz.gettz('America/New_York')) + + assert NYC1 is NYC_ref() + + del NYC1 + gc.collect() + + assert NYC_ref() is not None # Should still be in the strong cache + assert tz.gettz('America/New_York') is NYC_ref() + + # Populate strong cache with other timezones + tz.gettz('Europe/Monaco') + tz.gettz('Pacific/Easter') + tz.gettz('Australia/Currie') + + gc.collect() + assert NYC_ref() is None # Should have been pushed out + assert tz.gettz('America/New_York') is not NYC_ref() class ZoneInfoGettzTest(GettzTest, WarningTestMixin): def gettz(self, name): @@ -1375,6 +1486,28 @@ def testTzStrInstance(self): # Ensure that these still are all the same zone assert tz1 == tz2 == tz3 + +@pytest.mark.smoke +@pytest.mark.tzstr +def test_tzstr_weakref(): + tz_t1 = tz.tzstr('EST5EDT') + tz_t2_ref = weakref.ref(tz.tzstr('EST5EDT')) + assert tz_t1 is tz_t2_ref() + + del tz_t1 + gc.collect() + + assert tz_t2_ref() is not None + assert tz.tzstr('EST5EDT') is tz_t2_ref() + + for offset in range(5,15): + tz.tzstr('GMT+{}'.format(offset)) + gc.collect() + + assert tz_t2_ref() is None + assert tz.tzstr('EST5EDT') is not tz_t2_ref() + + @pytest.mark.tzstr @pytest.mark.parametrize('tz_str,expected', [ # From https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html @@ -1859,12 +1992,6 @@ def testFilestreamWithNameRepr(self): tzc = tz.tzfile(fileobj) self.assertEqual(repr(tzc), 'tzfile(' + repr('foo') + ')') - def testRoundNonFullMinutes(self): - # This timezone has an offset of 5992 seconds in 1900-01-01. - tzc = tz.tzfile(BytesIO(base64.b64decode(EUROPE_HELSINKI))) - self.assertEqual(str(datetime(1900, 1, 1, 0, 0, tzinfo=tzc)), - "1900-01-01 00:00:00+01:40") - def testLeapCountDecodesProperly(self): # This timezone has leapcnt, and failed to decode until # Eugene Oden notified about the issue. @@ -1925,6 +2052,40 @@ def testTZSetDoesntCorrupt(self): self.assertEqual(str(dt), '2014-07-20 12:34:56+00:00') +@pytest.mark.tzfile +@pytest.mark.skipif(not SUPPORTS_SUB_MINUTE_OFFSETS, + reason='Sub-minute offsets not supported') +def test_tzfile_sub_minute_offset(): + # If user running python 3.6 or newer, exact offset is used + tzc = tz.tzfile(BytesIO(base64.b64decode(EUROPE_HELSINKI))) + offset = timedelta(hours=1, minutes=39, seconds=52) + assert datetime(1900, 1, 1, 0, 0, tzinfo=tzc).utcoffset() == offset + + +@pytest.mark.tzfile +@pytest.mark.skipif(SUPPORTS_SUB_MINUTE_OFFSETS, + reason='Sub-minute offsets supported.') +def test_sub_minute_rounding_tzfile(): + # This timezone has an offset of 5992 seconds in 1900-01-01. + # For python version pre-3.6, this will be rounded + tzc = tz.tzfile(BytesIO(base64.b64decode(EUROPE_HELSINKI))) + offset = timedelta(hours=1, minutes=40) + assert datetime(1900, 1, 1, 0, 0, tzinfo=tzc).utcoffset() == offset + + +@pytest.mark.tzfile +def test_samoa_transition(): + # utcoffset() was erroneously returning +14:00 an hour early (GH #812) + APIA = tz.gettz('Pacific/Apia') + dt = datetime(2011, 12, 29, 23, 59, tzinfo=APIA) + assert dt.utcoffset() == timedelta(hours=-10) + + # Make sure the transition actually works, too + dt_after = (dt.astimezone(tz.UTC) + timedelta(minutes=1)).astimezone(APIA) + assert dt_after == datetime(2011, 12, 31, tzinfo=APIA) + assert dt_after.utcoffset() == timedelta(hours=14) + + @unittest.skipUnless(IS_WIN, "Requires Windows") class TzWinTest(unittest.TestCase, TzWinFoldMixin): def setUp(self): @@ -2472,22 +2633,44 @@ def testSpecifiedTzOverridesAttached(self): self.assertFalse(tz.datetime_exists(dt, tz=AEST)) -class EnfoldTest(unittest.TestCase): - def testEnterFoldDefault(self): +class TestEnfold: + def test_enter_fold_default(self): dt = tz.enfold(datetime(2020, 1, 19, 3, 32)) - self.assertEqual(dt.fold, 1) + assert dt.fold == 1 - def testEnterFold(self): + def test_enter_fold(self): dt = tz.enfold(datetime(2020, 1, 19, 3, 32), fold=1) - self.assertEqual(dt.fold, 1) + assert dt.fold == 1 - def testExitFold(self): + def test_exit_fold(self): dt = tz.enfold(datetime(2020, 1, 19, 3, 32), fold=0) # Before Python 3.6, dt.fold won't exist if fold is 0. - self.assertEqual(getattr(dt, 'fold', 0), 0) + assert getattr(dt, 'fold', 0) == 0 + + def test_defold(self): + dt = tz.enfold(datetime(2020, 1, 19, 3, 32), fold=1) + + dt2 = tz.enfold(dt, fold=0) + + assert getattr(dt2, 'fold', 0) == 0 + + def test_fold_replace_args(self): + # This test can be dropped when Python < 3.6 is dropped, since it + # is mainly to cover the `replace` method on _DatetimeWithFold + dt = tz.enfold(datetime(1950, 1, 2, 12, 30, 15, 8), fold=1) + + dt2 = dt.replace(1952, 2, 3, 13, 31, 16, 9) + assert dt2 == tz.enfold(datetime(1952, 2, 3, 13, 31, 16, 9), fold=1) + assert dt2.fold == 1 + + def test_fold_replace_exception_duplicate_args(self): + dt = tz.enfold(datetime(1999, 1, 3), fold=1) + + with pytest.raises(TypeError): + dt.replace(1950, year=2000) @pytest.mark.tz_resolve_imaginary @@ -2569,8 +2752,7 @@ def __get_kiritimati_resolve_imaginary_test(): return (tzi, ) + dates -@pytest.mark.tz_resolve_imaginary -@pytest.mark.parametrize('tzi, dt, dt_exp', [ +resolve_imaginary_tests = [ (tz.gettz('Europe/London'), datetime(2018, 3, 25, 1, 30), datetime(2018, 3, 25, 2, 30)), (tz.gettz('America/New_York'), @@ -2578,24 +2760,20 @@ def __get_kiritimati_resolve_imaginary_test(): (tz.gettz('Australia/Sydney'), datetime(2014, 10, 5, 2, 0), datetime(2014, 10, 5, 3, 0)), __get_kiritimati_resolve_imaginary_test(), -]) -def test_resolve_imaginary(tzi, dt, dt_exp): - dt = dt.replace(tzinfo=tzi) - dt_exp = dt_exp.replace(tzinfo=tzi) +] - dt_r = tz.resolve_imaginary(dt) - assert dt_r == dt_exp - assert dt_r.tzname() == dt_exp.tzname() - assert dt_r.utcoffset() == dt_exp.utcoffset() + +if SUPPORTS_SUB_MINUTE_OFFSETS: + resolve_imaginary_tests.append( + (tz.gettz('Africa/Monrovia'), + datetime(1972, 1, 7, 0, 30), datetime(1972, 1, 7, 1, 14, 30))) -@pytest.mark.xfail @pytest.mark.tz_resolve_imaginary -def test_resolve_imaginary_monrovia(): - # See GH #582 - When that is resolved, move this into test_resolve_imaginary - tzi = tz.gettz('Africa/Monrovia') - dt = datetime(1972, 1, 7, hour=0, minute=30, second=0, tzinfo=tzi) - dt_exp = datetime(1972, 1, 7, hour=1, minute=14, second=30, tzinfo=tzi) +@pytest.mark.parametrize('tzi, dt, dt_exp', resolve_imaginary_tests) +def test_resolve_imaginary(tzi, dt, dt_exp): + dt = dt.replace(tzinfo=tzi) + dt_exp = dt_exp.replace(tzinfo=tzi) dt_r = tz.resolve_imaginary(dt) assert dt_r == dt_exp diff --git a/ext/dateutil/tz/_common.py b/ext/dateutil/tz/_common.py index ccabb7da63..594e08234e 100644 --- a/ext/dateutil/tz/_common.py +++ b/ext/dateutil/tz/_common.py @@ -1,4 +1,4 @@ -from six import PY3 +from six import PY2 from functools import wraps @@ -16,14 +16,18 @@ def tzname_in_python2(namefunc): tzname() API changed in Python 3. It used to return bytes, but was changed to unicode strings """ - def adjust_encoding(*args, **kwargs): - name = namefunc(*args, **kwargs) - if name is not None and not PY3: - name = name.encode() - - return name - - return adjust_encoding + if PY2: + @wraps(namefunc) + def adjust_encoding(*args, **kwargs): + name = namefunc(*args, **kwargs) + if name is not None: + name = name.encode() + + return name + + return adjust_encoding + else: + return namefunc # The following is adapted from Alexander Belopolsky's tz library diff --git a/ext/dateutil/tz/_factories.py b/ext/dateutil/tz/_factories.py index de2e0c1de7..d2560eb738 100644 --- a/ext/dateutil/tz/_factories.py +++ b/ext/dateutil/tz/_factories.py @@ -1,4 +1,6 @@ from datetime import timedelta +import weakref +from collections import OrderedDict class _TzSingleton(type): @@ -11,6 +13,7 @@ def __call__(cls): cls.__instance = super(_TzSingleton, cls).__call__() return cls.__instance + class _TzFactory(type): def instance(cls, *args, **kwargs): """Alternate constructor that returns a fresh instance""" @@ -19,7 +22,9 @@ def instance(cls, *args, **kwargs): class _TzOffsetFactory(_TzFactory): def __init__(cls, *args, **kwargs): - cls.__instances = {} + cls.__instances = weakref.WeakValueDictionary() + cls.__strong_cache = OrderedDict() + cls.__strong_cache_size = 8 def __call__(cls, name, offset): if isinstance(offset, timedelta): @@ -31,12 +36,22 @@ def __call__(cls, name, offset): if instance is None: instance = cls.__instances.setdefault(key, cls.instance(name, offset)) + + cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance) + + # Remove an item if the strong cache is overpopulated + # TODO: Maybe this should be under a lock? + if len(cls.__strong_cache) > cls.__strong_cache_size: + cls.__strong_cache.popitem(last=False) + return instance class _TzStrFactory(_TzFactory): def __init__(cls, *args, **kwargs): - cls.__instances = {} + cls.__instances = weakref.WeakValueDictionary() + cls.__strong_cache = OrderedDict() + cls.__strong_cache_size = 8 def __call__(cls, s, posix_offset=False): key = (s, posix_offset) @@ -45,5 +60,14 @@ def __call__(cls, s, posix_offset=False): if instance is None: instance = cls.__instances.setdefault(key, cls.instance(s, posix_offset)) + + cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance) + + + # Remove an item if the strong cache is overpopulated + # TODO: Maybe this should be under a lock? + if len(cls.__strong_cache) > cls.__strong_cache_size: + cls.__strong_cache.popitem(last=False) + return instance diff --git a/ext/dateutil/tz/tz.py b/ext/dateutil/tz/tz.py index ac82b9c83d..d05414e76d 100644 --- a/ext/dateutil/tz/tz.py +++ b/ext/dateutil/tz/tz.py @@ -13,6 +13,8 @@ import sys import os import bisect +import weakref +from collections import OrderedDict import six from six import string_types @@ -28,6 +30,9 @@ except ImportError: tzwin = tzwinlocal = None +# For warning about rounding tzinfo +from warnings import warn + ZERO = datetime.timedelta(0) EPOCH = datetime.datetime.utcfromtimestamp(0) EPOCHORDINAL = EPOCH.toordinal() @@ -137,7 +142,8 @@ def __init__(self, name, offset): offset = offset.total_seconds() except (TypeError, AttributeError): pass - self._offset = datetime.timedelta(seconds=offset) + + self._offset = datetime.timedelta(seconds=_get_supported_offset(offset)) def utcoffset(self, dt): return self._offset @@ -460,7 +466,7 @@ def __init__(self, fileobj, filename=None): if fileobj is not None: if not file_opened_here: - fileobj = _ContextWrapper(fileobj) + fileobj = _nullcontext(fileobj) with fileobj as file_stream: tzobj = self._read_tzfile(file_stream) @@ -600,10 +606,7 @@ def _read_tzfile(self, fileobj): out.ttinfo_list = [] for i in range(typecnt): gmtoff, isdst, abbrind = ttinfo[i] - # Round to full-minutes if that's not the case. Python's - # datetime doesn't accept sub-minute timezones. Check - # http://python.org/sf/1447945 for some information. - gmtoff = 60 * ((gmtoff + 30) // 60) + gmtoff = _get_supported_offset(gmtoff) tti = _ttinfo() tti.offset = gmtoff tti.dstoffset = datetime.timedelta(0) @@ -655,37 +658,44 @@ def _read_tzfile(self, fileobj): # isgmt are off, so it should be in wall time. OTOH, it's # always in gmt time. Let me know if you have comments # about this. - laststdoffset = None + lastdst = None + lastoffset = None + lastdstoffset = None + lastbaseoffset = None out.trans_list = [] - for i, tti in enumerate(out.trans_idx): - if not tti.isdst: - offset = tti.offset - laststdoffset = offset - else: - if laststdoffset is not None: - # Store the DST offset as well and update it in the list - tti.dstoffset = tti.offset - laststdoffset - out.trans_idx[i] = tti - - offset = laststdoffset or 0 - - out.trans_list.append(out.trans_list_utc[i] + offset) - - # In case we missed any DST offsets on the way in for some reason, make - # a second pass over the list, looking for the /next/ DST offset. - laststdoffset = None - for i in reversed(range(len(out.trans_idx))): - tti = out.trans_idx[i] - if tti.isdst: - if not (tti.dstoffset or laststdoffset is None): - tti.dstoffset = tti.offset - laststdoffset - else: - laststdoffset = tti.offset - - if not isinstance(tti.dstoffset, datetime.timedelta): - tti.dstoffset = datetime.timedelta(seconds=tti.dstoffset) - out.trans_idx[i] = tti + for i, tti in enumerate(out.trans_idx): + offset = tti.offset + dstoffset = 0 + + if lastdst is not None: + if tti.isdst: + if not lastdst: + dstoffset = offset - lastoffset + + if not dstoffset and lastdstoffset: + dstoffset = lastdstoffset + + tti.dstoffset = datetime.timedelta(seconds=dstoffset) + lastdstoffset = dstoffset + + # If a time zone changes its base offset during a DST transition, + # then you need to adjust by the previous base offset to get the + # transition time in local time. Otherwise you use the current + # base offset. Ideally, I would have some mathematical proof of + # why this is true, but I haven't really thought about it enough. + baseoffset = offset - dstoffset + adjustment = baseoffset + if (lastbaseoffset is not None and baseoffset != lastbaseoffset + and tti.isdst != lastdst): + # The base DST has changed + adjustment = lastbaseoffset + + lastdst = tti.isdst + lastoffset = offset + lastbaseoffset = baseoffset + + out.trans_list.append(out.trans_list_utc[i] + adjustment) out.trans_idx = tuple(out.trans_idx) out.trans_list = tuple(out.trans_list) @@ -1255,7 +1265,7 @@ def __init__(self, fileobj): fileobj = open(fileobj, 'r') else: self._s = getattr(fileobj, 'name', repr(fileobj)) - fileobj = _ContextWrapper(fileobj) + fileobj = _nullcontext(fileobj) self._vtz = {} @@ -1528,7 +1538,9 @@ class GettzFunc(object): """ def __init__(self): - self.__instances = {} + self.__instances = weakref.WeakValueDictionary() + self.__strong_cache_size = 8 + self.__strong_cache = OrderedDict() self._cache_lock = _thread.allocate_lock() def __call__(self, name=None): @@ -1537,17 +1549,37 @@ def __call__(self, name=None): if rv is None: rv = self.nocache(name=name) - if not (name is None or isinstance(rv, tzlocal_classes)): + if not (name is None + or isinstance(rv, tzlocal_classes) + or rv is None): # tzlocal is slightly more complicated than the other # time zone providers because it depends on environment # at construction time, so don't cache that. + # + # We also cannot store weak references to None, so we + # will also not store that. self.__instances[name] = rv + else: + # No need for strong caching, return immediately + return rv + + self.__strong_cache[name] = self.__strong_cache.pop(name, rv) + + if len(self.__strong_cache) > self.__strong_cache_size: + self.__strong_cache.popitem(last=False) return rv + def set_cache_size(self, size): + with self._cache_lock: + self.__strong_cache_size = size + while len(self.__strong_cache) > size: + self.__strong_cache.popitem(last=False) + def cache_clear(self): with self._cache_lock: - self.__instances = {} + self.__instances = weakref.WeakValueDictionary() + self.__strong_cache.clear() @staticmethod def nocache(name=None): @@ -1601,7 +1633,8 @@ def nocache(name=None): if tzwin is not None: try: tz = tzwin(name) - except WindowsError: + except (WindowsError, UnicodeEncodeError): + # UnicodeEncodeError is for Python 2.7 compat tz = None if not tz: @@ -1768,18 +1801,36 @@ def _datetime_to_timestamp(dt): return (dt.replace(tzinfo=None) - EPOCH).total_seconds() -class _ContextWrapper(object): - """ - Class for wrapping contexts so that they are passed through in a - with statement. - """ - def __init__(self, context): - self.context = context +if sys.version_info >= (3, 6): + def _get_supported_offset(second_offset): + return second_offset +else: + def _get_supported_offset(second_offset): + # For python pre-3.6, round to full-minutes if that's not the case. + # Python's datetime doesn't accept sub-minute timezones. Check + # http://python.org/sf/1447945 or https://bugs.python.org/issue5288 + # for some information. + old_offset = second_offset + calculated_offset = 60 * ((second_offset + 30) // 60) + return calculated_offset - def __enter__(self): - return self.context - def __exit__(*args, **kwargs): - pass +try: + # Python 3.7 feature + from contextmanager import nullcontext as _nullcontext +except ImportError: + class _nullcontext(object): + """ + Class for wrapping contexts so that they are passed through in a + with statement. + """ + def __init__(self, context): + self.context = context + + def __enter__(self): + return self.context + + def __exit__(*args, **kwargs): + pass # vim:ts=4:sw=4:et diff --git a/ext/dateutil/tz/win.py b/ext/dateutil/tz/win.py index def4353a64..cde07ba792 100644 --- a/ext/dateutil/tz/win.py +++ b/ext/dateutil/tz/win.py @@ -1,3 +1,11 @@ +# -*- coding: utf-8 -*- +""" +This module provides an interface to the native time zone data on Windows, +including :py:class:`datetime.tzinfo` implementations. + +Attempting to import this module on a non-Windows platform will raise an +:py:obj:`ImportError`. +""" # This code was originally contributed by Jeffrey Harris. import datetime import struct @@ -39,7 +47,7 @@ def _settzkeyname(): class tzres(object): """ - Class for accessing `tzres.dll`, which contains timezone name related + Class for accessing ``tzres.dll``, which contains timezone name related resources. .. versionadded:: 2.5.0 @@ -72,9 +80,10 @@ def load_name(self, offset): :param offset: A positive integer value referring to a string from the tzres dll. - ..note: + .. note:: + Offsets found in the registry are generally of the form - `@tzres.dll,-114`. The offset in this case if 114, not -114. + ``@tzres.dll,-114``. The offset in this case is 114, not -114. """ resource = self.p_wchar() @@ -146,6 +155,9 @@ def list(): return result def display(self): + """ + Return the display name of the time zone. + """ return self._display def transitions(self, year): @@ -188,6 +200,17 @@ def _dst_base_offset(self): class tzwin(tzwinbase): + """ + Time zone object created from the zone info in the Windows registry + + These are similar to :py:class:`dateutil.tz.tzrange` objects in that + the time zone data is provided in the format of a single offset rule + for either 0 or 2 time zone transitions per year. + + :param: name + The name of a Windows time zone key, e.g. "Eastern Standard Time". + The full list of keys can be retrieved with :func:`tzwin.list`. + """ def __init__(self, name): self._name = name @@ -234,6 +257,22 @@ def __reduce__(self): class tzwinlocal(tzwinbase): + """ + Class representing the local time zone information in the Windows registry + + While :class:`dateutil.tz.tzlocal` makes system calls (via the :mod:`time` + module) to retrieve time zone information, ``tzwinlocal`` retrieves the + rules directly from the Windows registry and creates an object like + :class:`dateutil.tz.tzwin`. + + Because Windows does not have an equivalent of :func:`time.tzset`, on + Windows, :class:`dateutil.tz.tzlocal` instances will always reflect the + time zone settings *at the time that the process was started*, meaning + changes to the machine's time zone settings during the run of a program + on Windows will **not** be reflected by :class:`dateutil.tz.tzlocal`. + Because ``tzwinlocal`` reads the registry directly, it is unaffected by + this issue. + """ def __init__(self): with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle: with winreg.OpenKey(handle, TZLOCALKEYNAME) as tzlocalkey: diff --git a/ext/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz b/ext/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz index 6e8c05efd4..124f3e14c6 100644 Binary files a/ext/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz and b/ext/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz differ diff --git a/ext/deluge_client/__init__.py b/ext/deluge_client/__init__.py new file mode 100644 index 0000000000..125e0d16a5 --- /dev/null +++ b/ext/deluge_client/__init__.py @@ -0,0 +1 @@ +from .client import DelugeRPCClient, FailedToReconnectException \ No newline at end of file diff --git a/ext/deluge_client/client.py b/ext/deluge_client/client.py new file mode 100644 index 0000000000..17f0a483eb --- /dev/null +++ b/ext/deluge_client/client.py @@ -0,0 +1,265 @@ +import logging +import socket +import ssl +import struct +import warnings +import zlib + +from .rencode import dumps, loads + +RPC_RESPONSE = 1 +RPC_ERROR = 2 +RPC_EVENT = 3 + +MESSAGE_HEADER_SIZE = 5 +READ_SIZE = 10 + +logger = logging.getLogger(__name__) + + +class ConnectionLostException(Exception): + pass + + +class CallTimeoutException(Exception): + pass + + +class InvalidHeaderException(Exception): + pass + + +class FailedToReconnectException(Exception): + pass + + +class RemoteException(Exception): + pass + + +class DelugeRPCClient(object): + timeout = 20 + + def __init__(self, host, port, username, password, decode_utf8=False, automatic_reconnect=True): + self.host = host + self.port = port + self.username = username + self.password = password + self.deluge_version = None + # This is only applicable if deluge_version is 2 + self.deluge_protocol_version = None + + self.decode_utf8 = decode_utf8 + if not self.decode_utf8: + warnings.warn('Using `decode_utf8=False` is deprecated, please set it to True.' + 'The argument will be removed in a future release where it will be always True', DeprecationWarning) + + self.automatic_reconnect = automatic_reconnect + + self.request_id = 1 + self.connected = False + self._create_socket() + + def _create_socket(self, ssl_version=None): + if ssl_version is not None: + self._socket = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM), ssl_version=ssl_version) + else: + self._socket = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) + self._socket.settimeout(self.timeout) + + def connect(self): + """ + Connects to the Deluge instance + """ + self._connect() + logger.debug('Connected to Deluge, detecting daemon version') + self._detect_deluge_version() + logger.debug('Daemon version {} detected, logging in'.format(self.deluge_version)) + if self.deluge_version == 2: + result = self.call('daemon.login', self.username, self.password, client_version='deluge-client') + else: + result = self.call('daemon.login', self.username, self.password) + logger.debug('Logged in with value %r' % result) + self.connected = True + + def _connect(self): + logger.info('Connecting to %s:%s' % (self.host, self.port)) + try: + self._socket.connect((self.host, self.port)) + except ssl.SSLError as e: + # Note: have not verified that we actually get errno 258 for this error + if (hasattr(ssl, 'PROTOCOL_SSLv3') and + (getattr(e, 'reason', None) == 'UNSUPPORTED_PROTOCOL' or e.errno == 258)): + logger.warning('Was unable to ssl handshake, trying to force SSLv3 (insecure)') + self._create_socket(ssl_version=ssl.PROTOCOL_SSLv3) + self._socket.connect((self.host, self.port)) + else: + raise + + def disconnect(self): + """ + Disconnect from deluge + """ + if self.connected: + self._socket.close() + self._socket = None + self.connected = False + + def _detect_deluge_version(self): + if self.deluge_version is not None: + return + + self._send_call(1, None, 'daemon.info') + self._send_call(2, None, 'daemon.info') + self._send_call(2, 1, 'daemon.info') + result = self._socket.recv(1) + if result[:1] == b'D': + # This is a protocol deluge 2.0 was using before release + self.deluge_version = 2 + self.deluge_protocol_version = None + # If we need the specific version of deluge 2, this is it. + daemon_version = self._receive_response(2, None, partial_data=result) + elif ord(result[:1]) == 1: + self.deluge_version = 2 + self.deluge_protocol_version = 1 + # If we need the specific version of deluge 2, this is it. + daemon_version = self._receive_response(2, 1, partial_data=result) + else: + self.deluge_version = 1 + # Deluge 1 doesn't recover well from the bad request. Re-connect the socket. + self._socket.close() + self._create_socket() + self._connect() + + def _send_call(self, deluge_version, protocol_version, method, *args, **kwargs): + self.request_id += 1 + logger.debug('Calling reqid %s method %r with args:%r kwargs:%r' % (self.request_id, method, args, kwargs)) + + req = ((self.request_id, method, args, kwargs), ) + req = zlib.compress(dumps(req)) + + if deluge_version == 2: + if protocol_version is None: + # This was a protocol for deluge 2 before they introduced protocol version numbers + self._socket.send(b'D' + struct.pack("!i", len(req))) + elif protocol_version == 1: + self._socket.send(struct.pack('!BI', protocol_version, len(req))) + else: + raise Exception('Deluge protocol version {} is not (yet) supported.'.format(protocol_version)) + self._socket.send(req) + + def _receive_response(self, deluge_version, protocol_version, partial_data=b''): + expected_bytes = None + data = partial_data + while True: + try: + d = self._socket.recv(READ_SIZE) + except ssl.SSLError: + raise CallTimeoutException() + + data += d + if deluge_version == 2: + if expected_bytes is None: + if len(data) < 5: + continue + + header = data[:MESSAGE_HEADER_SIZE] + data = data[MESSAGE_HEADER_SIZE:] + + if protocol_version is None: + if header[0] != b'D'[0]: + raise InvalidHeaderException('Expected D as first byte in reply') + elif ord(header[:1]) != protocol_version: + raise InvalidHeaderException( + 'Expected protocol version ({}) as first byte in reply'.format(protocol_version) + ) + + if protocol_version is None: + expected_bytes = struct.unpack('!i', header[1:])[0] + else: + expected_bytes = struct.unpack('!I', header[1:])[0] + + if len(data) >= expected_bytes: + data = zlib.decompress(data) + break + else: + try: + data = zlib.decompress(data) + except zlib.error: + if not d: + raise ConnectionLostException() + continue + break + + data = list(loads(data, decode_utf8=self.decode_utf8)) + msg_type = data.pop(0) + request_id = data.pop(0) + + if msg_type == RPC_ERROR: + if self.deluge_version == 2: + exception_type, exception_msg, _, traceback = data + # On deluge 2, exception arguments are sent as tuple + if self.decode_utf8: + exception_msg = ', '.join(exception_msg) + else: + exception_msg = b', '.join(exception_msg) + else: + exception_type, exception_msg, traceback = data[0] + if self.decode_utf8: + exception = type(str(exception_type), (RemoteException, ), {}) + exception_msg = '%s\n%s' % (exception_msg, + traceback) + else: + exception = type(str(exception_type.decode('utf-8', 'ignore')), (RemoteException, ), {}) + exception_msg = '%s\n%s' % (exception_msg.decode('utf-8', 'ignore'), + traceback.decode('utf-8', 'ignore')) + raise exception(exception_msg) + elif msg_type == RPC_RESPONSE: + retval = data[0] + return retval + + def reconnect(self): + """ + Reconnect + """ + self.disconnect() + self._create_socket() + self.connect() + + def call(self, method, *args, **kwargs): + """ + Calls an RPC function + """ + tried_reconnect = False + for _ in range(2): + try: + self._send_call(self.deluge_version, self.deluge_protocol_version, method, *args, **kwargs) + return self._receive_response(self.deluge_version, self.deluge_protocol_version) + except (socket.error, ConnectionLostException, CallTimeoutException): + if self.automatic_reconnect: + if tried_reconnect: + raise FailedToReconnectException() + else: + try: + self.reconnect() + except (socket.error, ConnectionLostException, CallTimeoutException): + raise FailedToReconnectException() + + tried_reconnect = True + else: + raise + + def __getattr__(self, item): + return RPCCaller(self.call, item) + + +class RPCCaller(object): + def __init__(self, caller, method=''): + self.caller = caller + self.method = method + + def __getattr__(self, item): + return RPCCaller(self.caller, self.method+'.'+item) + + def __call__(self, *args, **kwargs): + return self.caller(self.method, *args, **kwargs) diff --git a/lib/synchronousdeluge/rencode.py b/ext/deluge_client/rencode.py similarity index 55% rename from lib/synchronousdeluge/rencode.py rename to ext/deluge_client/rencode.py index e58c715422..d9ac8fb891 100644 --- a/lib/synchronousdeluge/rencode.py +++ b/ext/deluge_client/rencode.py @@ -1,27 +1,3 @@ - -""" -rencode -- Web safe object pickling/unpickling. - -Public domain, Connelly Barnes 2006-2007. - -The rencode module is a modified version of bencode from the -BitTorrent project. For complex, heterogeneous data structures with -many small elements, r-encodings take up significantly less space than -b-encodings: - - >>> len(rencode.dumps({'a':0, 'b':[1,2], 'c':99})) - 13 - >>> len(bencode.bencode({'a':0, 'b':[1,2], 'c':99})) - 26 - -The rencode format is not standardized, and may change with different -rencode module versions, so you should check that you are using the -same rencode version throughout your project. -""" - -__version__ = '1.0.1' -__all__ = ['dumps', 'loads'] - # Original bencode module by Petru Paler, et al. # # Modifications by Connelly Barnes: @@ -62,10 +38,50 @@ # (The rencode module is licensed under the above license as well). # +""" +rencode -- Web safe object pickling/unpickling. + +Public domain, Connelly Barnes 2006-2007. + +The rencode module is a modified version of bencode from the +BitTorrent project. For complex, heterogeneous data structures with +many small elements, r-encodings take up significantly less space than +b-encodings: + + >>> len(rencode.dumps({'a':0, 'b':[1,2], 'c':99})) + 13 + >>> len(bencode.bencode({'a':0, 'b':[1,2], 'c':99})) + 26 + +The rencode format is not standardized, and may change with different +rencode module versions, so you should check that you are using the +same rencode version throughout your project. +""" + import struct -import string +import sys from threading import Lock +try: + from future_builtins import zip +except ImportError: + # Ignore on Py3. + pass + +__version__ = ('Python', 1, 0, 4) +__all__ = ['dumps', 'loads'] + +py3 = sys.version_info[0] >= 3 +if py3: + long = int # pylint: disable=redefined-builtin + unicode = str # pylint: disable=redefined-builtin + + def int2byte(c): + return bytes([c]) +else: + def int2byte(c): + return chr(c) + # Default number of bits for serialized floats, either 32 or 64 (also a parameter for dumps()). DEFAULT_FLOAT_BITS = 32 @@ -74,19 +90,19 @@ # The bencode 'typecodes' such as i, d, etc have been extended and # relocated on the base-256 character set. -CHR_LIST = chr(59) -CHR_DICT = chr(60) -CHR_INT = chr(61) -CHR_INT1 = chr(62) -CHR_INT2 = chr(63) -CHR_INT4 = chr(64) -CHR_INT8 = chr(65) -CHR_FLOAT32 = chr(66) -CHR_FLOAT64 = chr(44) -CHR_TRUE = chr(67) -CHR_FALSE = chr(68) -CHR_NONE = chr(69) -CHR_TERM = chr(127) +CHR_LIST = int2byte(59) +CHR_DICT = int2byte(60) +CHR_INT = int2byte(61) +CHR_INT1 = int2byte(62) +CHR_INT2 = int2byte(63) +CHR_INT4 = int2byte(64) +CHR_INT8 = int2byte(65) +CHR_FLOAT32 = int2byte(66) +CHR_FLOAT64 = int2byte(44) +CHR_TRUE = int2byte(67) +CHR_FALSE = int2byte(68) +CHR_NONE = int2byte(69) +CHR_TERM = int2byte(127) # Positive integers with value embedded in typecode. INT_POS_FIXED_START = 0 @@ -105,9 +121,13 @@ STR_FIXED_COUNT = 64 # Lists with length embedded in typecode. -LIST_FIXED_START = STR_FIXED_START+STR_FIXED_COUNT +LIST_FIXED_START = STR_FIXED_START + STR_FIXED_COUNT LIST_FIXED_COUNT = 64 +# Whether strings should be decoded when loading +_decode_utf8 = False + + def decode_int(x, f): f += 1 newf = x.index(CHR_TERM, f) @@ -117,185 +137,193 @@ def decode_int(x, f): n = int(x[f:newf]) except (OverflowError, ValueError): n = long(x[f:newf]) - if x[f] == '-': - if x[f + 1] == '0': + if x[f:f + 1] == '-': + if x[f + 1:f + 2] == '0': raise ValueError - elif x[f] == '0' and newf != f+1: + elif x[f:f + 1] == '0' and newf != f + 1: raise ValueError - return (n, newf+1) + return (n, newf + 1) + def decode_intb(x, f): f += 1 - return (struct.unpack('!b', x[f:f+1])[0], f+1) + return (struct.unpack('!b', x[f:f + 1])[0], f + 1) + def decode_inth(x, f): f += 1 - return (struct.unpack('!h', x[f:f+2])[0], f+2) + return (struct.unpack('!h', x[f:f + 2])[0], f + 2) + def decode_intl(x, f): f += 1 - return (struct.unpack('!l', x[f:f+4])[0], f+4) + + return (struct.unpack('!l', x[f:f + 4])[0], f + 4) + def decode_intq(x, f): f += 1 - return (struct.unpack('!q', x[f:f+8])[0], f+8) + return (struct.unpack('!q', x[f:f + 8])[0], f + 8) + def decode_float32(x, f): f += 1 - n = struct.unpack('!f', x[f:f+4])[0] - return (n, f+4) + n = struct.unpack('!f', x[f:f + 4])[0] + return (n, f + 4) + def decode_float64(x, f): f += 1 - n = struct.unpack('!d', x[f:f+8])[0] - return (n, f+8) + n = struct.unpack('!d', x[f:f + 8])[0] + return (n, f + 8) + def decode_string(x, f): - colon = x.index(':', f) + colon = x.index(b':', f) try: n = int(x[f:colon]) except (OverflowError, ValueError): n = long(x[f:colon]) - if x[f] == '0' and colon != f+1: + if x[f] == '0' and colon != f + 1: raise ValueError colon += 1 - s = x[colon:colon+n] - try: - t = s.decode("utf8") - if len(t) != len(s): - s = t - except UnicodeDecodeError: - pass - return (s, colon+n) + s = x[colon:colon + n] + if _decode_utf8: + s = s.decode('utf8') + return (s, colon + n) + def decode_list(x, f): - r, f = [], f+1 - while x[f] != CHR_TERM: - v, f = decode_func[x[f]](x, f) + r, f = [], f + 1 + while x[f:f + 1] != CHR_TERM: + v, f = decode_func[x[f:f + 1]](x, f) r.append(v) return (tuple(r), f + 1) + def decode_dict(x, f): - r, f = {}, f+1 - while x[f] != CHR_TERM: - k, f = decode_func[x[f]](x, f) - r[k], f = decode_func[x[f]](x, f) + r, f = {}, f + 1 + while x[f:f + 1] != CHR_TERM: + k, f = decode_func[x[f:f + 1]](x, f) + r[k], f = decode_func[x[f:f + 1]](x, f) return (r, f + 1) + def decode_true(x, f): - return (True, f+1) + return (True, f + 1) + def decode_false(x, f): - return (False, f+1) + return (False, f + 1) + def decode_none(x, f): - return (None, f+1) + return (None, f + 1) + decode_func = {} -decode_func['0'] = decode_string -decode_func['1'] = decode_string -decode_func['2'] = decode_string -decode_func['3'] = decode_string -decode_func['4'] = decode_string -decode_func['5'] = decode_string -decode_func['6'] = decode_string -decode_func['7'] = decode_string -decode_func['8'] = decode_string -decode_func['9'] = decode_string -decode_func[CHR_LIST ] = decode_list -decode_func[CHR_DICT ] = decode_dict -decode_func[CHR_INT ] = decode_int -decode_func[CHR_INT1 ] = decode_intb -decode_func[CHR_INT2 ] = decode_inth -decode_func[CHR_INT4 ] = decode_intl -decode_func[CHR_INT8 ] = decode_intq +decode_func[b'0'] = decode_string +decode_func[b'1'] = decode_string +decode_func[b'2'] = decode_string +decode_func[b'3'] = decode_string +decode_func[b'4'] = decode_string +decode_func[b'5'] = decode_string +decode_func[b'6'] = decode_string +decode_func[b'7'] = decode_string +decode_func[b'8'] = decode_string +decode_func[b'9'] = decode_string +decode_func[CHR_LIST] = decode_list +decode_func[CHR_DICT] = decode_dict +decode_func[CHR_INT] = decode_int +decode_func[CHR_INT1] = decode_intb +decode_func[CHR_INT2] = decode_inth +decode_func[CHR_INT4] = decode_intl +decode_func[CHR_INT8] = decode_intq decode_func[CHR_FLOAT32] = decode_float32 decode_func[CHR_FLOAT64] = decode_float64 -decode_func[CHR_TRUE ] = decode_true -decode_func[CHR_FALSE ] = decode_false -decode_func[CHR_NONE ] = decode_none +decode_func[CHR_TRUE] = decode_true +decode_func[CHR_FALSE] = decode_false +decode_func[CHR_NONE] = decode_none + def make_fixed_length_string_decoders(): def make_decoder(slen): def f(x, f): - s = x[f+1:f+1+slen] - try: - t = s.decode("utf8") - if len(t) != len(s): - s = t - except UnicodeDecodeError: - pass - return (s, f+1+slen) + s = x[f + 1:f + 1 + slen] + if _decode_utf8: + s = s.decode('utf8') + return (s, f + 1 + slen) return f for i in range(STR_FIXED_COUNT): - decode_func[chr(STR_FIXED_START+i)] = make_decoder(i) + decode_func[int2byte(STR_FIXED_START + i)] = make_decoder(i) + make_fixed_length_string_decoders() + def make_fixed_length_list_decoders(): def make_decoder(slen): def f(x, f): - r, f = [], f+1 - for i in range(slen): - v, f = decode_func[x[f]](x, f) + r, f = [], f + 1 + for _ in range(slen): + v, f = decode_func[x[f:f + 1]](x, f) r.append(v) return (tuple(r), f) return f for i in range(LIST_FIXED_COUNT): - decode_func[chr(LIST_FIXED_START+i)] = make_decoder(i) + decode_func[int2byte(LIST_FIXED_START + i)] = make_decoder(i) + make_fixed_length_list_decoders() + def make_fixed_length_int_decoders(): def make_decoder(j): def f(x, f): - return (j, f+1) + return (j, f + 1) return f for i in range(INT_POS_FIXED_COUNT): - decode_func[chr(INT_POS_FIXED_START+i)] = make_decoder(i) + decode_func[int2byte(INT_POS_FIXED_START + i)] = make_decoder(i) for i in range(INT_NEG_FIXED_COUNT): - decode_func[chr(INT_NEG_FIXED_START+i)] = make_decoder(-1-i) + decode_func[int2byte(INT_NEG_FIXED_START + i)] = make_decoder(-1 - i) + make_fixed_length_int_decoders() + def make_fixed_length_dict_decoders(): def make_decoder(slen): def f(x, f): - r, f = {}, f+1 - for j in range(slen): - k, f = decode_func[x[f]](x, f) - r[k], f = decode_func[x[f]](x, f) + r, f = {}, f + 1 + for _ in range(slen): + k, f = decode_func[x[f:f + 1]](x, f) + r[k], f = decode_func[x[f:f + 1]](x, f) return (r, f) return f for i in range(DICT_FIXED_COUNT): - decode_func[chr(DICT_FIXED_START+i)] = make_decoder(i) + decode_func[int2byte(DICT_FIXED_START + i)] = make_decoder(i) -make_fixed_length_dict_decoders() -def encode_dict(x,r): - r.append(CHR_DICT) - for k, v in x.items(): - encode_func[type(k)](k, r) - encode_func[type(v)](v, r) - r.append(CHR_TERM) +make_fixed_length_dict_decoders() -def loads(x): +def loads(x, decode_utf8=False): + global _decode_utf8 + _decode_utf8 = decode_utf8 try: - r, l = decode_func[x[0]](x, 0) + r, l = decode_func[x[0:1]](x, 0) except (IndexError, KeyError): raise ValueError if l != len(x): raise ValueError return r -from types import StringType, IntType, LongType, DictType, ListType, TupleType, FloatType, NoneType, UnicodeType def encode_int(x, r): if 0 <= x < INT_POS_FIXED_COUNT: - r.append(chr(INT_POS_FIXED_START+x)) + r.append(int2byte(INT_POS_FIXED_START + x)) elif -INT_NEG_FIXED_COUNT <= x < 0: - r.append(chr(INT_NEG_FIXED_START-1-x)) + r.append(int2byte(INT_NEG_FIXED_START - 1 - x)) elif -128 <= x < 128: r.extend((CHR_INT1, struct.pack('!b', x))) elif -32768 <= x < 32768: @@ -306,34 +334,47 @@ def encode_int(x, r): r.extend((CHR_INT8, struct.pack('!q', x))) else: s = str(x) + if py3: + s = bytes(s, 'ascii') + if len(s) >= MAX_INT_LENGTH: raise ValueError('overflow') r.extend((CHR_INT, s, CHR_TERM)) + def encode_float32(x, r): r.extend((CHR_FLOAT32, struct.pack('!f', x))) + def encode_float64(x, r): r.extend((CHR_FLOAT64, struct.pack('!d', x))) + def encode_bool(x, r): - r.extend({False: CHR_FALSE, True: CHR_TRUE}[bool(x)]) + r.append({False: CHR_FALSE, True: CHR_TRUE}[bool(x)]) + def encode_none(x, r): - r.extend(CHR_NONE) + r.append(CHR_NONE) + def encode_string(x, r): if len(x) < STR_FIXED_COUNT: - r.extend((chr(STR_FIXED_START + len(x)), x)) + r.extend((int2byte(STR_FIXED_START + len(x)), x)) else: - r.extend((str(len(x)), ':', x)) + s = str(len(x)) + if py3: + s = bytes(s, 'ascii') + r.extend((s, b':', x)) + def encode_unicode(x, r): - encode_string(x.encode("utf8"), r) + encode_string(x.encode('utf8'), r) + def encode_list(x, r): if len(x) < LIST_FIXED_COUNT: - r.append(chr(LIST_FIXED_START + len(x))) + r.append(int2byte(LIST_FIXED_START + len(x))) for i in x: encode_func[type(i)](i, r) else: @@ -342,9 +383,10 @@ def encode_list(x, r): encode_func[type(i)](i, r) r.append(CHR_TERM) -def encode_dict(x,r): + +def encode_dict(x, r): if len(x) < DICT_FIXED_COUNT: - r.append(chr(DICT_FIXED_START + len(x))) + r.append(int2byte(DICT_FIXED_START + len(x))) for k, v in x.items(): encode_func[type(k)](k, r) encode_func[type(v)](v, r) @@ -355,23 +397,20 @@ def encode_dict(x,r): encode_func[type(v)](v, r) r.append(CHR_TERM) + encode_func = {} -encode_func[IntType] = encode_int -encode_func[LongType] = encode_int -encode_func[StringType] = encode_string -encode_func[ListType] = encode_list -encode_func[TupleType] = encode_list -encode_func[DictType] = encode_dict -encode_func[NoneType] = encode_none -encode_func[UnicodeType] = encode_unicode +encode_func[int] = encode_int +encode_func[long] = encode_int +encode_func[bytes] = encode_string +encode_func[list] = encode_list +encode_func[tuple] = encode_list +encode_func[dict] = encode_dict +encode_func[type(None)] = encode_none +encode_func[unicode] = encode_unicode +encode_func[bool] = encode_bool lock = Lock() -try: - from types import BooleanType - encode_func[BooleanType] = encode_bool -except ImportError: - pass def dumps(x, float_bits=DEFAULT_FLOAT_BITS): """ @@ -379,48 +418,50 @@ def dumps(x, float_bits=DEFAULT_FLOAT_BITS): Here float_bits is either 32 or 64. """ - lock.acquire() - try: + with lock: if float_bits == 32: - encode_func[FloatType] = encode_float32 + encode_func[float] = encode_float32 elif float_bits == 64: - encode_func[FloatType] = encode_float64 + encode_func[float] = encode_float64 else: raise ValueError('Float bits (%d) is not 32 or 64' % float_bits) r = [] encode_func[type(x)](x, r) - finally: - lock.release() - return ''.join(r) + return b''.join(r) + def test(): f1 = struct.unpack('!f', struct.pack('!f', 25.5))[0] f2 = struct.unpack('!f', struct.pack('!f', 29.3))[0] f3 = struct.unpack('!f', struct.pack('!f', -0.6))[0] - L = (({'a':15, 'bb':f1, 'ccc':f2, '':(f3,(),False,True,'')},('a',10**20),tuple(range(-100000,100000)),'b'*31,'b'*62,'b'*64,2**30,2**33,2**62,2**64,2**30,2**33,2**62,2**64,False,False, True, -1, 2, 0),) - assert loads(dumps(L)) == L - d = dict(zip(range(-100000,100000),range(-100000,100000))) - d.update({'a':20, 20:40, 40:41, f1:f2, f2:f3, f3:False, False:True, True:False}) - L = (d, {}, {5:6}, {7:7,True:8}, {9:10, 22:39, 49:50, 44: ''}) - assert loads(dumps(L)) == L - L = ('', 'a'*10, 'a'*100, 'a'*1000, 'a'*10000, 'a'*100000, 'a'*1000000, 'a'*10000000) - assert loads(dumps(L)) == L - L = tuple([dict(zip(range(n),range(n))) for n in range(100)]) + ('b',) - assert loads(dumps(L)) == L - L = tuple([dict(zip(range(n),range(-n,0))) for n in range(100)]) + ('b',) - assert loads(dumps(L)) == L - L = tuple([tuple(range(n)) for n in range(100)]) + ('b',) - assert loads(dumps(L)) == L - L = tuple(['a'*n for n in range(1000)]) + ('b',) - assert loads(dumps(L)) == L - L = tuple(['a'*n for n in range(1000)]) + (None,True,None) - assert loads(dumps(L)) == L - assert loads(dumps(None)) == None - assert loads(dumps({None:None})) == {None:None} - assert 1e-10 (3,): + long = int + + +@pytest.fixture +def client(request): + if sys.platform.startswith('win'): + auth_path = os.path.join(os.getenv('APPDATA'), 'deluge', 'auth') + else: + auth_path = os.path.expanduser("~/.config/deluge/auth") + + with open(auth_path, 'rb') as f: + filedata = f.read().decode("utf-8").split('\n')[0].split(':') + + username, password = filedata[:2] + ip = '127.0.0.1' + port = 58846 + kwargs = {'decode_utf8': True} + if hasattr(request, 'param'): + kwargs.update(request.param) + client = DelugeRPCClient(ip, port, username, password, **kwargs) + client.connect() + + yield client + + try: + client.disconnect() + except: + pass + + +def test_connect(client): + assert client.connected + + +def test_call_method(client): + assert isinstance(client.call('core.get_free_space'), (int, long)) + + +def test_call_method_arguments(client): + assert isinstance(client.call('core.get_free_space', '/'), (int, long)) + + +@pytest.mark.parametrize('client', + [{'decode_utf8': True}, {'decode_utf8': False}], + ids=['decode_utf8_on', 'decode_utf8_off'], + indirect=True) +def test_call_method_exception(client): + with pytest.raises(RemoteException) as ex_info: + client.call('core.get_free_space', '1', '2') + assert ('takes at most 2 arguments' in str(ex_info.value) or + 'takes from 1 to 2 positional arguments' in str(ex_info.value)) # deluge 2.0 + + +def test_attr_caller(client): + assert isinstance(client.core.get_free_space(), (int, long)) + assert isinstance(client.core.get_free_space('/'), (int, long)) diff --git a/ext/dogpile/__init__.py b/ext/dogpile/__init__.py index dd4472abd7..fc8fd45240 100644 --- a/ext/dogpile/__init__.py +++ b/ext/dogpile/__init__.py @@ -1,4 +1,4 @@ -__version__ = '0.6.7' +__version__ = '0.7.1' from .lock import Lock # noqa from .lock import NeedRegenerationException # noqa diff --git a/ext/dogpile/cache/region.py b/ext/dogpile/cache/region.py index a16a2a1518..261a8db482 100644 --- a/ext/dogpile/cache/region.py +++ b/ext/dogpile/cache/region.py @@ -10,8 +10,9 @@ import time import datetime from numbers import Number -from functools import wraps +from functools import wraps, partial import threading +from decorator import decorate _backend_loader = PluginLoader("dogpile.cache") register_backend = _backend_loader.register @@ -188,7 +189,7 @@ def is_soft_invalidated(self, timestamp): class CacheRegion(object): - """A front end to a particular cache backend. + r"""A front end to a particular cache backend. :param name: Optional, a string name for the region. This isn't used internally @@ -743,7 +744,8 @@ def get_multi(self, keys, expiration_time=None, ignore_expiration=False): ] def get_or_create( - self, key, creator, expiration_time=None, should_cache_fn=None): + self, key, creator, expiration_time=None, should_cache_fn=None, + creator_args=None): """Return a cached value based on the given key. If the value does not exist or is considered to be expired @@ -779,6 +781,11 @@ def get_or_create( :param creator: function which creates a new value. + :param creator_args: optional tuple of (args, kwargs) that will be + passed to the creator function if present. + + .. versionadded:: 0.7.0 + :param expiration_time: optional expiration time which will overide the expiration time already configured on this :class:`.CacheRegion` if not None. To set no expiration, use the value -1. @@ -828,7 +835,10 @@ def get_value(): return value.payload, ct def gen_value(): - created_value = creator() + if creator_args: + created_value = creator(*creator_args[0], **creator_args[1]) + else: + created_value = creator() value = self._value(created_value) if not should_cache_fn or \ @@ -851,8 +861,13 @@ def gen_value(): if self.async_creation_runner: def async_creator(mutex): - return self.async_creation_runner( - self, orig_key, creator, mutex) + if creator_args: + @wraps(creator) + def go(): + return creator(*creator_args[0], **creator_args[1]) + else: + go = creator + return self.async_creation_runner(self, orig_key, go, mutex) else: async_creator = None @@ -1248,26 +1263,31 @@ def somemethod(self, x, y): if function_key_generator is None: function_key_generator = self.function_key_generator - def decorator(fn): + def get_or_create_for_user_func(key_generator, user_func, *arg, **kw): + key = key_generator(*arg, **kw) + + timeout = expiration_time() if expiration_time_is_callable \ + else expiration_time + return self.get_or_create(key, user_func, timeout, + should_cache_fn, (arg, kw)) + + def cache_decorator(user_func): if to_str is compat.string_type: # backwards compatible - key_generator = function_key_generator(namespace, fn) + key_generator = function_key_generator(namespace, user_func) else: key_generator = function_key_generator( - namespace, fn, + namespace, user_func, to_str=to_str) - @wraps(fn) - def decorate(*arg, **kw): + def refresh(*arg, **kw): + """ + Like invalidate, but regenerates the value instead + """ key = key_generator(*arg, **kw) - - @wraps(fn) - def creator(): - return fn(*arg, **kw) - timeout = expiration_time() if expiration_time_is_callable \ - else expiration_time - return self.get_or_create(key, creator, timeout, - should_cache_fn) + value = user_func(*arg, **kw) + self.set(key, value) + return value def invalidate(*arg, **kw): key = key_generator(*arg, **kw) @@ -1281,20 +1301,18 @@ def get(*arg, **kw): key = key_generator(*arg, **kw) return self.get(key) - def refresh(*arg, **kw): - key = key_generator(*arg, **kw) - value = fn(*arg, **kw) - self.set(key, value) - return value + user_func.set = set_ + user_func.invalidate = invalidate + user_func.get = get + user_func.refresh = refresh + user_func.original = user_func + + # Use `decorate` to preserve the signature of :param:`user_func`. - decorate.set = set_ - decorate.invalidate = invalidate - decorate.refresh = refresh - decorate.get = get - decorate.original = fn + return decorate(user_func, partial( + get_or_create_for_user_func, key_generator)) - return decorate - return decorator + return cache_decorator def cache_multi_on_arguments( self, namespace=None, expiration_time=None, @@ -1422,50 +1440,49 @@ def generate_something(*keys): if function_multi_key_generator is None: function_multi_key_generator = self.function_multi_key_generator - def decorator(fn): - key_generator = function_multi_key_generator( - namespace, fn, - to_str=to_str) - - @wraps(fn) - def decorate(*arg, **kw): - cache_keys = arg - keys = key_generator(*arg, **kw) - key_lookup = dict(zip(keys, cache_keys)) - - @wraps(fn) - def creator(*keys_to_create): - return fn(*[key_lookup[k] for k in keys_to_create]) - - timeout = expiration_time() if expiration_time_is_callable \ - else expiration_time + def get_or_create_for_user_func(key_generator, user_func, *arg, **kw): + cache_keys = arg + keys = key_generator(*arg, **kw) + key_lookup = dict(zip(keys, cache_keys)) + + @wraps(user_func) + def creator(*keys_to_create): + return user_func(*[key_lookup[k] for k in keys_to_create]) + + timeout = expiration_time() if expiration_time_is_callable \ + else expiration_time + + if asdict: + def dict_create(*keys): + d_values = creator(*keys) + return [ + d_values.get(key_lookup[k], NO_VALUE) + for k in keys] + + def wrap_cache_fn(value): + if value is NO_VALUE: + return False + elif not should_cache_fn: + return True + else: + return should_cache_fn(value) + + result = self.get_or_create_multi( + keys, dict_create, timeout, wrap_cache_fn) + result = dict( + (k, v) for k, v in zip(cache_keys, result) + if v is not NO_VALUE) + else: + result = self.get_or_create_multi( + keys, creator, timeout, + should_cache_fn) - if asdict: - def dict_create(*keys): - d_values = creator(*keys) - return [ - d_values.get(key_lookup[k], NO_VALUE) - for k in keys] - - def wrap_cache_fn(value): - if value is NO_VALUE: - return False - elif not should_cache_fn: - return True - else: - return should_cache_fn(value) - - result = self.get_or_create_multi( - keys, dict_create, timeout, wrap_cache_fn) - result = dict( - (k, v) for k, v in zip(cache_keys, result) - if v is not NO_VALUE) - else: - result = self.get_or_create_multi( - keys, creator, timeout, - should_cache_fn) + return result - return result + def cache_decorator(user_func): + key_generator = function_multi_key_generator( + namespace, user_func, + to_str=to_str) def invalidate(*arg): keys = key_generator(*arg) @@ -1486,7 +1503,7 @@ def get(*arg): def refresh(*arg): keys = key_generator(*arg) - values = fn(*arg) + values = user_func(*arg) if asdict: self.set_multi( dict(zip(keys, [values[a] for a in arg])) @@ -1498,13 +1515,18 @@ def refresh(*arg): ) return values - decorate.set = set_ - decorate.invalidate = invalidate - decorate.refresh = refresh - decorate.get = get + user_func.set = set_ + user_func.invalidate = invalidate + user_func.refresh = refresh + user_func.get = get + + # Use `decorate` to preserve the signature of :param:`user_func`. + + return decorate(user_func, partial(get_or_create_for_user_func, key_generator)) + + return cache_decorator + - return decorate - return decorator def make_region(*arg, **kw): diff --git a/ext/dogpile/cache/util.py b/ext/dogpile/cache/util.py index 4b56f64298..16bcd1c975 100644 --- a/ext/dogpile/cache/util.py +++ b/ext/dogpile/cache/util.py @@ -1,5 +1,4 @@ from hashlib import sha1 -import inspect from ..util import compat from ..util import langhelpers @@ -28,7 +27,7 @@ def function_key_generator(namespace, fn, to_str=compat.string_type): else: namespace = '%s:%s|%s' % (fn.__module__, fn.__name__, namespace) - args = inspect.getargspec(fn) + args = compat.inspect_getargspec(fn) has_self = args[0] and args[0][0] in ('self', 'cls') def generate_key(*args, **kw): @@ -50,7 +49,7 @@ def function_multi_key_generator(namespace, fn, to_str=compat.string_type): else: namespace = '%s:%s|%s' % (fn.__module__, fn.__name__, namespace) - args = inspect.getargspec(fn) + args = compat.inspect_getargspec(fn) has_self = args[0] and args[0][0] in ('self', 'cls') def generate_keys(*args, **kw): @@ -88,7 +87,7 @@ def kwarg_function_key_generator(namespace, fn, to_str=compat.string_type): else: namespace = '%s:%s|%s' % (fn.__module__, fn.__name__, namespace) - argspec = inspect.getargspec(fn) + argspec = compat.inspect_getargspec(fn) default_list = list(argspec.defaults or []) # Reverse the list, as we want to compare the argspec by negative index, # meaning default_list[0] should be args[-1], which works well with diff --git a/ext/dogpile/util/compat.py b/ext/dogpile/util/compat.py index d29bb1dacf..198c762763 100644 --- a/ext/dogpile/util/compat.py +++ b/ext/dogpile/util/compat.py @@ -51,11 +51,33 @@ def ue(s): import thread # noqa +if py3k: + import collections + ArgSpec = collections.namedtuple( + "ArgSpec", + ["args", "varargs", "keywords", "defaults"]) + + from inspect import getfullargspec as inspect_getfullargspec + + def inspect_getargspec(func): + return ArgSpec( + *inspect_getfullargspec(func)[0:4] + ) +else: + from inspect import getargspec as inspect_getargspec # noqa + if py3k or jython: import pickle else: import cPickle as pickle # noqa +if py3k: + def read_config_file(config, fileobj): + return config.read_file(fileobj) +else: + def read_config_file(config, fileobj): + return config.readfp(fileobj) + def timedelta_total_seconds(td): if py27: diff --git a/ext/dogpile/util/nameregistry.py b/ext/dogpile/util/nameregistry.py index a5102b2387..7087f7cd63 100644 --- a/ext/dogpile/util/nameregistry.py +++ b/ext/dogpile/util/nameregistry.py @@ -50,7 +50,7 @@ def __init__(self, creator): self.creator = creator def get(self, identifier, *args, **kw): - """Get and possibly create the value. + r"""Get and possibly create the value. :param identifier: Hash key for the value. If the creation function is called, this identifier @@ -75,10 +75,12 @@ def _sync_get(self, identifier, *args, **kw): if identifier in self._values: return self._values[identifier] else: - self._values[identifier] = value = self.creator(identifier, *args, **kw) + self._values[identifier] = value = self.creator( + identifier, *args, **kw) return value except KeyError: - self._values[identifier] = value = self.creator(identifier, *args, **kw) + self._values[identifier] = value = self.creator( + identifier, *args, **kw) return value finally: self._mutex.release() diff --git a/ext/guessit/__main__.py b/ext/guessit/__main__.py index 9894180aae..fad196d6bb 100644 --- a/ext/guessit/__main__.py +++ b/ext/guessit/__main__.py @@ -142,7 +142,7 @@ def main(args=None): # pylint:disable=too-many-branches if options.get('yaml'): try: - import yaml # pylint:disable=unused-variable + import yaml # pylint:disable=unused-variable,unused-import except ImportError: # pragma: no cover del options['yaml'] print('PyYAML is not installed. \'--yaml\' option will be ignored ...', file=sys.stderr) diff --git a/ext/guessit/__version__.py b/ext/guessit/__version__.py index f5913166e8..88d8b8a6ae 100644 --- a/ext/guessit/__version__.py +++ b/ext/guessit/__version__.py @@ -4,4 +4,4 @@ Version module """ # pragma: no cover -__version__ = '3.0.3' +__version__ = '3.0.4.dev0' diff --git a/ext/guessit/api.py b/ext/guessit/api.py index 3bf5aae27d..8e306340b4 100644 --- a/ext/guessit/api.py +++ b/ext/guessit/api.py @@ -82,6 +82,19 @@ def properties(options=None): return default_api.properties(options) +def suggested_expected(titles, options=None): + """ + Return a list of suggested titles to be used as `expected_title` based on the list of titles + :param titles: the filename or release name + :type titles: list|set|dict + :param options: + :type options: str|dict + :return: + :rtype: list of str + """ + return default_api.suggested_expected(titles, options) + + class GuessItApi(object): """ An api class that can be configured with custom Rebulk configuration. @@ -228,5 +241,23 @@ def properties(self, options=None): ordered = self.rebulk.customize_properties(ordered) return ordered + def suggested_expected(self, titles, options=None): + """ + Return a list of suggested titles to be used as `expected_title` based on the list of titles + :param titles: the filename or release name + :type titles: list|set|dict + :param options: + :type options: str|dict + :return: + :rtype: list of str + """ + suggested = [] + for title in titles: + guess = self.guessit(title, options) + if len(guess) != 2 or 'title' not in guess: + suggested.append(title) + + return suggested + default_api = GuessItApi() diff --git a/ext/guessit/config/options.json b/ext/guessit/config/options.json index 11b17271dc..9c60d596bc 100644 --- a/ext/guessit/config/options.json +++ b/ext/guessit/config/options.json @@ -1,6 +1,7 @@ { "expected_title": [ - "OSS 117" + "OSS 117", + "This is Us" ], "allowed_countries": [ "au", @@ -21,6 +22,7 @@ "ja", "ko", "nl", + "no", "pl", "pt", "ro", @@ -33,13 +35,46 @@ ], "advanced_config": { "common_words": [ + "ca", + "cat", "de", - "it" + "he", + "it", + "no", + "por", + "rum", + "se", + "st", + "sub" ], "groups": { "starting": "([{", "ending": ")]}" }, + "audio_codec": { + "audio_channels": { + "1.0": [ + "1ch", + "mono" + ], + "2.0": [ + "2ch", + "stereo", + "re:(2[\\W_]0(?:ch)?)(?=[^\\d]|$)" + ], + "5.1": [ + "5ch", + "6ch", + "re:(5[\\W_][01](?:ch)?)(?=[^\\d]|$)", + "re:(6[\\W_]0(?:ch)?)(?=[^\\d]|$)" + ], + "7.1": [ + "7ch", + "8ch", + "re:(7[\\W_][01](?:ch)?)(?=[^\\d]|$)" + ] + } + }, "container": { "subtitles": [ "srt", @@ -329,6 +364,7 @@ "progressive": [ "360", "480", + "540", "576", "900", "1080", @@ -357,6 +393,180 @@ "prefixes": [ "from" ] + }, + "streaming_service": { + "A&E": [ + "AE", + "A&E" + ], + "ABC": "AMBC", + "ABC Australia": "AUBC", + "Al Jazeera English": "AJAZ", + "AMC": "AMC", + "Amazon Prime": [ + "AMZN", + "Amazon", + "re:Amazon-?Prime" + ], + "Adult Swim": [ + "AS", + "re:Adult-?Swim" + ], + "America's Test Kitchen": "ATK", + "Animal Planet": "ANPL", + "AnimeLab": "ANLB", + "AOL": "AOL", + "ARD": "ARD", + "BBC iPlayer": [ + "iP", + "re:BBC-?iPlayer" + ], + "BravoTV": "BRAV", + "Canal+": "CNLP", + "Cartoon Network": "CN", + "CBC": "CBC", + "CBS": "CBS", + "CNBC": "CNBC", + "Comedy Central": [ + "CC", + "re:Comedy-?Central" + ], + "Channel 4": "4OD", + "CHRGD": "CHGD", + "Cinemax": "CMAX", + "Country Music Television": "CMT", + "Comedians in Cars Getting Coffee": "CCGC", + "Crunchy Roll": [ + "CR", + "re:Crunchy-?Roll" + ], + "Crackle": "CRKL", + "CSpan": "CSPN", + "CTV": "CTV", + "CuriosityStream": "CUR", + "CWSeed": "CWS", + "Daisuki": "DSKI", + "DC Universe": "DCU", + "Deadhouse Films": "DHF", + "Digiturk Diledigin Yerde": "DDY", + "Discovery": [ + "DISC", + "Discovery" + ], + "Disney": [ + "DSNY", + "Disney" + ], + "DIY Network": "DIY", + "Doc Club": "DOCC", + "DPlay": "DPLY", + "E!": "ETV", + "ePix": "EPIX", + "El Trece": "ETTV", + "ESPN": "ESPN", + "Esquire": "ESQ", + "Family": "FAM", + "Family Jr": "FJR", + "Food Network": "FOOD", + "Fox": "FOX", + "Freeform": "FREE", + "FYI Network": "FYI", + "Global": "GLBL", + "GloboSat Play": "GLOB", + "Hallmark": "HLMK", + "HBO Go": [ + "HBO", + "re:HBO-?Go" + ], + "HGTV": "HGTV", + "History": [ + "HIST", + "History" + ], + "Hulu": "HULU", + "Investigation Discovery": "ID", + "IFC": "IFC", + "iTunes": "iTunes", + "ITV": "ITV", + "Knowledge Network": "KNOW", + "Lifetime": "LIFE", + "Motor Trend OnDemand": "MTOD", + "MSNBC": "MNBC", + "MTV": "MTV", + "National Geographic": [ + "NATG", + "re:National-?Geographic" + ], + "NBA TV": [ + "NBA", + "re:NBA-?TV" + ], + "NBC": "NBC", + "Netflix": [ + "NF", + "Netflix" + ], + "NFL": "NFL", + "NFL Now": "NFLN", + "NHL GameCenter": "GC", + "Nickelodeon": [ + "NICK", + "Nickelodeon" + ], + "Norsk Rikskringkasting": "NRK", + "PBS": "PBS", + "PBS Kids": "PBSK", + "Playstation Network": "PSN", + "Pluzz": "PLUZ", + "RTE One": "RTE", + "SBS (AU)": "SBS", + "SeeSo": [ + "SESO", + "SeeSo" + ], + "Shomi": "SHMI", + "Spike": "SPIK", + "Spike TV": [ + "SPKE", + "re:Spike-?TV" + ], + "Sportsnet": "SNET", + "Sprout": "SPRT", + "Stan": "STAN", + "Starz": "STZ", + "Sveriges Television": "SVT", + "SwearNet": "SWER", + "Syfy": "SYFY", + "TBS": "TBS", + "TFou": "TFOU", + "The CW": [ + "CW", + "re:The-?CW" + ], + "TLC": "TLC", + "TubiTV": "TUBI", + "TV3 Ireland": "TV3", + "TV4 Sweeden": "TV4", + "TV Land": [ + "TVL", + "re:TV-?Land" + ], + "UFC": "UFC", + "UKTV": "UKTV", + "Univision": "UNIV", + "USA Network": "USAN", + "Velocity": "VLCT", + "VH1": "VH1", + "Viceland": "VICE", + "Vimeo": "VMEO", + "VRV": "VRV", + "W Network": "WNET", + "WatchMe": "WME", + "WWE Network": "WWEN", + "Xbox Video": "XBOX", + "Yahoo": "YHOO", + "YouTube Red": "RED", + "ZDF": "ZDF" } } } \ No newline at end of file diff --git a/ext/guessit/options.py b/ext/guessit/options.py index 50ee423513..14e4d069b4 100644 --- a/ext/guessit/options.py +++ b/ext/guessit/options.py @@ -128,7 +128,7 @@ class ConfigurationException(Exception): """ Exception related to configuration file. """ - pass + pass # pylint:disable=unnecessary-pass def load_config(options): @@ -153,7 +153,7 @@ def load_config(options): cwd = os.getcwd() yaml_supported = False try: - import yaml # pylint: disable=unused-variable + import yaml # pylint:disable=unused-variable,unused-import yaml_supported = True except ImportError: pass diff --git a/ext/guessit/rules/common/formatters.py b/ext/guessit/rules/common/formatters.py index 434c20be3b..2a64dee9fa 100644 --- a/ext/guessit/rules/common/formatters.py +++ b/ext/guessit/rules/common/formatters.py @@ -25,7 +25,7 @@ def _potential_before(i, input_string): :return: :rtype: bool """ - return i - 2 >= 0 and input_string[i] in seps and input_string[i - 2] in seps and input_string[i - 1] not in seps + return i - 1 >= 0 and input_string[i] in seps and input_string[i - 2] in seps and input_string[i - 1] not in seps def _potential_after(i, input_string): diff --git a/ext/guessit/rules/properties/audio_codec.py b/ext/guessit/rules/properties/audio_codec.py index a2566bcee5..b9f298ea8c 100644 --- a/ext/guessit/rules/properties/audio_codec.py +++ b/ext/guessit/rules/properties/audio_codec.py @@ -71,16 +71,16 @@ def audio_codec_priority(match1, match2): rebulk.string('EX', value='EX', tags=['audio_profile.rule', 'Dolby Digital']) rebulk.defaults(name="audio_channels", disabled=lambda context: is_disabled(context, 'audio_channels')) - rebulk.regex(r'(7[\W_][01](?:ch)?)(?=[^\d]|$)', value='7.1', children=True) - rebulk.regex(r'(5[\W_][01](?:ch)?)(?=[^\d]|$)', value='5.1', children=True) - rebulk.regex(r'(2[\W_]0(?:ch)?)(?=[^\d]|$)', value='2.0', children=True) rebulk.regex('7[01]', value='7.1', validator=seps_after, tags='weak-audio_channels') rebulk.regex('5[01]', value='5.1', validator=seps_after, tags='weak-audio_channels') rebulk.string('20', value='2.0', validator=seps_after, tags='weak-audio_channels') - rebulk.string('7ch', '8ch', value='7.1') - rebulk.string('5ch', '6ch', value='5.1') - rebulk.string('2ch', 'stereo', value='2.0') - rebulk.string('1ch', 'mono', value='1.0') + + for value, items in config.get('audio_channels').items(): + for item in items: + if item.startswith('re:'): + rebulk.regex(item[3:], value=value, children=True) + else: + rebulk.string(item, value=value) rebulk.rules(DtsHDRule, DtsRule, AacRule, DolbyDigitalRule, AudioValidatorRule, HqConflictRule, AudioChannelsValidatorRule) diff --git a/ext/guessit/rules/properties/bonus.py b/ext/guessit/rules/properties/bonus.py index c4554cd065..54087aa315 100644 --- a/ext/guessit/rules/properties/bonus.py +++ b/ext/guessit/rules/properties/bonus.py @@ -26,7 +26,8 @@ def bonus(config): # pylint:disable=unused-argument rebulk = rebulk.regex_defaults(flags=re.IGNORECASE) rebulk.regex(r'x(\d+)', name='bonus', private_parent=True, children=True, formatter=int, - validator={'__parent__': lambda match: seps_surround}, + validator={'__parent__': seps_surround}, + validate_all=True, conflict_solver=lambda match, conflicting: match if conflicting.name in ('video_codec', 'episode') and 'weak-episode' not in conflicting.tags else '__default__') diff --git a/ext/guessit/rules/properties/episodes.py b/ext/guessit/rules/properties/episodes.py index 97f060a2b9..d2e74bc587 100644 --- a/ext/guessit/rules/properties/episodes.py +++ b/ext/guessit/rules/properties/episodes.py @@ -629,10 +629,11 @@ class RemoveWeak(Rule): Remove weak-episode matches which appears after video, source, and audio matches. """ priority = 16 - consequence = RemoveMatch + consequence = RemoveMatch, AppendMatch def when(self, matches, context): to_remove = [] + to_append = [] for filepart in matches.markers.named('path'): weaks = matches.range(filepart.start, filepart.end, predicate=lambda m: 'weak-episode' in m.tags) if weaks: @@ -641,8 +642,18 @@ def when(self, matches, context): 'audio_channels', 'audio_profile'), index=0) if previous and not matches.holes( previous.end, weaks[0].start, predicate=lambda m: m.raw.strip(seps)): + if previous.raw.lower() == 'ep': + episode = copy.copy(weaks[0]) + episode.name = 'episode' + episode.value = int(weaks[0].value) + episode.start = previous.start + episode.private = False + episode.tags = [] + + to_append.append(episode) + to_remove.extend(weaks) - return to_remove + return to_remove, to_append class RemoveWeakIfSxxExx(Rule): diff --git a/ext/guessit/rules/properties/language.py b/ext/guessit/rules/properties/language.py index bcdbda8b7c..be8306346b 100644 --- a/ext/guessit/rules/properties/language.py +++ b/ext/guessit/rules/properties/language.py @@ -72,6 +72,8 @@ def find_languages(string, context=None): UNDETERMINED = babelfish.Language('und') +MULTIPLE = babelfish.Language('mul') +NON_SPECIFIC_LANGUAGES = frozenset([UNDETERMINED, MULTIPLE]) class GuessitConverter(babelfish.LanguageReverseConverter): # pylint: disable=missing-docstring @@ -478,6 +480,7 @@ class RemoveInvalidLanguages(Rule): """Remove language matches that matches the blacklisted common words.""" consequence = RemoveMatch + priority = 32 def __init__(self, common_words): """Constructor.""" diff --git a/ext/guessit/rules/properties/other.py b/ext/guessit/rules/properties/other.py index 330caa9216..34f47159e7 100644 --- a/ext/guessit/rules/properties/other.py +++ b/ext/guessit/rules/properties/other.py @@ -35,11 +35,16 @@ def other(config): # pylint:disable=unused-argument,too-many-statements rebulk.regex('ws', 'wide-?screen', value='Widescreen') rebulk.regex('Re-?Enc(?:oded)?', value='Reencoded') - rebulk.string('Proper', 'Repack', 'Rerip', value='Proper', + rebulk.string('Repack', 'Rerip', value='Proper', tags=['streaming_service.prefix', 'streaming_service.suffix']) + rebulk.string('Proper', value='Proper', + tags=['has-neighbor', 'streaming_service.prefix', 'streaming_service.suffix']) rebulk.regex('Real-Proper', 'Real-Repack', 'Real-Rerip', value='Proper', tags=['streaming_service.prefix', 'streaming_service.suffix', 'real']) + rebulk.regex('Real', value='Proper', + tags=['has-neighbor', 'streaming_service.prefix', 'streaming_service.suffix', 'real']) + rebulk.string('Fix', 'Fixed', value='Fix', tags=['has-neighbor-before', 'has-neighbor-after', 'streaming_service.prefix', 'streaming_service.suffix']) rebulk.string('Dirfix', 'Nfofix', 'Prooffix', value='Fix', @@ -80,8 +85,9 @@ def validate_complete(match): rebulk.regex('(HD)(?PRip)', value={'other': 'HD', 'another': 'Rip'}, private_parent=True, children=True, validator={'__parent__': seps_surround}, validate_all=True) - for value in ('Screener', 'Remux', '3D', 'PAL', 'SECAM', 'NTSC', 'XXX'): + for value in ('Screener', 'Remux', 'PAL', 'SECAM', 'NTSC', 'XXX'): rebulk.string(value, value=value) + rebulk.string('3D', value='3D', tags='has-neighbor') rebulk.string('HQ', value='High Quality', tags='uhdbluray-neighbor') rebulk.string('HR', value='High Resolution') @@ -128,13 +134,15 @@ def validate_complete(match): rebulk.regex('BT-?2020', value='BT.2020', tags='uhdbluray-neighbor') rebulk.string('Sample', value='Sample', tags=['at-end', 'not-a-release-group']) + rebulk.string('Extras', value='Extras', tags='has-neighbor') + rebulk.regex('Digital-?Extras?', value='Extras') rebulk.string('Proof', value='Proof', tags=['at-end', 'not-a-release-group']) rebulk.string('Obfuscated', 'Scrambled', value='Obfuscated', tags=['at-end', 'not-a-release-group']) rebulk.string('xpost', 'postbot', 'asrequested', value='Repost', tags='not-a-release-group') rebulk.rules(RenameAnotherToOther, ValidateHasNeighbor, ValidateHasNeighborAfter, ValidateHasNeighborBefore, ValidateScreenerRule, ValidateMuxRule, ValidateHardcodedSubs, ValidateStreamingServiceNeighbor, - ValidateAtEnd, ProperCountRule) + ValidateAtEnd, ValidateReal, ProperCountRule) return rebulk @@ -354,3 +362,20 @@ def when(self, matches, context): to_remove.append(match) return to_remove + + +class ValidateReal(Rule): + """ + Validate Real + """ + consequence = RemoveMatch + priority = 64 + + def when(self, matches, context): + ret = [] + for filepart in matches.markers.named('path'): + for match in matches.range(filepart.start, filepart.end, lambda m: m.name == 'other' and 'real' in m.tags): + if not matches.range(filepart.start, match.start): + ret.append(match) + + return ret diff --git a/ext/guessit/rules/properties/release_group.py b/ext/guessit/rules/properties/release_group.py index ff1ac66023..1b4512c02a 100644 --- a/ext/guessit/rules/properties/release_group.py +++ b/ext/guessit/rules/properties/release_group.py @@ -50,7 +50,7 @@ def clean_groupname(string): if string.lower().endswith(forbidden) and string[-len(forbidden) - 1:-len(forbidden)] in seps: string = string[:len(forbidden)] string = string.strip(groupname_seps) - return string + return string.strip() rebulk = Rebulk(disabled=lambda context: is_disabled(context, 'release_group')) diff --git a/ext/guessit/rules/properties/source.py b/ext/guessit/rules/properties/source.py index ae9a7b03ae..d2261ba405 100644 --- a/ext/guessit/rules/properties/source.py +++ b/ext/guessit/rules/properties/source.py @@ -92,8 +92,9 @@ def demote_other(match, other): # pylint: disable=unused-argument # WEBCap is a synonym to WEBRip, mostly used by non english rebulk.regex(*build_source_pattern('WEB-?(?PCap)', suffix=rip_optional_suffix), value={'source': 'Web', 'other': 'Rip', 'another': 'Rip'}) - rebulk.regex(*build_source_pattern('WEB-?DL', 'WEB-?U?HD', 'WEB', 'DL-?WEB', 'DL(?=-?Mux)'), + rebulk.regex(*build_source_pattern('WEB-?DL', 'WEB-?U?HD', 'DL-?WEB', 'DL(?=-?Mux)'), value={'source': 'Web'}) + rebulk.regex('(WEB)', value='Web', tags='weak.source') rebulk.regex(*build_source_pattern('HD-?DVD', suffix=rip_optional_suffix), value={'source': 'HD-DVD', 'other': 'Rip'}) @@ -175,27 +176,40 @@ def when(self, matches, context): class ValidateSource(Rule): """ - Validate source with screener property, with video_codec property or separated + Validate source with source prefix, source suffix. """ priority = 64 consequence = RemoveMatch def when(self, matches, context): ret = [] - for match in matches.named('source'): - match = match.initiator - if not seps_before(match) and \ - not matches.range(match.start - 1, match.start - 2, - lambda m: 'source-prefix' in m.tags): - if match.children: - ret.extend(match.children) - ret.append(match) - continue - if not seps_after(match) and \ - not matches.range(match.end, match.end + 1, - lambda m: 'source-suffix' in m.tags): - if match.children: - ret.extend(match.children) - ret.append(match) - continue + for filepart in matches.markers.named('path'): + for match in matches.range(filepart.start, filepart.end, predicate=lambda m: m.name == 'source'): + match = match.initiator + if not seps_before(match) and \ + not matches.range(match.start - 1, match.start - 2, + lambda m: 'source-prefix' in m.tags): + if match.children: + ret.extend(match.children) + ret.append(match) + continue + if not seps_after(match) and \ + not matches.range(match.end, match.end + 1, + lambda m: 'source-suffix' in m.tags): + if match.children: + ret.extend(match.children) + ret.append(match) + continue + + # if there are more than 1 source in this filepart, just before the year and with holes for the title + # most likely the source is part of the title + if 'weak.source' in match.tags \ + and matches.range(match.end, filepart.end, predicate=lambda m: m.name == 'source') \ + and matches.holes(filepart.start, match.start, + predicate=lambda m: m.value.strip(seps), index=-1): + if match.children: + ret.extend(match.children) + ret.append(match) + continue + return ret diff --git a/ext/guessit/rules/properties/streaming_service.py b/ext/guessit/rules/properties/streaming_service.py index 1302befb0b..3f5646c1b9 100644 --- a/ext/guessit/rules/properties/streaming_service.py +++ b/ext/guessit/rules/properties/streaming_service.py @@ -25,133 +25,13 @@ def streaming_service(config): # pylint: disable=too-many-statements,unused-arg rebulk = rebulk.string_defaults(ignore_case=True).regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='streaming_service', tags=['source-prefix']) - rebulk.string('AE', 'A&E', value='A&E') - rebulk.string('AMBC', value='ABC') - rebulk.string('AUBC', value='ABC Australia') - rebulk.string('AJAZ', value='Al Jazeera English') - rebulk.string('AMC', value='AMC') - rebulk.string('AMZN', 'Amazon', value='Amazon Prime') - rebulk.regex('Amazon-?Prime', value='Amazon Prime') - rebulk.string('AS', value='Adult Swim') - rebulk.regex('Adult-?Swim', value='Adult Swim') - rebulk.string('ATK', value="America's Test Kitchen") - rebulk.string('ANPL', value='Animal Planet') - rebulk.string('ANLB', value='AnimeLab') - rebulk.string('AOL', value='AOL') - rebulk.string('ARD', value='ARD') - rebulk.string('iP', value='BBC iPlayer') - rebulk.regex('BBC-?iPlayer', value='BBC iPlayer') - rebulk.string('BRAV', value='BravoTV') - rebulk.string('CNLP', value='Canal+') - rebulk.string('CN', value='Cartoon Network') - rebulk.string('CBC', value='CBC') - rebulk.string('CBS', value='CBS') - rebulk.string('CNBC', value='CNBC') - rebulk.string('CC', value='Comedy Central') - rebulk.string('4OD', value='Channel 4') - rebulk.string('CHGD', value='CHRGD') - rebulk.string('CMAX', value='Cinemax') - rebulk.string('CMT', value='Country Music Television') - rebulk.regex('Comedy-?Central', value='Comedy Central') - rebulk.string('CCGC', value='Comedians in Cars Getting Coffee') - rebulk.string('CR', value='Crunchy Roll') - rebulk.string('CRKL', value='Crackle') - rebulk.regex('Crunchy-?Roll', value='Crunchy Roll') - rebulk.string('CSPN', value='CSpan') - rebulk.string('CTV', value='CTV') - rebulk.string('CUR', value='CuriosityStream') - rebulk.string('CWS', value='CWSeed') - rebulk.string('DSKI', value='Daisuki') - rebulk.string('DHF', value='Deadhouse Films') - rebulk.string('DDY', value='Digiturk Diledigin Yerde') - rebulk.string('DISC', 'Discovery', value='Discovery') - rebulk.string('DSNY', 'Disney', value='Disney') - rebulk.string('DIY', value='DIY Network') - rebulk.string('DOCC', value='Doc Club') - rebulk.string('DPLY', value='DPlay') - rebulk.string('ETV', value='E!') - rebulk.string('EPIX', value='ePix') - rebulk.string('ETTV', value='El Trece') - rebulk.string('ESPN', value='ESPN') - rebulk.string('ESQ', value='Esquire') - rebulk.string('FAM', value='Family') - rebulk.string('FJR', value='Family Jr') - rebulk.string('FOOD', value='Food Network') - rebulk.string('FOX', value='Fox') - rebulk.string('FREE', value='Freeform') - rebulk.string('FYI', value='FYI Network') - rebulk.string('GLBL', value='Global') - rebulk.string('GLOB', value='GloboSat Play') - rebulk.string('HLMK', value='Hallmark') - rebulk.string('HBO', value='HBO Go') - rebulk.regex('HBO-?Go', value='HBO Go') - rebulk.string('HGTV', value='HGTV') - rebulk.string('HIST', 'History', value='History') - rebulk.string('HULU', value='Hulu') - rebulk.string('ID', value='Investigation Discovery') - rebulk.string('IFC', value='IFC') - rebulk.string('iTunes', 'iT', value='iTunes') - rebulk.string('ITV', value='ITV') - rebulk.string('KNOW', value='Knowledge Network') - rebulk.string('LIFE', value='Lifetime') - rebulk.string('MTOD', value='Motor Trend OnDemand') - rebulk.string('MNBC', value='MSNBC') - rebulk.string('MTV', value='MTV') - rebulk.string('NATG', value='National Geographic') - rebulk.regex('National-?Geographic', value='National Geographic') - rebulk.string('NBA', value='NBA TV') - rebulk.regex('NBA-?TV', value='NBA TV') - rebulk.string('NBC', value='NBC') - rebulk.string('NF', 'Netflix', value='Netflix') - rebulk.string('NFL', value='NFL') - rebulk.string('NFLN', value='NFL Now') - rebulk.string('GC', value='NHL GameCenter') - rebulk.string('NICK', 'Nickelodeon', value='Nickelodeon') - rebulk.string('NRK', value='Norsk Rikskringkasting') - rebulk.string('PBS', value='PBS') - rebulk.string('PBSK', value='PBS Kids') - rebulk.string('PSN', value='Playstation Network') - rebulk.string('PLUZ', value='Pluzz') - rebulk.string('RTE', value='RTE One') - rebulk.string('SBS', value='SBS (AU)') - rebulk.string('SESO', 'SeeSo', value='SeeSo') - rebulk.string('SHMI', value='Shomi') - rebulk.string('SPIK', value='Spike') - rebulk.string('SPKE', value='Spike TV') - rebulk.regex('Spike-?TV', value='Spike TV') - rebulk.string('SNET', value='Sportsnet') - rebulk.string('SPRT', value='Sprout') - rebulk.string('STAN', value='Stan') - rebulk.string('STZ', value='Starz') - rebulk.string('SVT', value='Sveriges Television') - rebulk.string('SWER', value='SwearNet') - rebulk.string('SYFY', value='Syfy') - rebulk.string('TBS', value='TBS') - rebulk.string('TFOU', value='TFou') - rebulk.string('CW', value='The CW') - rebulk.regex('The-?CW', value='The CW') - rebulk.string('TLC', value='TLC') - rebulk.string('TUBI', value='TubiTV') - rebulk.string('TV3', value='TV3 Ireland') - rebulk.string('TV4', value='TV4 Sweeden') - rebulk.string('TVL', value='TV Land') - rebulk.regex('TV-?Land', value='TV Land') - rebulk.string('UFC', value='UFC') - rebulk.string('UKTV', value='UKTV') - rebulk.string('UNIV', value='Univision') - rebulk.string('USAN', value='USA Network') - rebulk.string('VLCT', value='Velocity') - rebulk.string('VH1', value='VH1') - rebulk.string('VICE', value='Viceland') - rebulk.string('VMEO', value='Vimeo') - rebulk.string('VRV', value='VRV') - rebulk.string('WNET', value='W Network') - rebulk.string('WME', value='WatchMe') - rebulk.string('WWEN', value='WWE Network') - rebulk.string('XBOX', value='Xbox Video') - rebulk.string('YHOO', value='Yahoo') - rebulk.string('RED', value='YouTube Red') - rebulk.string('ZDF', value='ZDF') + for value, items in config.items(): + patterns = items if isinstance(items, list) else [items] + for pattern in patterns: + if pattern.startswith('re:'): + rebulk.regex(pattern, value=value) + else: + rebulk.string(pattern, value=value) rebulk.rules(ValidateStreamingService) diff --git a/ext/guessit/rules/properties/title.py b/ext/guessit/rules/properties/title.py index d1cafe2a8e..63f4bf296d 100644 --- a/ext/guessit/rules/properties/title.py +++ b/ext/guessit/rules/properties/title.py @@ -8,7 +8,12 @@ from rebulk.formatters import formatters from .film import FilmTitleRule -from .language import SubtitlePrefixLanguageRule, SubtitleSuffixLanguageRule, SubtitleExtensionRule +from .language import ( + SubtitlePrefixLanguageRule, + SubtitleSuffixLanguageRule, + SubtitleExtensionRule, + NON_SPECIFIC_LANGUAGES +) from ..common import seps, title_seps from ..common.comparators import marker_sorted from ..common.expected import build_expected_function @@ -88,9 +93,15 @@ def holes_process(self, holes, matches): :rtype: """ cropped_holes = [] + group_markers = matches.markers.named('group') + for group_marker in group_markers: + path_marker = matches.markers.at_match(group_marker, predicate=lambda m: m.name == 'path', index=0) + if path_marker and path_marker.span == group_marker.span: + group_markers.remove(group_marker) + for hole in holes: - group_markers = matches.markers.named('group') cropped_holes.extend(hole.crop(group_markers)) + return cropped_holes def is_ignored(self, match): @@ -130,7 +141,8 @@ def should_keep(self, match, to_keep, matches, filepart, hole, starting): for outside in outside_matches: other_languages.extend(matches.range(outside.start, outside.end, lambda c_match: c_match.name == match.name and - c_match not in to_keep)) + c_match not in to_keep and + c_match.value not in NON_SPECIFIC_LANGUAGES)) if not other_languages and (not starting or len(match.raw) <= 3): return True diff --git a/ext/guessit/test/enable_disable_properties.yml b/ext/guessit/test/enable_disable_properties.yml index 86c659d667..24ac29bad6 100644 --- a/ext/guessit/test/enable_disable_properties.yml +++ b/ext/guessit/test/enable_disable_properties.yml @@ -35,9 +35,9 @@ -cd: 1 -cd_count: 3 -? This.Is.Us +? This.is.Us : options: --exclude country - title: This Is Us + title: This is Us -country: US ? 2015.01.31 diff --git a/ext/guessit/test/episodes.yml b/ext/guessit/test/episodes.yml index f7b5c3df3d..fcb9f6abd3 100644 --- a/ext/guessit/test/episodes.yml +++ b/ext/guessit/test/episodes.yml @@ -1917,9 +1917,11 @@ ? Duck.Dynasty.S02E07.Streik.German.DOKU.DL.WS.DVDRiP.x264-CDP : episode: 7 - episode_title: Streik German + episode_title: Streik source: DVD - language: mul + language: + - German + - Multi other: [Documentary, Widescreen, Rip] release_group: CDP season: 2 @@ -1930,9 +1932,11 @@ ? Family.Guy.S13E14.JOLO.German.AC3D.DL.720p.WebHD.x264-CDD : audio_codec: Dolby Digital episode: 14 - episode_title: JOLO German + episode_title: JOLO source: Web - language: mul + language: + - German + - Multi release_group: CDD screen_size: 720p season: 13 @@ -4524,4 +4528,129 @@ video_codec: H.264 audio_codec: MP2 release_group: KIDKAT - type: episode \ No newline at end of file + type: episode + +? Por Trece Razones - Temporada 2 [HDTV 720p][Cap.201][AC3 5.1 Castellano]/Por Trece Razones 2x01 [des202].mkv +: title: Por Trece Razones + season: 2 + source: HDTV + screen_size: 720p + episode: 1 + audio_codec: Dolby Digital + audio_channels: '5.1' + language: Catalan + release_group: des202 + container: mkv + type: episode + +? Cuerpo de Elite - Temporada 1 [HDTV 720p][Cap.113][AC3 5.1 Esp Castellano]\CuerpoDeElite720p_113_desca202.mkv +: title: Cuerpo de Elite + season: 1 + source: HDTV + screen_size: 720p + episode: 13 + audio_codec: Dolby Digital + audio_channels: '5.1' + language: + - Spanish + - Catalan + container: mkv + type: episode + +? Show.Name.S01E01.St.Patricks.Day.1080p.mkv +: title: Show Name + season: 1 + episode: 1 + episode_title: St Patricks Day + screen_size: 1080p + container: mkv + type: episode + +? Show.Name.S01E01.St.Patricks.Day.1080p-grp.mkv +: title: Show Name + season: 1 + episode: 1 + episode_title: St Patricks Day + screen_size: 1080p + release_group: grp + container: mkv + type: episode + +? Titans.2018.S01E09.Hank.And.Dawn.720p.DCU.WEB-DL.AAC2.0.H264-NTb +: title: Titans + year: 2018 + season: 1 + episode: 9 + episode_title: Hank And Dawn + screen_size: 720p + streaming_service: DC Universe + source: Web + audio_codec: AAC + audio_channels: '2.0' + video_codec: H.264 + release_group: NTb + type: episode + +? S.W.A.T.2017.S01E21.Treibjagd.German.Dubbed.DL.AmazonHD.x264-TVS +: title: S.W.A.T. + year: 2017 + season: 1 + episode: 21 + episode_title: Treibjagd + language: + - German + - Multi + streaming_service: Amazon Prime + other: HD + video_codec: H.264 + release_group: TVS + type: episode + +? S.W.A.T.2017.S01E16.READNFO.720p.HDTV.x264-KILLERS +: title: S.W.A.T. + year: 2017 + season: 1 + episode: 16 + other: Read NFO + screen_size: 720p + source: HDTV + video_codec: H.264 + release_group: KILLERS + type: episode + +? /mnt/NAS/NoSubsTVShows/Babylon 5/Season 01/Ep. 02 - Soul Hunter +: title: Babylon 5 + season: 1 + episode: 2 + episode_title: Soul Hunter + type: episode + +? This.is.Us.S01E01.HDTV.x264-KILLERS.mkv +: title: This is Us + season: 1 + episode: 1 + source: HDTV + video_codec: H.264 + release_group: KILLERS + container: mkv + type: episode + +? Videos/Office1080/The Office (US) (2005) Season 2 S02 + Extras (1080p AMZN WEB-DL x265 HEVC 10bit AAC 2.0 LION)/The Office (US) (2005) - S02E12 - The Injury (1080p AMZN WEB-DL x265 LION).mkv +: title: The Office + country: US + year: 2005 + season: 2 + other: Extras + screen_size: 1080p + streaming_service: Amazon Prime + source: Web + video_codec: H.265 + video_profile: High Efficiency Video Coding + color_depth: 10-bit + audio_codec: AAC + audio_channels: '2.0' + release_group: LION + episode: 12 + episode_title: The Injury + container: mkv + type: episode diff --git a/ext/guessit/test/movies.yml b/ext/guessit/test/movies.yml index 642012a926..a534ca0f22 100644 --- a/ext/guessit/test/movies.yml +++ b/ext/guessit/test/movies.yml @@ -815,10 +815,12 @@ ? Das.Appartement.German.AC3D.DL.720p.BluRay.x264-TVP : audio_codec: Dolby Digital source: Blu-ray - language: mul + language: + - German + - Multi release_group: TVP screen_size: 720p - title: Das Appartement German + title: Das Appartement type: movie video_codec: H.264 @@ -1723,7 +1725,7 @@ ? Ant-Man.and.the.Wasp.2018.Digital.Extras.1080p.AMZN.WEB-DL.DDP5.1.H.264-NTG.mkv : title: Ant-Man and the Wasp year: 2018 - alternative_title: Digital Extras + other: Extras screen_size: 1080p streaming_service: Amazon Prime source: Web @@ -1770,4 +1772,15 @@ audio_channels: '5.1' video_codec: H.264 release_group: CMRG - type: movie \ No newline at end of file + type: movie + +? The.Girl.in.the.Spiders.Web.2019.1080p.WEB-DL.x264.AC3-EVO.mkv +: title: The Girl in the Spiders Web + year: 2019 + screen_size: 1080p + source: Web + video_codec: H.264 + audio_codec: Dolby Digital + release_group: EVO + container: mkv + type: movie diff --git a/ext/guessit/test/rules/common_words.yml b/ext/guessit/test/rules/common_words.yml new file mode 100644 index 0000000000..d403a45717 --- /dev/null +++ b/ext/guessit/test/rules/common_words.yml @@ -0,0 +1,467 @@ +? is +: title: is + +? it +: title: it + +? am +: title: am + +? mad +: title: mad + +? men +: title: men + +? man +: title: man + +? run +: title: run + +? sin +: title: sin + +? st +: title: st + +? to +: title: to + +? 'no' +: title: 'no' + +? non +: title: non + +? war +: title: war + +? min +: title: min + +? new +: title: new + +? car +: title: car + +? day +: title: day + +? bad +: title: bad + +? bat +: title: bat + +? fan +: title: fan + +? fry +: title: fry + +? cop +: title: cop + +? zen +: title: zen + +? gay +: title: gay + +? fat +: title: fat + +? one +: title: one + +? cherokee +: title: cherokee + +? got +: title: got + +? an +: title: an + +? as +: title: as + +? cat +: title: cat + +? her +: title: her + +? be +: title: be + +? hat +: title: hat + +? sun +: title: sun + +? may +: title: may + +? my +: title: my + +? mr +: title: mr + +? rum +: title: rum + +? pi +: title: pi + +? bb +: title: bb + +? bt +: title: bt + +? tv +: title: tv + +? aw +: title: aw + +? by +: title: by + +? md +: other: Mic Dubbed + +? mp +: title: mp + +? cd +: title: cd + +? in +: title: in + +? ad +: title: ad + +? ice +: title: ice + +? ay +: title: ay + +? at +: title: at + +? star +: title: star + +? so +: title: so + +? he +: title: he + +? do +: title: do + +? ax +: title: ax + +? mx +: title: mx + +? bas +: title: bas + +? de +: title: de + +? le +: title: le + +? son +: title: son + +? ne +: title: ne + +? ca +: title: ca + +? ce +: title: ce + +? et +: title: et + +? que +: title: que + +? mal +: title: mal + +? est +: title: est + +? vol +: title: vol + +? or +: title: or + +? mon +: title: mon + +? se +: title: se + +? je +: title: je + +? tu +: title: tu + +? me +: title: me + +? ma +: title: ma + +? va +: title: va + +? au +: country: AU + +? lu +: title: lu + +? wa +: title: wa + +? ga +: title: ga + +? ao +: title: ao + +? la +: title: la + +? el +: title: el + +? del +: title: del + +? por +: title: por + +? mar +: title: mar + +? al +: title: al + +? un +: title: un + +? ind +: title: ind + +? arw +: title: arw + +? ts +: source: Telesync + +? ii +: title: ii + +? bin +: title: bin + +? chan +: title: chan + +? ss +: title: ss + +? san +: title: san + +? oss +: title: oss + +? iii +: title: iii + +? vi +: title: vi + +? ben +: title: ben + +? da +: title: da + +? lt +: title: lt + +? ch +: title: ch + +? sr +: title: sr + +? ps +: title: ps + +? cx +: title: cx + +? vo +: title: vo + +? mkv +: container: mkv + +? avi +: container: avi + +? dmd +: title: dmd + +? the +: title: the + +? dis +: title: dis + +? cut +: title: cut + +? stv +: title: stv + +? des +: title: des + +? dia +: title: dia + +? and +: title: and + +? cab +: title: cab + +? sub +: title: sub + +? mia +: title: mia + +? rim +: title: rim + +? las +: title: las + +? une +: title: une + +? par +: title: par + +? srt +: container: srt + +? ano +: title: ano + +? toy +: title: toy + +? job +: title: job + +? gag +: title: gag + +? reel +: title: reel + +? www +: title: www + +? for +: title: for + +? ayu +: title: ayu + +? csi +: title: csi + +? ren +: title: ren + +? moi +: title: moi + +? sur +: title: sur + +? fer +: title: fer + +? fun +: title: fun + +? two +: title: two + +? big +: title: big + +? psy +: title: psy + +? air +: title: air + +? brazil +: title: brazil + +? jordan +: title: jordan + +? bs +: title: bs + +? kz +: title: kz + +? gt +: title: gt + +? im +: title: im + +? pt +: language: pt + +? scr +: title: scr + +? sd +: title: sd + +? hr +: other: High Resolution diff --git a/ext/guessit/test/rules/country.yml b/ext/guessit/test/rules/country.yml index 763831807f..b3d4d8f140 100644 --- a/ext/guessit/test/rules/country.yml +++ b/ext/guessit/test/rules/country.yml @@ -5,8 +5,8 @@ : country: US title: this is title -? This.is.us.title -: title: This is us title +? This.is.Us +: title: This is Us ? This.Is.Us : options: --no-default-config diff --git a/ext/guessit/test/rules/other.yml b/ext/guessit/test/rules/other.yml index e2bea6e75b..447f1787d2 100644 --- a/ext/guessit/test/rules/other.yml +++ b/ext/guessit/test/rules/other.yml @@ -48,7 +48,7 @@ proper_count: 3 -? Proper +? Proper.720p ? +Repack ? +Rerip : other: Proper @@ -80,7 +80,7 @@ ? Remux : other: Remux -? 3D +? 3D.2019 : other: 3D ? HD diff --git a/ext/guessit/test/suggested.json b/ext/guessit/test/suggested.json new file mode 100644 index 0000000000..dc838ad012 --- /dev/null +++ b/ext/guessit/test/suggested.json @@ -0,0 +1,21 @@ +{ + "titles": [ + "13 Reasons Why", + "Star Wars: Episode VII - The Force Awakens", + "3%", + "The 100", + "3 Percent", + "This is Us", + "Open Season 2", + "Game of Thrones", + "The X-Files", + "11.22.63" + ], + "suggested": [ + "13 Reasons Why", + "Star Wars: Episode VII - The Force Awakens", + "The 100", + "Open Season 2", + "11.22.63" + ] +} \ No newline at end of file diff --git a/ext/guessit/test/test_api.py b/ext/guessit/test/test_api.py index 9abb84d9fd..391dbced87 100644 --- a/ext/guessit/test/test_api.py +++ b/ext/guessit/test/test_api.py @@ -1,13 +1,14 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # pylint: disable=no-self-use, pointless-statement, missing-docstring, invalid-name, pointless-string-statement - +import json import os +import sys import pytest import six -from ..api import guessit, properties, GuessitException +from ..api import guessit, properties, suggested_expected, GuessitException __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) @@ -27,12 +28,16 @@ def test_forced_binary(): assert ret and 'title' in ret and isinstance(ret['title'], six.binary_type) -@pytest.mark.skipif('sys.version_info < (3, 4)', reason="Path is not available") +@pytest.mark.skipif(sys.version_info < (3, 4), reason="Path is not available") def test_pathlike_object(): - from pathlib import Path - path = Path('Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv') - ret = guessit(path) - assert ret and 'title' in ret + try: + from pathlib import Path + + path = Path('Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv') + ret = guessit(path) + assert ret and 'title' in ret + except ImportError: # pragma: no-cover + pass def test_unicode_japanese(): @@ -69,3 +74,10 @@ def test_exception(): assert "An internal error has occured in guessit" in str(excinfo.value) assert "Guessit Exception Report" in str(excinfo.value) assert "Please report at https://github.com/guessit-io/guessit/issues" in str(excinfo.value) + + +def test_suggested_expected(): + with open(os.path.join(__location__, 'suggested.json'), 'r') as f: + content = json.load(f) + actual = suggested_expected(content['titles']) + assert actual == content['suggested'] diff --git a/ext/guessit/test/test_yml.py b/ext/guessit/test/test_yml.py index 4f58a056c6..78edaf1152 100644 --- a/ext/guessit/test/test_yml.py +++ b/ext/guessit/test/test_yml.py @@ -7,9 +7,9 @@ from io import open # pylint: disable=redefined-builtin import babelfish -import pytest -import six -import yaml +import pytest # pylint:disable=wrong-import-order +import six # pylint:disable=wrong-import-order +import yaml # pylint:disable=wrong-import-order from rebulk.remodule import re from rebulk.utils import is_iterable diff --git a/ext/guessit/test/various.yml b/ext/guessit/test/various.yml index 5e689e0b37..cf0e6617e5 100644 --- a/ext/guessit/test/various.yml +++ b/ext/guessit/test/various.yml @@ -946,3 +946,171 @@ source: Blu-ray audio_codec: DTS-HD type: movie + +? Mr Robot - S03E01 - eps3 0 power-saver-mode h (1080p AMZN WEB-DL x265 HEVC 10bit EAC3 6.0 RCVR).mkv +: title: Mr Robot + season: 3 + episode: 1 + episode_title: eps3 0 power-saver-mode h + screen_size: 1080p + streaming_service: Amazon Prime + source: Web + video_codec: H.265 + video_profile: High Efficiency Video Coding + color_depth: 10-bit + audio_codec: Dolby Digital Plus + audio_channels: '5.1' + release_group: RCVR + container: mkv + type: episode + +? Panorama.15-05-2018.Web-DL.540p.H264.AAC.Subs.mp4 +: title: Panorama + date: 2018-05-15 + source: Web + screen_size: 540p + video_codec: H.264 + audio_codec: AAC + subtitle_language: und + container: mp4 + type: episode + +? Shaolin 2011.720p.BluRay.x264-x0r.mkv +: title: Shaolin + year: 2011 + screen_size: 720p + source: Blu-ray + video_codec: H.264 + release_group: x0r + container: mkv + type: movie + +? '[ Engineering Catastrophes S02E10 1080p AMZN WEB-DL DD+ 2.0 x264-TrollHD ]' +: title: Engineering Catastrophes + season: 2 + episode: 10 + screen_size: 1080p + streaming_service: Amazon Prime + source: Web + audio_codec: Dolby Digital Plus + audio_channels: '2.0' + video_codec: H.264 + release_group: TrollHD + type: episode + +? A Very Harold & Kumar 3D Christmas (2011).mkv +: title: A Very Harold & Kumar 3D Christmas + year: 2011 + container: mkv + type: movie + +? Cleveland.Hustles.S01E03.Downward.Dogs.and.Proper.Pigs.720p.HDTV.x264-W4F +: title: Cleveland Hustles + season: 1 + episode: 3 + episode_title: Downward Dogs and Proper Pigs + screen_size: 720p + source: HDTV + video_codec: H.264 + release_group: W4F + type: episode + +? Pawn.Stars.S12E20.The.Pawn.Awakens.REAL.READ.NFO.720p.HDTV.x264-DHD +: title: Pawn Stars + season: 12 + episode: 20 + episode_title: The Pawn Awakens + other: + - Proper + - Read NFO + proper_count: 2 + screen_size: 720p + source: HDTV + video_codec: H.264 + release_group: DHD + type: episode + +? Pawn.Stars.S12E22.Racing.Revolution.REAL.720p.HDTV.x264-DHD +: title: Pawn Stars + season: 12 + episode: 22 + episode_title: Racing Revolution + other: Proper + proper_count: 2 + screen_size: 720p + source: HDTV + video_codec: H.264 + release_group: DHD + type: episode + +? Luksusfellen.S18E02.REAL.NORWEGiAN.720p.WEB.h264-NORPiLT +: title: Luksusfellen + season: 18 + episode: 2 + other: Proper + proper_count: 2 + language: Norwegian + screen_size: 720p + source: Web + video_codec: H.264 + release_group: NORPiLT + type: episode + +? The.Exorcist.S02E07.REAL.FRENCH.720p.HDTV.x264-SH0W +: title: The Exorcist + season: 2 + episode: 7 + other: Proper + proper_count: 2 + language: fr + screen_size: 720p + source: HDTV + video_codec: H.264 + release_group: SH0W + type: episode + +? Outrageous.Acts.of.Science.S05E02.Is.This.for.Real.720p.HDTV.x264-DHD +: title: Outrageous Acts of Science + season: 5 + episode: 2 +# corner case +# episode_title: Is This for Real + screen_size: 720p + source: HDTV + video_codec: H.264 + release_group: DHD + type: episode + +? How.the.Universe.Works.S06E08.Strange.Lives.of.Dwarf.Planets.REAL.720p.WEB.x264-DHD +: title: How the Universe Works + season: 6 + episode: 8 + episode_title: Strange Lives of Dwarf Planets + other: Proper + proper_count: 2 + screen_size: 720p + source: Web + video_codec: H.264 + release_group: DHD + type: episode + +? Vampirina.S01E16.REAL.HDTV.x264-W4F +: title: Vampirina + season: 1 + episode: 16 + other: Proper + proper_count: 2 + source: HDTV + video_codec: H.264 + release_group: W4F + type: episode + +? Test.S01E16.Some Real Episode Title.HDTV.x264-W4F +: title: Test + season: 1 + episode: 16 + episode_title: Some Real Episode Title + source: HDTV + video_codec: H.264 + release_group: W4F + type: episode diff --git a/ext/guessit/yamlutils.py b/ext/guessit/yamlutils.py index 01ac77781a..e6f9fc1d8f 100644 --- a/ext/guessit/yamlutils.py +++ b/ext/guessit/yamlutils.py @@ -10,7 +10,7 @@ from ordereddict import OrderedDict # pylint:disable=import-error import babelfish -import yaml +import yaml # pylint:disable=wrong-import-order from .rules.common.quantity import BitRate, FrameRate, Size @@ -58,7 +58,7 @@ class CustomDumper(yaml.SafeDumper): """ Custom YAML Dumper. """ - pass + pass # pylint:disable=unnecessary-pass def default_representer(dumper, data): diff --git a/ext/idna/core.py b/ext/idna/core.py index 090c2c18d5..104624ad2d 100644 --- a/ext/idna/core.py +++ b/ext/idna/core.py @@ -267,10 +267,7 @@ def alabel(label): try: label = label.encode('ascii') - try: - ulabel(label) - except IDNAError: - raise IDNAError('The label {0} is not a valid A-label'.format(label)) + ulabel(label) if not valid_label_length(label): raise IDNAError('Label too long') return label diff --git a/ext/idna/idnadata.py b/ext/idna/idnadata.py index 17974e2337..a80c959d2a 100644 --- a/ext/idna/idnadata.py +++ b/ext/idna/idnadata.py @@ -1,6 +1,6 @@ # This file is automatically generated by tools/idna-data -__version__ = "10.0.0" +__version__ = "11.0.0" scripts = { 'Greek': ( 0x37000000374, @@ -49,7 +49,7 @@ 0x30210000302a, 0x30380000303c, 0x340000004db6, - 0x4e0000009feb, + 0x4e0000009ff0, 0xf9000000fa6e, 0xfa700000fada, 0x200000002a6d7, @@ -62,7 +62,7 @@ 'Hebrew': ( 0x591000005c8, 0x5d0000005eb, - 0x5f0000005f5, + 0x5ef000005f5, 0xfb1d0000fb37, 0xfb380000fb3d, 0xfb3e0000fb3f, @@ -248,6 +248,7 @@ 0x6fb: 68, 0x6fc: 68, 0x6ff: 68, + 0x70f: 84, 0x710: 82, 0x712: 68, 0x713: 68, @@ -522,6 +523,7 @@ 0x1875: 68, 0x1876: 68, 0x1877: 68, + 0x1878: 68, 0x1880: 85, 0x1881: 85, 0x1882: 85, @@ -690,6 +692,70 @@ 0x10bad: 68, 0x10bae: 68, 0x10baf: 85, + 0x10d00: 76, + 0x10d01: 68, + 0x10d02: 68, + 0x10d03: 68, + 0x10d04: 68, + 0x10d05: 68, + 0x10d06: 68, + 0x10d07: 68, + 0x10d08: 68, + 0x10d09: 68, + 0x10d0a: 68, + 0x10d0b: 68, + 0x10d0c: 68, + 0x10d0d: 68, + 0x10d0e: 68, + 0x10d0f: 68, + 0x10d10: 68, + 0x10d11: 68, + 0x10d12: 68, + 0x10d13: 68, + 0x10d14: 68, + 0x10d15: 68, + 0x10d16: 68, + 0x10d17: 68, + 0x10d18: 68, + 0x10d19: 68, + 0x10d1a: 68, + 0x10d1b: 68, + 0x10d1c: 68, + 0x10d1d: 68, + 0x10d1e: 68, + 0x10d1f: 68, + 0x10d20: 68, + 0x10d21: 68, + 0x10d22: 82, + 0x10d23: 68, + 0x10f30: 68, + 0x10f31: 68, + 0x10f32: 68, + 0x10f33: 82, + 0x10f34: 68, + 0x10f35: 68, + 0x10f36: 68, + 0x10f37: 68, + 0x10f38: 68, + 0x10f39: 68, + 0x10f3a: 68, + 0x10f3b: 68, + 0x10f3c: 68, + 0x10f3d: 68, + 0x10f3e: 68, + 0x10f3f: 68, + 0x10f40: 68, + 0x10f41: 68, + 0x10f42: 68, + 0x10f43: 68, + 0x10f44: 68, + 0x10f45: 85, + 0x10f51: 68, + 0x10f52: 68, + 0x10f53: 68, + 0x10f54: 82, + 0x110bd: 85, + 0x110cd: 85, 0x1e900: 68, 0x1e901: 68, 0x1e902: 68, @@ -1034,14 +1100,15 @@ 0x52d0000052e, 0x52f00000530, 0x5590000055a, - 0x56100000587, + 0x56000000587, + 0x58800000589, 0x591000005be, 0x5bf000005c0, 0x5c1000005c3, 0x5c4000005c6, 0x5c7000005c8, 0x5d0000005eb, - 0x5f0000005f3, + 0x5ef000005f3, 0x6100000061b, 0x62000000640, 0x64100000660, @@ -1054,12 +1121,13 @@ 0x7100000074b, 0x74d000007b2, 0x7c0000007f6, + 0x7fd000007fe, 0x8000000082e, 0x8400000085c, 0x8600000086b, 0x8a0000008b5, 0x8b6000008be, - 0x8d4000008e2, + 0x8d3000008e2, 0x8e300000958, 0x96000000964, 0x96600000970, @@ -1077,6 +1145,7 @@ 0x9e0000009e4, 0x9e6000009f2, 0x9fc000009fd, + 0x9fe000009ff, 0xa0100000a04, 0xa0500000a0b, 0xa0f00000a11, @@ -1136,8 +1205,7 @@ 0xbd000000bd1, 0xbd700000bd8, 0xbe600000bf0, - 0xc0000000c04, - 0xc0500000c0d, + 0xc0000000c0d, 0xc0e00000c11, 0xc1200000c29, 0xc2a00000c3a, @@ -1276,7 +1344,7 @@ 0x17dc000017de, 0x17e0000017ea, 0x18100000181a, - 0x182000001878, + 0x182000001879, 0x1880000018ab, 0x18b0000018f6, 0x19000000191f, @@ -1544,11 +1612,11 @@ 0x309d0000309f, 0x30a1000030fb, 0x30fc000030ff, - 0x31050000312f, + 0x310500003130, 0x31a0000031bb, 0x31f000003200, 0x340000004db6, - 0x4e0000009feb, + 0x4e0000009ff0, 0xa0000000a48d, 0xa4d00000a4fe, 0xa5000000a60d, @@ -1655,8 +1723,10 @@ 0xa7a50000a7a6, 0xa7a70000a7a8, 0xa7a90000a7aa, + 0xa7af0000a7b0, 0xa7b50000a7b6, 0xa7b70000a7b8, + 0xa7b90000a7ba, 0xa7f70000a7f8, 0xa7fa0000a828, 0xa8400000a874, @@ -1664,8 +1734,7 @@ 0xa8d00000a8da, 0xa8e00000a8f8, 0xa8fb0000a8fc, - 0xa8fd0000a8fe, - 0xa9000000a92e, + 0xa8fd0000a92e, 0xa9300000a954, 0xa9800000a9c1, 0xa9cf0000a9da, @@ -1743,7 +1812,7 @@ 0x10a0500010a07, 0x10a0c00010a14, 0x10a1500010a18, - 0x10a1900010a34, + 0x10a1900010a36, 0x10a3800010a3b, 0x10a3f00010a40, 0x10a6000010a7d, @@ -1756,6 +1825,11 @@ 0x10b8000010b92, 0x10c0000010c49, 0x10cc000010cf3, + 0x10d0000010d28, + 0x10d3000010d3a, + 0x10f0000010f1d, + 0x10f2700010f28, + 0x10f3000010f51, 0x1100000011047, 0x1106600011070, 0x1107f000110bb, @@ -1763,10 +1837,11 @@ 0x110f0000110fa, 0x1110000011135, 0x1113600011140, + 0x1114400011147, 0x1115000011174, 0x1117600011177, 0x11180000111c5, - 0x111ca000111cd, + 0x111c9000111cd, 0x111d0000111db, 0x111dc000111dd, 0x1120000011212, @@ -1786,7 +1861,7 @@ 0x1132a00011331, 0x1133200011334, 0x113350001133a, - 0x1133c00011345, + 0x1133b00011345, 0x1134700011349, 0x1134b0001134e, 0x1135000011351, @@ -1796,6 +1871,7 @@ 0x1137000011375, 0x114000001144b, 0x114500001145a, + 0x1145e0001145f, 0x11480000114c6, 0x114c7000114c8, 0x114d0000114da, @@ -1807,15 +1883,17 @@ 0x116500001165a, 0x11680000116b8, 0x116c0000116ca, - 0x117000001171a, + 0x117000001171b, 0x1171d0001172c, 0x117300001173a, + 0x118000001183b, 0x118c0000118ea, 0x118ff00011900, 0x11a0000011a3f, 0x11a4700011a48, 0x11a5000011a84, 0x11a8600011a9a, + 0x11a9d00011a9e, 0x11ac000011af9, 0x11c0000011c09, 0x11c0a00011c37, @@ -1831,6 +1909,13 @@ 0x11d3c00011d3e, 0x11d3f00011d48, 0x11d5000011d5a, + 0x11d6000011d66, + 0x11d6700011d69, + 0x11d6a00011d8f, + 0x11d9000011d92, + 0x11d9300011d99, + 0x11da000011daa, + 0x11ee000011ef7, 0x120000001239a, 0x1248000012544, 0x130000001342f, @@ -1845,11 +1930,12 @@ 0x16b5000016b5a, 0x16b6300016b78, 0x16b7d00016b90, + 0x16e6000016e80, 0x16f0000016f45, 0x16f5000016f7f, 0x16f8f00016fa0, 0x16fe000016fe2, - 0x17000000187ed, + 0x17000000187f2, 0x1880000018af3, 0x1b0000001b11f, 0x1b1700001b2fc, diff --git a/ext/idna/package_data.py b/ext/idna/package_data.py index 39c192bae6..257e898939 100644 --- a/ext/idna/package_data.py +++ b/ext/idna/package_data.py @@ -1,2 +1,2 @@ -__version__ = '2.7' +__version__ = '2.8' diff --git a/ext/idna/uts46data.py b/ext/idna/uts46data.py index 79731cb9e7..a68ed4c0ec 100644 --- a/ext/idna/uts46data.py +++ b/ext/idna/uts46data.py @@ -4,7 +4,7 @@ """IDNA Mapping Table from UTS46.""" -__version__ = "10.0.0" +__version__ = "11.0.0" def _seg_0(): return [ (0x0, '3'), @@ -1029,11 +1029,8 @@ def _seg_9(): (0x556, 'M', u'ֆ'), (0x557, 'X'), (0x559, 'V'), - (0x560, 'X'), - (0x561, 'V'), (0x587, 'M', u'եւ'), - (0x588, 'X'), - (0x589, 'V'), + (0x588, 'V'), (0x58B, 'X'), (0x58D, 'V'), (0x590, 'X'), @@ -1041,15 +1038,15 @@ def _seg_9(): (0x5C8, 'X'), (0x5D0, 'V'), (0x5EB, 'X'), - (0x5F0, 'V'), + (0x5EF, 'V'), (0x5F5, 'X'), + (0x606, 'V'), + (0x61C, 'X'), + (0x61E, 'V'), ] def _seg_10(): return [ - (0x606, 'V'), - (0x61C, 'X'), - (0x61E, 'V'), (0x675, 'M', u'اٴ'), (0x676, 'M', u'وٴ'), (0x677, 'M', u'ۇٴ'), @@ -1064,7 +1061,7 @@ def _seg_10(): (0x7B2, 'X'), (0x7C0, 'V'), (0x7FB, 'X'), - (0x800, 'V'), + (0x7FD, 'V'), (0x82E, 'X'), (0x830, 'V'), (0x83F, 'X'), @@ -1078,7 +1075,7 @@ def _seg_10(): (0x8B5, 'X'), (0x8B6, 'V'), (0x8BE, 'X'), - (0x8D4, 'V'), + (0x8D3, 'V'), (0x8E2, 'X'), (0x8E3, 'V'), (0x958, 'M', u'क़'), @@ -1118,7 +1115,7 @@ def _seg_10(): (0x9E0, 'V'), (0x9E4, 'X'), (0x9E6, 'V'), - (0x9FE, 'X'), + (0x9FF, 'X'), (0xA01, 'V'), (0xA04, 'X'), (0xA05, 'V'), @@ -1147,19 +1144,19 @@ def _seg_10(): (0xA4E, 'X'), (0xA51, 'V'), (0xA52, 'X'), + (0xA59, 'M', u'ਖ਼'), + (0xA5A, 'M', u'ਗ਼'), + (0xA5B, 'M', u'ਜ਼'), ] def _seg_11(): return [ - (0xA59, 'M', u'ਖ਼'), - (0xA5A, 'M', u'ਗ਼'), - (0xA5B, 'M', u'ਜ਼'), (0xA5C, 'V'), (0xA5D, 'X'), (0xA5E, 'M', u'ਫ਼'), (0xA5F, 'X'), (0xA66, 'V'), - (0xA76, 'X'), + (0xA77, 'X'), (0xA81, 'V'), (0xA84, 'X'), (0xA85, 'V'), @@ -1250,16 +1247,14 @@ def _seg_11(): (0xBE6, 'V'), (0xBFB, 'X'), (0xC00, 'V'), - (0xC04, 'X'), - ] - -def _seg_12(): - return [ - (0xC05, 'V'), (0xC0D, 'X'), (0xC0E, 'V'), (0xC11, 'X'), (0xC12, 'V'), + ] + +def _seg_12(): + return [ (0xC29, 'X'), (0xC2A, 'V'), (0xC3A, 'X'), @@ -1278,8 +1273,6 @@ def _seg_12(): (0xC66, 'V'), (0xC70, 'X'), (0xC78, 'V'), - (0xC84, 'X'), - (0xC85, 'V'), (0xC8D, 'X'), (0xC8E, 'V'), (0xC91, 'X'), @@ -1355,10 +1348,6 @@ def _seg_12(): (0xE83, 'X'), (0xE84, 'V'), (0xE85, 'X'), - ] - -def _seg_13(): - return [ (0xE87, 'V'), (0xE89, 'X'), (0xE8A, 'V'), @@ -1366,6 +1355,10 @@ def _seg_13(): (0xE8D, 'V'), (0xE8E, 'X'), (0xE94, 'V'), + ] + +def _seg_13(): + return [ (0xE98, 'X'), (0xE99, 'V'), (0xEA0, 'X'), @@ -1459,10 +1452,6 @@ def _seg_13(): (0x124E, 'X'), (0x1250, 'V'), (0x1257, 'X'), - ] - -def _seg_14(): - return [ (0x1258, 'V'), (0x1259, 'X'), (0x125A, 'V'), @@ -1470,6 +1459,10 @@ def _seg_14(): (0x1260, 'V'), (0x1289, 'X'), (0x128A, 'V'), + ] + +def _seg_14(): + return [ (0x128E, 'X'), (0x1290, 'V'), (0x12B1, 'X'), @@ -1538,7 +1531,7 @@ def _seg_14(): (0x1810, 'V'), (0x181A, 'X'), (0x1820, 'V'), - (0x1878, 'X'), + (0x1879, 'X'), (0x1880, 'V'), (0x18AB, 'X'), (0x18B0, 'V'), @@ -1563,10 +1556,6 @@ def _seg_14(): (0x19DB, 'X'), (0x19DE, 'V'), (0x1A1C, 'X'), - ] - -def _seg_15(): - return [ (0x1A1E, 'V'), (0x1A5F, 'X'), (0x1A60, 'V'), @@ -1574,6 +1563,10 @@ def _seg_15(): (0x1A7F, 'V'), (0x1A8A, 'X'), (0x1A90, 'V'), + ] + +def _seg_15(): + return [ (0x1A9A, 'X'), (0x1AA0, 'V'), (0x1AAE, 'X'), @@ -1667,10 +1660,6 @@ def _seg_15(): (0x1D68, 'M', u'ρ'), (0x1D69, 'M', u'φ'), (0x1D6A, 'M', u'χ'), - ] - -def _seg_16(): - return [ (0x1D6B, 'V'), (0x1D78, 'M', u'н'), (0x1D79, 'V'), @@ -1678,6 +1667,10 @@ def _seg_16(): (0x1D9C, 'M', u'c'), (0x1D9D, 'M', u'ɕ'), (0x1D9E, 'M', u'ð'), + ] + +def _seg_16(): + return [ (0x1D9F, 'M', u'ɜ'), (0x1DA0, 'M', u'f'), (0x1DA1, 'M', u'ɟ'), @@ -1771,10 +1764,6 @@ def _seg_16(): (0x1E36, 'M', u'ḷ'), (0x1E37, 'V'), (0x1E38, 'M', u'ḹ'), - ] - -def _seg_17(): - return [ (0x1E39, 'V'), (0x1E3A, 'M', u'ḻ'), (0x1E3B, 'V'), @@ -1782,6 +1771,10 @@ def _seg_17(): (0x1E3D, 'V'), (0x1E3E, 'M', u'ḿ'), (0x1E3F, 'V'), + ] + +def _seg_17(): + return [ (0x1E40, 'M', u'ṁ'), (0x1E41, 'V'), (0x1E42, 'M', u'ṃ'), @@ -1875,10 +1868,6 @@ def _seg_17(): (0x1E9F, 'V'), (0x1EA0, 'M', u'ạ'), (0x1EA1, 'V'), - ] - -def _seg_18(): - return [ (0x1EA2, 'M', u'ả'), (0x1EA3, 'V'), (0x1EA4, 'M', u'ấ'), @@ -1886,6 +1875,10 @@ def _seg_18(): (0x1EA6, 'M', u'ầ'), (0x1EA7, 'V'), (0x1EA8, 'M', u'ẩ'), + ] + +def _seg_18(): + return [ (0x1EA9, 'V'), (0x1EAA, 'M', u'ẫ'), (0x1EAB, 'V'), @@ -1979,10 +1972,6 @@ def _seg_18(): (0x1F0B, 'M', u'ἃ'), (0x1F0C, 'M', u'ἄ'), (0x1F0D, 'M', u'ἅ'), - ] - -def _seg_19(): - return [ (0x1F0E, 'M', u'ἆ'), (0x1F0F, 'M', u'ἇ'), (0x1F10, 'V'), @@ -1990,6 +1979,10 @@ def _seg_19(): (0x1F18, 'M', u'ἐ'), (0x1F19, 'M', u'ἑ'), (0x1F1A, 'M', u'ἒ'), + ] + +def _seg_19(): + return [ (0x1F1B, 'M', u'ἓ'), (0x1F1C, 'M', u'ἔ'), (0x1F1D, 'M', u'ἕ'), @@ -2083,10 +2076,6 @@ def _seg_19(): (0x1F9A, 'M', u'ἢι'), (0x1F9B, 'M', u'ἣι'), (0x1F9C, 'M', u'ἤι'), - ] - -def _seg_20(): - return [ (0x1F9D, 'M', u'ἥι'), (0x1F9E, 'M', u'ἦι'), (0x1F9F, 'M', u'ἧι'), @@ -2094,6 +2083,10 @@ def _seg_20(): (0x1FA1, 'M', u'ὡι'), (0x1FA2, 'M', u'ὢι'), (0x1FA3, 'M', u'ὣι'), + ] + +def _seg_20(): + return [ (0x1FA4, 'M', u'ὤι'), (0x1FA5, 'M', u'ὥι'), (0x1FA6, 'M', u'ὦι'), @@ -2187,10 +2180,6 @@ def _seg_20(): (0x2024, 'X'), (0x2027, 'V'), (0x2028, 'X'), - ] - -def _seg_21(): - return [ (0x202F, '3', u' '), (0x2030, 'V'), (0x2033, 'M', u'′′'), @@ -2198,6 +2187,10 @@ def _seg_21(): (0x2035, 'V'), (0x2036, 'M', u'‵‵'), (0x2037, 'M', u'‵‵‵'), + ] + +def _seg_21(): + return [ (0x2038, 'V'), (0x203C, '3', u'!!'), (0x203D, 'V'), @@ -2291,10 +2284,6 @@ def _seg_21(): (0x2120, 'M', u'sm'), (0x2121, 'M', u'tel'), (0x2122, 'M', u'tm'), - ] - -def _seg_22(): - return [ (0x2123, 'V'), (0x2124, 'M', u'z'), (0x2125, 'V'), @@ -2302,6 +2291,10 @@ def _seg_22(): (0x2127, 'V'), (0x2128, 'M', u'z'), (0x2129, 'V'), + ] + +def _seg_22(): + return [ (0x212A, 'M', u'k'), (0x212B, 'M', u'å'), (0x212C, 'M', u'b'), @@ -2395,10 +2388,6 @@ def _seg_22(): (0x226E, '3'), (0x2270, 'V'), (0x2329, 'M', u'〈'), - ] - -def _seg_23(): - return [ (0x232A, 'M', u'〉'), (0x232B, 'V'), (0x2427, 'X'), @@ -2406,6 +2395,10 @@ def _seg_23(): (0x244B, 'X'), (0x2460, 'M', u'1'), (0x2461, 'M', u'2'), + ] + +def _seg_23(): + return [ (0x2462, 'M', u'3'), (0x2463, 'M', u'4'), (0x2464, 'M', u'5'), @@ -2499,10 +2492,6 @@ def _seg_23(): (0x24CF, 'M', u'z'), (0x24D0, 'M', u'a'), (0x24D1, 'M', u'b'), - ] - -def _seg_24(): - return [ (0x24D2, 'M', u'c'), (0x24D3, 'M', u'd'), (0x24D4, 'M', u'e'), @@ -2510,6 +2499,10 @@ def _seg_24(): (0x24D6, 'M', u'g'), (0x24D7, 'M', u'h'), (0x24D8, 'M', u'i'), + ] + +def _seg_24(): + return [ (0x24D9, 'M', u'j'), (0x24DA, 'M', u'k'), (0x24DB, 'M', u'l'), @@ -2541,13 +2534,9 @@ def _seg_24(): (0x2B76, 'V'), (0x2B96, 'X'), (0x2B98, 'V'), - (0x2BBA, 'X'), - (0x2BBD, 'V'), (0x2BC9, 'X'), (0x2BCA, 'V'), - (0x2BD3, 'X'), - (0x2BEC, 'V'), - (0x2BF0, 'X'), + (0x2BFF, 'X'), (0x2C00, 'M', u'ⰰ'), (0x2C01, 'M', u'ⰱ'), (0x2C02, 'M', u'ⰲ'), @@ -2603,10 +2592,6 @@ def _seg_24(): (0x2C62, 'M', u'ɫ'), (0x2C63, 'M', u'ᵽ'), (0x2C64, 'M', u'ɽ'), - ] - -def _seg_25(): - return [ (0x2C65, 'V'), (0x2C67, 'M', u'ⱨ'), (0x2C68, 'V'), @@ -2618,6 +2603,10 @@ def _seg_25(): (0x2C6E, 'M', u'ɱ'), (0x2C6F, 'M', u'ɐ'), (0x2C70, 'M', u'ɒ'), + ] + +def _seg_25(): + return [ (0x2C71, 'V'), (0x2C72, 'M', u'ⱳ'), (0x2C73, 'V'), @@ -2707,10 +2696,6 @@ def _seg_25(): (0x2CCD, 'V'), (0x2CCE, 'M', u'ⳏ'), (0x2CCF, 'V'), - ] - -def _seg_26(): - return [ (0x2CD0, 'M', u'ⳑ'), (0x2CD1, 'V'), (0x2CD2, 'M', u'ⳓ'), @@ -2722,6 +2707,10 @@ def _seg_26(): (0x2CD8, 'M', u'ⳙ'), (0x2CD9, 'V'), (0x2CDA, 'M', u'ⳛ'), + ] + +def _seg_26(): + return [ (0x2CDB, 'V'), (0x2CDC, 'M', u'ⳝ'), (0x2CDD, 'V'), @@ -2768,7 +2757,7 @@ def _seg_26(): (0x2DD8, 'V'), (0x2DDF, 'X'), (0x2DE0, 'V'), - (0x2E4A, 'X'), + (0x2E4F, 'X'), (0x2E80, 'V'), (0x2E9A, 'X'), (0x2E9B, 'V'), @@ -2811,10 +2800,6 @@ def _seg_26(): (0x2F20, 'M', u'士'), (0x2F21, 'M', u'夂'), (0x2F22, 'M', u'夊'), - ] - -def _seg_27(): - return [ (0x2F23, 'M', u'夕'), (0x2F24, 'M', u'大'), (0x2F25, 'M', u'女'), @@ -2826,6 +2811,10 @@ def _seg_27(): (0x2F2B, 'M', u'尸'), (0x2F2C, 'M', u'屮'), (0x2F2D, 'M', u'山'), + ] + +def _seg_27(): + return [ (0x2F2E, 'M', u'巛'), (0x2F2F, 'M', u'工'), (0x2F30, 'M', u'己'), @@ -2915,10 +2904,6 @@ def _seg_27(): (0x2F84, 'M', u'至'), (0x2F85, 'M', u'臼'), (0x2F86, 'M', u'舌'), - ] - -def _seg_28(): - return [ (0x2F87, 'M', u'舛'), (0x2F88, 'M', u'舟'), (0x2F89, 'M', u'艮'), @@ -2930,6 +2915,10 @@ def _seg_28(): (0x2F8F, 'M', u'行'), (0x2F90, 'M', u'衣'), (0x2F91, 'M', u'襾'), + ] + +def _seg_28(): + return [ (0x2F92, 'M', u'見'), (0x2F93, 'M', u'角'), (0x2F94, 'M', u'言'), @@ -3019,13 +3008,9 @@ def _seg_28(): (0x309F, 'M', u'より'), (0x30A0, 'V'), (0x30FF, 'M', u'コト'), - ] - -def _seg_29(): - return [ (0x3100, 'X'), (0x3105, 'V'), - (0x312F, 'X'), + (0x3130, 'X'), (0x3131, 'M', u'ᄀ'), (0x3132, 'M', u'ᄁ'), (0x3133, 'M', u'ᆪ'), @@ -3034,6 +3019,10 @@ def _seg_29(): (0x3136, 'M', u'ᆭ'), (0x3137, 'M', u'ᄃ'), (0x3138, 'M', u'ᄄ'), + ] + +def _seg_29(): + return [ (0x3139, 'M', u'ᄅ'), (0x313A, 'M', u'ᆰ'), (0x313B, 'M', u'ᆱ'), @@ -3123,10 +3112,6 @@ def _seg_29(): (0x318F, 'X'), (0x3190, 'V'), (0x3192, 'M', u'一'), - ] - -def _seg_30(): - return [ (0x3193, 'M', u'二'), (0x3194, 'M', u'三'), (0x3195, 'M', u'四'), @@ -3138,6 +3123,10 @@ def _seg_30(): (0x319B, 'M', u'丙'), (0x319C, 'M', u'丁'), (0x319D, 'M', u'天'), + ] + +def _seg_30(): + return [ (0x319E, 'M', u'地'), (0x319F, 'M', u'人'), (0x31A0, 'V'), @@ -3227,10 +3216,6 @@ def _seg_30(): (0x3256, 'M', u'26'), (0x3257, 'M', u'27'), (0x3258, 'M', u'28'), - ] - -def _seg_31(): - return [ (0x3259, 'M', u'29'), (0x325A, 'M', u'30'), (0x325B, 'M', u'31'), @@ -3242,6 +3227,10 @@ def _seg_31(): (0x3261, 'M', u'ᄂ'), (0x3262, 'M', u'ᄃ'), (0x3263, 'M', u'ᄅ'), + ] + +def _seg_31(): + return [ (0x3264, 'M', u'ᄆ'), (0x3265, 'M', u'ᄇ'), (0x3266, 'M', u'ᄉ'), @@ -3331,10 +3320,6 @@ def _seg_31(): (0x32BA, 'M', u'45'), (0x32BB, 'M', u'46'), (0x32BC, 'M', u'47'), - ] - -def _seg_32(): - return [ (0x32BD, 'M', u'48'), (0x32BE, 'M', u'49'), (0x32BF, 'M', u'50'), @@ -3346,6 +3331,10 @@ def _seg_32(): (0x32C5, 'M', u'6月'), (0x32C6, 'M', u'7月'), (0x32C7, 'M', u'8月'), + ] + +def _seg_32(): + return [ (0x32C8, 'M', u'9月'), (0x32C9, 'M', u'10月'), (0x32CA, 'M', u'11月'), @@ -3435,10 +3424,6 @@ def _seg_32(): (0x331E, 'M', u'コーポ'), (0x331F, 'M', u'サイクル'), (0x3320, 'M', u'サンチーム'), - ] - -def _seg_33(): - return [ (0x3321, 'M', u'シリング'), (0x3322, 'M', u'センチ'), (0x3323, 'M', u'セント'), @@ -3450,6 +3435,10 @@ def _seg_33(): (0x3329, 'M', u'ノット'), (0x332A, 'M', u'ハイツ'), (0x332B, 'M', u'パーセント'), + ] + +def _seg_33(): + return [ (0x332C, 'M', u'パーツ'), (0x332D, 'M', u'バーレル'), (0x332E, 'M', u'ピアストル'), @@ -3539,10 +3528,6 @@ def _seg_33(): (0x3382, 'M', u'μa'), (0x3383, 'M', u'ma'), (0x3384, 'M', u'ka'), - ] - -def _seg_34(): - return [ (0x3385, 'M', u'kb'), (0x3386, 'M', u'mb'), (0x3387, 'M', u'gb'), @@ -3554,6 +3539,10 @@ def _seg_34(): (0x338D, 'M', u'μg'), (0x338E, 'M', u'mg'), (0x338F, 'M', u'kg'), + ] + +def _seg_34(): + return [ (0x3390, 'M', u'hz'), (0x3391, 'M', u'khz'), (0x3392, 'M', u'mhz'), @@ -3643,10 +3632,6 @@ def _seg_34(): (0x33E6, 'M', u'7日'), (0x33E7, 'M', u'8日'), (0x33E8, 'M', u'9日'), - ] - -def _seg_35(): - return [ (0x33E9, 'M', u'10日'), (0x33EA, 'M', u'11日'), (0x33EB, 'M', u'12日'), @@ -3658,6 +3643,10 @@ def _seg_35(): (0x33F1, 'M', u'18日'), (0x33F2, 'M', u'19日'), (0x33F3, 'M', u'20日'), + ] + +def _seg_35(): + return [ (0x33F4, 'M', u'21日'), (0x33F5, 'M', u'22日'), (0x33F6, 'M', u'23日'), @@ -3673,7 +3662,7 @@ def _seg_35(): (0x3400, 'V'), (0x4DB6, 'X'), (0x4DC0, 'V'), - (0x9FEB, 'X'), + (0x9FF0, 'X'), (0xA000, 'V'), (0xA48D, 'X'), (0xA490, 'V'), @@ -3747,10 +3736,6 @@ def _seg_35(): (0xA692, 'M', u'ꚓ'), (0xA693, 'V'), (0xA694, 'M', u'ꚕ'), - ] - -def _seg_36(): - return [ (0xA695, 'V'), (0xA696, 'M', u'ꚗ'), (0xA697, 'V'), @@ -3762,6 +3747,10 @@ def _seg_36(): (0xA69D, 'M', u'ь'), (0xA69E, 'V'), (0xA6F8, 'X'), + ] + +def _seg_36(): + return [ (0xA700, 'V'), (0xA722, 'M', u'ꜣ'), (0xA723, 'V'), @@ -3851,10 +3840,6 @@ def _seg_36(): (0xA780, 'M', u'ꞁ'), (0xA781, 'V'), (0xA782, 'M', u'ꞃ'), - ] - -def _seg_37(): - return [ (0xA783, 'V'), (0xA784, 'M', u'ꞅ'), (0xA785, 'V'), @@ -3866,6 +3851,10 @@ def _seg_37(): (0xA78E, 'V'), (0xA790, 'M', u'ꞑ'), (0xA791, 'V'), + ] + +def _seg_37(): + return [ (0xA792, 'M', u'ꞓ'), (0xA793, 'V'), (0xA796, 'M', u'ꞗ'), @@ -3893,7 +3882,7 @@ def _seg_37(): (0xA7AC, 'M', u'ɡ'), (0xA7AD, 'M', u'ɬ'), (0xA7AE, 'M', u'ɪ'), - (0xA7AF, 'X'), + (0xA7AF, 'V'), (0xA7B0, 'M', u'ʞ'), (0xA7B1, 'M', u'ʇ'), (0xA7B2, 'M', u'ʝ'), @@ -3903,6 +3892,8 @@ def _seg_37(): (0xA7B6, 'M', u'ꞷ'), (0xA7B7, 'V'), (0xA7B8, 'X'), + (0xA7B9, 'V'), + (0xA7BA, 'X'), (0xA7F7, 'V'), (0xA7F8, 'M', u'ħ'), (0xA7F9, 'M', u'œ'), @@ -3917,8 +3908,6 @@ def _seg_37(): (0xA8CE, 'V'), (0xA8DA, 'X'), (0xA8E0, 'V'), - (0xA8FE, 'X'), - (0xA900, 'V'), (0xA954, 'X'), (0xA95F, 'V'), (0xA97D, 'X'), @@ -3955,10 +3944,6 @@ def _seg_37(): (0xAB5F, 'M', u'ꭒ'), (0xAB60, 'V'), (0xAB66, 'X'), - ] - -def _seg_38(): - return [ (0xAB70, 'M', u'Ꭰ'), (0xAB71, 'M', u'Ꭱ'), (0xAB72, 'M', u'Ꭲ'), @@ -3970,6 +3955,10 @@ def _seg_38(): (0xAB78, 'M', u'Ꭸ'), (0xAB79, 'M', u'Ꭹ'), (0xAB7A, 'M', u'Ꭺ'), + ] + +def _seg_38(): + return [ (0xAB7B, 'M', u'Ꭻ'), (0xAB7C, 'M', u'Ꭼ'), (0xAB7D, 'M', u'Ꭽ'), @@ -4059,10 +4048,6 @@ def _seg_38(): (0xF907, 'M', u'龜'), (0xF909, 'M', u'契'), (0xF90A, 'M', u'金'), - ] - -def _seg_39(): - return [ (0xF90B, 'M', u'喇'), (0xF90C, 'M', u'奈'), (0xF90D, 'M', u'懶'), @@ -4074,6 +4059,10 @@ def _seg_39(): (0xF913, 'M', u'邏'), (0xF914, 'M', u'樂'), (0xF915, 'M', u'洛'), + ] + +def _seg_39(): + return [ (0xF916, 'M', u'烙'), (0xF917, 'M', u'珞'), (0xF918, 'M', u'落'), @@ -4163,10 +4152,6 @@ def _seg_39(): (0xF96C, 'M', u'塞'), (0xF96D, 'M', u'省'), (0xF96E, 'M', u'葉'), - ] - -def _seg_40(): - return [ (0xF96F, 'M', u'說'), (0xF970, 'M', u'殺'), (0xF971, 'M', u'辰'), @@ -4178,6 +4163,10 @@ def _seg_40(): (0xF977, 'M', u'亮'), (0xF978, 'M', u'兩'), (0xF979, 'M', u'凉'), + ] + +def _seg_40(): + return [ (0xF97A, 'M', u'梁'), (0xF97B, 'M', u'糧'), (0xF97C, 'M', u'良'), @@ -4267,10 +4256,6 @@ def _seg_40(): (0xF9D0, 'M', u'類'), (0xF9D1, 'M', u'六'), (0xF9D2, 'M', u'戮'), - ] - -def _seg_41(): - return [ (0xF9D3, 'M', u'陸'), (0xF9D4, 'M', u'倫'), (0xF9D5, 'M', u'崙'), @@ -4282,6 +4267,10 @@ def _seg_41(): (0xF9DB, 'M', u'率'), (0xF9DC, 'M', u'隆'), (0xF9DD, 'M', u'利'), + ] + +def _seg_41(): + return [ (0xF9DE, 'M', u'吏'), (0xF9DF, 'M', u'履'), (0xF9E0, 'M', u'易'), @@ -4371,10 +4360,6 @@ def _seg_41(): (0xFA39, 'M', u'塀'), (0xFA3A, 'M', u'墨'), (0xFA3B, 'M', u'層'), - ] - -def _seg_42(): - return [ (0xFA3C, 'M', u'屮'), (0xFA3D, 'M', u'悔'), (0xFA3E, 'M', u'慨'), @@ -4386,6 +4371,10 @@ def _seg_42(): (0xFA44, 'M', u'梅'), (0xFA45, 'M', u'海'), (0xFA46, 'M', u'渚'), + ] + +def _seg_42(): + return [ (0xFA47, 'M', u'漢'), (0xFA48, 'M', u'煮'), (0xFA49, 'M', u'爫'), @@ -4475,10 +4464,6 @@ def _seg_42(): (0xFA9F, 'M', u'犯'), (0xFAA0, 'M', u'猪'), (0xFAA1, 'M', u'瑱'), - ] - -def _seg_43(): - return [ (0xFAA2, 'M', u'甆'), (0xFAA3, 'M', u'画'), (0xFAA4, 'M', u'瘝'), @@ -4490,6 +4475,10 @@ def _seg_43(): (0xFAAA, 'M', u'着'), (0xFAAB, 'M', u'磌'), (0xFAAC, 'M', u'窱'), + ] + +def _seg_43(): + return [ (0xFAAD, 'M', u'節'), (0xFAAE, 'M', u'类'), (0xFAAF, 'M', u'絛'), @@ -4579,10 +4568,6 @@ def _seg_43(): (0xFB38, 'M', u'טּ'), (0xFB39, 'M', u'יּ'), (0xFB3A, 'M', u'ךּ'), - ] - -def _seg_44(): - return [ (0xFB3B, 'M', u'כּ'), (0xFB3C, 'M', u'לּ'), (0xFB3D, 'X'), @@ -4594,6 +4579,10 @@ def _seg_44(): (0xFB43, 'M', u'ףּ'), (0xFB44, 'M', u'פּ'), (0xFB45, 'X'), + ] + +def _seg_44(): + return [ (0xFB46, 'M', u'צּ'), (0xFB47, 'M', u'קּ'), (0xFB48, 'M', u'רּ'), @@ -4683,10 +4672,6 @@ def _seg_44(): (0xFC19, 'M', u'خج'), (0xFC1A, 'M', u'خح'), (0xFC1B, 'M', u'خم'), - ] - -def _seg_45(): - return [ (0xFC1C, 'M', u'سج'), (0xFC1D, 'M', u'سح'), (0xFC1E, 'M', u'سخ'), @@ -4698,6 +4683,10 @@ def _seg_45(): (0xFC24, 'M', u'ضخ'), (0xFC25, 'M', u'ضم'), (0xFC26, 'M', u'طح'), + ] + +def _seg_45(): + return [ (0xFC27, 'M', u'طم'), (0xFC28, 'M', u'ظم'), (0xFC29, 'M', u'عج'), @@ -4787,10 +4776,6 @@ def _seg_45(): (0xFC7D, 'M', u'في'), (0xFC7E, 'M', u'قى'), (0xFC7F, 'M', u'قي'), - ] - -def _seg_46(): - return [ (0xFC80, 'M', u'كا'), (0xFC81, 'M', u'كل'), (0xFC82, 'M', u'كم'), @@ -4802,6 +4787,10 @@ def _seg_46(): (0xFC88, 'M', u'ما'), (0xFC89, 'M', u'مم'), (0xFC8A, 'M', u'نر'), + ] + +def _seg_46(): + return [ (0xFC8B, 'M', u'نز'), (0xFC8C, 'M', u'نم'), (0xFC8D, 'M', u'نن'), @@ -4891,10 +4880,6 @@ def _seg_46(): (0xFCE1, 'M', u'بم'), (0xFCE2, 'M', u'به'), (0xFCE3, 'M', u'تم'), - ] - -def _seg_47(): - return [ (0xFCE4, 'M', u'ته'), (0xFCE5, 'M', u'ثم'), (0xFCE6, 'M', u'ثه'), @@ -4906,6 +4891,10 @@ def _seg_47(): (0xFCEC, 'M', u'كم'), (0xFCED, 'M', u'لم'), (0xFCEE, 'M', u'نم'), + ] + +def _seg_47(): + return [ (0xFCEF, 'M', u'نه'), (0xFCF0, 'M', u'يم'), (0xFCF1, 'M', u'يه'), @@ -4995,10 +4984,6 @@ def _seg_47(): (0xFD57, 'M', u'تمخ'), (0xFD58, 'M', u'جمح'), (0xFD5A, 'M', u'حمي'), - ] - -def _seg_48(): - return [ (0xFD5B, 'M', u'حمى'), (0xFD5C, 'M', u'سحج'), (0xFD5D, 'M', u'سجح'), @@ -5010,6 +4995,10 @@ def _seg_48(): (0xFD66, 'M', u'صمم'), (0xFD67, 'M', u'شحم'), (0xFD69, 'M', u'شجي'), + ] + +def _seg_48(): + return [ (0xFD6A, 'M', u'شمخ'), (0xFD6C, 'M', u'شمم'), (0xFD6E, 'M', u'ضحى'), @@ -5099,10 +5088,6 @@ def _seg_48(): (0xFDF3, 'M', u'اكبر'), (0xFDF4, 'M', u'محمد'), (0xFDF5, 'M', u'صلعم'), - ] - -def _seg_49(): - return [ (0xFDF6, 'M', u'رسول'), (0xFDF7, 'M', u'عليه'), (0xFDF8, 'M', u'وسلم'), @@ -5114,6 +5099,10 @@ def _seg_49(): (0xFDFE, 'X'), (0xFE00, 'I'), (0xFE10, '3', u','), + ] + +def _seg_49(): + return [ (0xFE11, 'M', u'、'), (0xFE12, 'X'), (0xFE13, '3', u':'), @@ -5203,10 +5192,6 @@ def _seg_49(): (0xFE8F, 'M', u'ب'), (0xFE93, 'M', u'ة'), (0xFE95, 'M', u'ت'), - ] - -def _seg_50(): - return [ (0xFE99, 'M', u'ث'), (0xFE9D, 'M', u'ج'), (0xFEA1, 'M', u'ح'), @@ -5218,6 +5203,10 @@ def _seg_50(): (0xFEB1, 'M', u'س'), (0xFEB5, 'M', u'ش'), (0xFEB9, 'M', u'ص'), + ] + +def _seg_50(): + return [ (0xFEBD, 'M', u'ض'), (0xFEC1, 'M', u'ط'), (0xFEC5, 'M', u'ظ'), @@ -5307,10 +5296,6 @@ def _seg_50(): (0xFF41, 'M', u'a'), (0xFF42, 'M', u'b'), (0xFF43, 'M', u'c'), - ] - -def _seg_51(): - return [ (0xFF44, 'M', u'd'), (0xFF45, 'M', u'e'), (0xFF46, 'M', u'f'), @@ -5322,6 +5307,10 @@ def _seg_51(): (0xFF4C, 'M', u'l'), (0xFF4D, 'M', u'm'), (0xFF4E, 'M', u'n'), + ] + +def _seg_51(): + return [ (0xFF4F, 'M', u'o'), (0xFF50, 'M', u'p'), (0xFF51, 'M', u'q'), @@ -5411,10 +5400,6 @@ def _seg_51(): (0xFFA5, 'M', u'ᆬ'), (0xFFA6, 'M', u'ᆭ'), (0xFFA7, 'M', u'ᄃ'), - ] - -def _seg_52(): - return [ (0xFFA8, 'M', u'ᄄ'), (0xFFA9, 'M', u'ᄅ'), (0xFFAA, 'M', u'ᆰ'), @@ -5426,6 +5411,10 @@ def _seg_52(): (0xFFB0, 'M', u'ᄚ'), (0xFFB1, 'M', u'ᄆ'), (0xFFB2, 'M', u'ᄇ'), + ] + +def _seg_52(): + return [ (0xFFB3, 'M', u'ᄈ'), (0xFFB4, 'M', u'ᄡ'), (0xFFB5, 'M', u'ᄉ'), @@ -5515,10 +5504,6 @@ def _seg_52(): (0x10300, 'V'), (0x10324, 'X'), (0x1032D, 'V'), - ] - -def _seg_53(): - return [ (0x1034B, 'X'), (0x10350, 'V'), (0x1037B, 'X'), @@ -5530,6 +5515,10 @@ def _seg_53(): (0x103D6, 'X'), (0x10400, 'M', u'𐐨'), (0x10401, 'M', u'𐐩'), + ] + +def _seg_53(): + return [ (0x10402, 'M', u'𐐪'), (0x10403, 'M', u'𐐫'), (0x10404, 'M', u'𐐬'), @@ -5619,10 +5608,6 @@ def _seg_53(): (0x10570, 'X'), (0x10600, 'V'), (0x10737, 'X'), - ] - -def _seg_54(): - return [ (0x10740, 'V'), (0x10756, 'X'), (0x10760, 'V'), @@ -5634,6 +5619,10 @@ def _seg_54(): (0x1080A, 'V'), (0x10836, 'X'), (0x10837, 'V'), + ] + +def _seg_54(): + return [ (0x10839, 'X'), (0x1083C, 'V'), (0x1083D, 'X'), @@ -5666,11 +5655,11 @@ def _seg_54(): (0x10A15, 'V'), (0x10A18, 'X'), (0x10A19, 'V'), - (0x10A34, 'X'), + (0x10A36, 'X'), (0x10A38, 'V'), (0x10A3B, 'X'), (0x10A3F, 'V'), - (0x10A48, 'X'), + (0x10A49, 'X'), (0x10A50, 'V'), (0x10A59, 'X'), (0x10A60, 'V'), @@ -5723,10 +5712,6 @@ def _seg_54(): (0x10C9B, 'M', u'𐳛'), (0x10C9C, 'M', u'𐳜'), (0x10C9D, 'M', u'𐳝'), - ] - -def _seg_55(): - return [ (0x10C9E, 'M', u'𐳞'), (0x10C9F, 'M', u'𐳟'), (0x10CA0, 'M', u'𐳠'), @@ -5738,6 +5723,10 @@ def _seg_55(): (0x10CA6, 'M', u'𐳦'), (0x10CA7, 'M', u'𐳧'), (0x10CA8, 'M', u'𐳨'), + ] + +def _seg_55(): + return [ (0x10CA9, 'M', u'𐳩'), (0x10CAA, 'M', u'𐳪'), (0x10CAB, 'M', u'𐳫'), @@ -5752,9 +5741,15 @@ def _seg_55(): (0x10CC0, 'V'), (0x10CF3, 'X'), (0x10CFA, 'V'), - (0x10D00, 'X'), + (0x10D28, 'X'), + (0x10D30, 'V'), + (0x10D3A, 'X'), (0x10E60, 'V'), (0x10E7F, 'X'), + (0x10F00, 'V'), + (0x10F28, 'X'), + (0x10F30, 'V'), + (0x10F5A, 'X'), (0x11000, 'V'), (0x1104E, 'X'), (0x11052, 'V'), @@ -5770,7 +5765,7 @@ def _seg_55(): (0x11100, 'V'), (0x11135, 'X'), (0x11136, 'V'), - (0x11144, 'X'), + (0x11147, 'X'), (0x11150, 'V'), (0x11177, 'X'), (0x11180, 'V'), @@ -5811,7 +5806,7 @@ def _seg_55(): (0x11334, 'X'), (0x11335, 'V'), (0x1133A, 'X'), - (0x1133C, 'V'), + (0x1133B, 'V'), (0x11345, 'X'), (0x11347, 'V'), (0x11349, 'X'), @@ -5827,16 +5822,16 @@ def _seg_55(): (0x1136D, 'X'), (0x11370, 'V'), (0x11375, 'X'), - ] - -def _seg_56(): - return [ (0x11400, 'V'), (0x1145A, 'X'), (0x1145B, 'V'), (0x1145C, 'X'), (0x1145D, 'V'), - (0x1145E, 'X'), + ] + +def _seg_56(): + return [ + (0x1145F, 'X'), (0x11480, 'V'), (0x114C8, 'X'), (0x114D0, 'V'), @@ -5856,11 +5851,13 @@ def _seg_56(): (0x116C0, 'V'), (0x116CA, 'X'), (0x11700, 'V'), - (0x1171A, 'X'), + (0x1171B, 'X'), (0x1171D, 'V'), (0x1172C, 'X'), (0x11730, 'V'), (0x11740, 'X'), + (0x11800, 'V'), + (0x1183C, 'X'), (0x118A0, 'M', u'𑣀'), (0x118A1, 'M', u'𑣁'), (0x118A2, 'M', u'𑣂'), @@ -5902,8 +5899,6 @@ def _seg_56(): (0x11A50, 'V'), (0x11A84, 'X'), (0x11A86, 'V'), - (0x11A9D, 'X'), - (0x11A9E, 'V'), (0x11AA3, 'X'), (0x11AC0, 'V'), (0x11AF9, 'X'), @@ -5931,14 +5926,28 @@ def _seg_56(): (0x11D3B, 'X'), (0x11D3C, 'V'), (0x11D3E, 'X'), - ] - -def _seg_57(): - return [ (0x11D3F, 'V'), (0x11D48, 'X'), (0x11D50, 'V'), (0x11D5A, 'X'), + (0x11D60, 'V'), + ] + +def _seg_57(): + return [ + (0x11D66, 'X'), + (0x11D67, 'V'), + (0x11D69, 'X'), + (0x11D6A, 'V'), + (0x11D8F, 'X'), + (0x11D90, 'V'), + (0x11D92, 'X'), + (0x11D93, 'V'), + (0x11D99, 'X'), + (0x11DA0, 'V'), + (0x11DAA, 'X'), + (0x11EE0, 'V'), + (0x11EF9, 'X'), (0x12000, 'V'), (0x1239A, 'X'), (0x12400, 'V'), @@ -5973,6 +5982,8 @@ def _seg_57(): (0x16B78, 'X'), (0x16B7D, 'V'), (0x16B90, 'X'), + (0x16E60, 'V'), + (0x16E9B, 'X'), (0x16F00, 'V'), (0x16F45, 'X'), (0x16F50, 'V'), @@ -5982,7 +5993,7 @@ def _seg_57(): (0x16FE0, 'V'), (0x16FE2, 'X'), (0x17000, 'V'), - (0x187ED, 'X'), + (0x187F2, 'X'), (0x18800, 'V'), (0x18AF3, 'X'), (0x1B000, 'V'), @@ -6024,21 +6035,23 @@ def _seg_57(): (0x1D1C1, 'V'), (0x1D1E9, 'X'), (0x1D200, 'V'), + ] + +def _seg_58(): + return [ (0x1D246, 'X'), + (0x1D2E0, 'V'), + (0x1D2F4, 'X'), (0x1D300, 'V'), (0x1D357, 'X'), (0x1D360, 'V'), - (0x1D372, 'X'), + (0x1D379, 'X'), (0x1D400, 'M', u'a'), (0x1D401, 'M', u'b'), (0x1D402, 'M', u'c'), (0x1D403, 'M', u'd'), (0x1D404, 'M', u'e'), (0x1D405, 'M', u'f'), - ] - -def _seg_58(): - return [ (0x1D406, 'M', u'g'), (0x1D407, 'M', u'h'), (0x1D408, 'M', u'i'), @@ -6126,6 +6139,10 @@ def _seg_58(): (0x1D45A, 'M', u'm'), (0x1D45B, 'M', u'n'), (0x1D45C, 'M', u'o'), + ] + +def _seg_59(): + return [ (0x1D45D, 'M', u'p'), (0x1D45E, 'M', u'q'), (0x1D45F, 'M', u'r'), @@ -6139,10 +6156,6 @@ def _seg_58(): (0x1D467, 'M', u'z'), (0x1D468, 'M', u'a'), (0x1D469, 'M', u'b'), - ] - -def _seg_59(): - return [ (0x1D46A, 'M', u'c'), (0x1D46B, 'M', u'd'), (0x1D46C, 'M', u'e'), @@ -6230,6 +6243,10 @@ def _seg_59(): (0x1D4C1, 'M', u'l'), (0x1D4C2, 'M', u'm'), (0x1D4C3, 'M', u'n'), + ] + +def _seg_60(): + return [ (0x1D4C4, 'X'), (0x1D4C5, 'M', u'p'), (0x1D4C6, 'M', u'q'), @@ -6243,10 +6260,6 @@ def _seg_59(): (0x1D4CE, 'M', u'y'), (0x1D4CF, 'M', u'z'), (0x1D4D0, 'M', u'a'), - ] - -def _seg_60(): - return [ (0x1D4D1, 'M', u'b'), (0x1D4D2, 'M', u'c'), (0x1D4D3, 'M', u'd'), @@ -6334,6 +6347,10 @@ def _seg_60(): (0x1D526, 'M', u'i'), (0x1D527, 'M', u'j'), (0x1D528, 'M', u'k'), + ] + +def _seg_61(): + return [ (0x1D529, 'M', u'l'), (0x1D52A, 'M', u'm'), (0x1D52B, 'M', u'n'), @@ -6347,10 +6364,6 @@ def _seg_60(): (0x1D533, 'M', u'v'), (0x1D534, 'M', u'w'), (0x1D535, 'M', u'x'), - ] - -def _seg_61(): - return [ (0x1D536, 'M', u'y'), (0x1D537, 'M', u'z'), (0x1D538, 'M', u'a'), @@ -6438,6 +6451,10 @@ def _seg_61(): (0x1D58C, 'M', u'g'), (0x1D58D, 'M', u'h'), (0x1D58E, 'M', u'i'), + ] + +def _seg_62(): + return [ (0x1D58F, 'M', u'j'), (0x1D590, 'M', u'k'), (0x1D591, 'M', u'l'), @@ -6451,10 +6468,6 @@ def _seg_61(): (0x1D599, 'M', u't'), (0x1D59A, 'M', u'u'), (0x1D59B, 'M', u'v'), - ] - -def _seg_62(): - return [ (0x1D59C, 'M', u'w'), (0x1D59D, 'M', u'x'), (0x1D59E, 'M', u'y'), @@ -6542,6 +6555,10 @@ def _seg_62(): (0x1D5F0, 'M', u'c'), (0x1D5F1, 'M', u'd'), (0x1D5F2, 'M', u'e'), + ] + +def _seg_63(): + return [ (0x1D5F3, 'M', u'f'), (0x1D5F4, 'M', u'g'), (0x1D5F5, 'M', u'h'), @@ -6555,10 +6572,6 @@ def _seg_62(): (0x1D5FD, 'M', u'p'), (0x1D5FE, 'M', u'q'), (0x1D5FF, 'M', u'r'), - ] - -def _seg_63(): - return [ (0x1D600, 'M', u's'), (0x1D601, 'M', u't'), (0x1D602, 'M', u'u'), @@ -6646,6 +6659,10 @@ def _seg_63(): (0x1D654, 'M', u'y'), (0x1D655, 'M', u'z'), (0x1D656, 'M', u'a'), + ] + +def _seg_64(): + return [ (0x1D657, 'M', u'b'), (0x1D658, 'M', u'c'), (0x1D659, 'M', u'd'), @@ -6659,10 +6676,6 @@ def _seg_63(): (0x1D661, 'M', u'l'), (0x1D662, 'M', u'm'), (0x1D663, 'M', u'n'), - ] - -def _seg_64(): - return [ (0x1D664, 'M', u'o'), (0x1D665, 'M', u'p'), (0x1D666, 'M', u'q'), @@ -6750,6 +6763,10 @@ def _seg_64(): (0x1D6B9, 'M', u'θ'), (0x1D6BA, 'M', u'σ'), (0x1D6BB, 'M', u'τ'), + ] + +def _seg_65(): + return [ (0x1D6BC, 'M', u'υ'), (0x1D6BD, 'M', u'φ'), (0x1D6BE, 'M', u'χ'), @@ -6763,10 +6780,6 @@ def _seg_64(): (0x1D6C6, 'M', u'ε'), (0x1D6C7, 'M', u'ζ'), (0x1D6C8, 'M', u'η'), - ] - -def _seg_65(): - return [ (0x1D6C9, 'M', u'θ'), (0x1D6CA, 'M', u'ι'), (0x1D6CB, 'M', u'κ'), @@ -6854,6 +6867,10 @@ def _seg_65(): (0x1D71F, 'M', u'δ'), (0x1D720, 'M', u'ε'), (0x1D721, 'M', u'ζ'), + ] + +def _seg_66(): + return [ (0x1D722, 'M', u'η'), (0x1D723, 'M', u'θ'), (0x1D724, 'M', u'ι'), @@ -6867,10 +6884,6 @@ def _seg_65(): (0x1D72C, 'M', u'ρ'), (0x1D72D, 'M', u'θ'), (0x1D72E, 'M', u'σ'), - ] - -def _seg_66(): - return [ (0x1D72F, 'M', u'τ'), (0x1D730, 'M', u'υ'), (0x1D731, 'M', u'φ'), @@ -6958,6 +6971,10 @@ def _seg_66(): (0x1D785, 'M', u'φ'), (0x1D786, 'M', u'χ'), (0x1D787, 'M', u'ψ'), + ] + +def _seg_67(): + return [ (0x1D788, 'M', u'ω'), (0x1D789, 'M', u'∂'), (0x1D78A, 'M', u'ε'), @@ -6971,10 +6988,6 @@ def _seg_66(): (0x1D792, 'M', u'γ'), (0x1D793, 'M', u'δ'), (0x1D794, 'M', u'ε'), - ] - -def _seg_67(): - return [ (0x1D795, 'M', u'ζ'), (0x1D796, 'M', u'η'), (0x1D797, 'M', u'θ'), @@ -7062,6 +7075,10 @@ def _seg_67(): (0x1D7EC, 'M', u'0'), (0x1D7ED, 'M', u'1'), (0x1D7EE, 'M', u'2'), + ] + +def _seg_68(): + return [ (0x1D7EF, 'M', u'3'), (0x1D7F0, 'M', u'4'), (0x1D7F1, 'M', u'5'), @@ -7075,10 +7092,6 @@ def _seg_67(): (0x1D7F9, 'M', u'3'), (0x1D7FA, 'M', u'4'), (0x1D7FB, 'M', u'5'), - ] - -def _seg_68(): - return [ (0x1D7FC, 'M', u'6'), (0x1D7FD, 'M', u'7'), (0x1D7FE, 'M', u'8'), @@ -7143,6 +7156,8 @@ def _seg_68(): (0x1E95A, 'X'), (0x1E95E, 'V'), (0x1E960, 'X'), + (0x1EC71, 'V'), + (0x1ECB5, 'X'), (0x1EE00, 'M', u'ا'), (0x1EE01, 'M', u'ب'), (0x1EE02, 'M', u'ج'), @@ -7164,6 +7179,10 @@ def _seg_68(): (0x1EE12, 'M', u'ق'), (0x1EE13, 'M', u'ر'), (0x1EE14, 'M', u'ش'), + ] + +def _seg_69(): + return [ (0x1EE15, 'M', u'ت'), (0x1EE16, 'M', u'ث'), (0x1EE17, 'M', u'خ'), @@ -7179,10 +7198,6 @@ def _seg_68(): (0x1EE21, 'M', u'ب'), (0x1EE22, 'M', u'ج'), (0x1EE23, 'X'), - ] - -def _seg_69(): - return [ (0x1EE24, 'M', u'ه'), (0x1EE25, 'X'), (0x1EE27, 'M', u'ح'), @@ -7268,6 +7283,10 @@ def _seg_69(): (0x1EE81, 'M', u'ب'), (0x1EE82, 'M', u'ج'), (0x1EE83, 'M', u'د'), + ] + +def _seg_70(): + return [ (0x1EE84, 'M', u'ه'), (0x1EE85, 'M', u'و'), (0x1EE86, 'M', u'ز'), @@ -7283,10 +7302,6 @@ def _seg_69(): (0x1EE90, 'M', u'ف'), (0x1EE91, 'M', u'ص'), (0x1EE92, 'M', u'ق'), - ] - -def _seg_70(): - return [ (0x1EE93, 'M', u'ر'), (0x1EE94, 'M', u'ش'), (0x1EE95, 'M', u'ت'), @@ -7372,6 +7387,10 @@ def _seg_70(): (0x1F122, '3', u'(s)'), (0x1F123, '3', u'(t)'), (0x1F124, '3', u'(u)'), + ] + +def _seg_71(): + return [ (0x1F125, '3', u'(v)'), (0x1F126, '3', u'(w)'), (0x1F127, '3', u'(x)'), @@ -7382,15 +7401,11 @@ def _seg_70(): (0x1F12C, 'M', u'r'), (0x1F12D, 'M', u'cd'), (0x1F12E, 'M', u'wz'), - (0x1F12F, 'X'), + (0x1F12F, 'V'), (0x1F130, 'M', u'a'), (0x1F131, 'M', u'b'), (0x1F132, 'M', u'c'), (0x1F133, 'M', u'd'), - ] - -def _seg_71(): - return [ (0x1F134, 'M', u'e'), (0x1F135, 'M', u'f'), (0x1F136, 'M', u'g'), @@ -7476,6 +7491,10 @@ def _seg_71(): (0x1F239, 'M', u'割'), (0x1F23A, 'M', u'営'), (0x1F23B, 'M', u'配'), + ] + +def _seg_72(): + return [ (0x1F23C, 'X'), (0x1F240, 'M', u'〔本〕'), (0x1F241, 'M', u'〔三〕'), @@ -7491,21 +7510,17 @@ def _seg_71(): (0x1F251, 'M', u'可'), (0x1F252, 'X'), (0x1F260, 'V'), - ] - -def _seg_72(): - return [ (0x1F266, 'X'), (0x1F300, 'V'), (0x1F6D5, 'X'), (0x1F6E0, 'V'), (0x1F6ED, 'X'), (0x1F6F0, 'V'), - (0x1F6F9, 'X'), + (0x1F6FA, 'X'), (0x1F700, 'V'), (0x1F774, 'X'), (0x1F780, 'V'), - (0x1F7D5, 'X'), + (0x1F7D9, 'X'), (0x1F800, 'V'), (0x1F80C, 'X'), (0x1F810, 'V'), @@ -7521,15 +7536,21 @@ def _seg_72(): (0x1F910, 'V'), (0x1F93F, 'X'), (0x1F940, 'V'), - (0x1F94D, 'X'), - (0x1F950, 'V'), - (0x1F96C, 'X'), - (0x1F980, 'V'), - (0x1F998, 'X'), + (0x1F971, 'X'), + (0x1F973, 'V'), + (0x1F977, 'X'), + (0x1F97A, 'V'), + (0x1F97B, 'X'), + (0x1F97C, 'V'), + (0x1F9A3, 'X'), + (0x1F9B0, 'V'), + (0x1F9BA, 'X'), (0x1F9C0, 'V'), - (0x1F9C1, 'X'), + (0x1F9C3, 'X'), (0x1F9D0, 'V'), - (0x1F9E7, 'X'), + (0x1FA00, 'X'), + (0x1FA60, 'V'), + (0x1FA6E, 'X'), (0x20000, 'V'), (0x2A6D7, 'X'), (0x2A700, 'V'), @@ -7574,6 +7595,10 @@ def _seg_72(): (0x2F81F, 'M', u'㓟'), (0x2F820, 'M', u'刻'), (0x2F821, 'M', u'剆'), + ] + +def _seg_73(): + return [ (0x2F822, 'M', u'割'), (0x2F823, 'M', u'剷'), (0x2F824, 'M', u'㔕'), @@ -7595,10 +7620,6 @@ def _seg_72(): (0x2F836, 'M', u'及'), (0x2F837, 'M', u'叟'), (0x2F838, 'M', u'𠭣'), - ] - -def _seg_73(): - return [ (0x2F839, 'M', u'叫'), (0x2F83A, 'M', u'叱'), (0x2F83B, 'M', u'吆'), @@ -7678,6 +7699,10 @@ def _seg_73(): (0x2F887, 'M', u'幩'), (0x2F888, 'M', u'㡢'), (0x2F889, 'M', u'𢆃'), + ] + +def _seg_74(): + return [ (0x2F88A, 'M', u'㡼'), (0x2F88B, 'M', u'庰'), (0x2F88C, 'M', u'庳'), @@ -7699,10 +7724,6 @@ def _seg_73(): (0x2F89E, 'M', u'志'), (0x2F89F, 'M', u'忹'), (0x2F8A0, 'M', u'悁'), - ] - -def _seg_74(): - return [ (0x2F8A1, 'M', u'㤺'), (0x2F8A2, 'M', u'㤜'), (0x2F8A3, 'M', u'悔'), @@ -7782,6 +7803,10 @@ def _seg_74(): (0x2F8ED, 'M', u'櫛'), (0x2F8EE, 'M', u'㰘'), (0x2F8EF, 'M', u'次'), + ] + +def _seg_75(): + return [ (0x2F8F0, 'M', u'𣢧'), (0x2F8F1, 'M', u'歔'), (0x2F8F2, 'M', u'㱎'), @@ -7803,10 +7828,6 @@ def _seg_74(): (0x2F902, 'M', u'流'), (0x2F903, 'M', u'浩'), (0x2F904, 'M', u'浸'), - ] - -def _seg_75(): - return [ (0x2F905, 'M', u'涅'), (0x2F906, 'M', u'𣴞'), (0x2F907, 'M', u'洴'), @@ -7886,6 +7907,10 @@ def _seg_75(): (0x2F953, 'M', u'祖'), (0x2F954, 'M', u'𥚚'), (0x2F955, 'M', u'𥛅'), + ] + +def _seg_76(): + return [ (0x2F956, 'M', u'福'), (0x2F957, 'M', u'秫'), (0x2F958, 'M', u'䄯'), @@ -7907,10 +7932,6 @@ def _seg_75(): (0x2F969, 'M', u'糣'), (0x2F96A, 'M', u'紀'), (0x2F96B, 'M', u'𥾆'), - ] - -def _seg_76(): - return [ (0x2F96C, 'M', u'絣'), (0x2F96D, 'M', u'䌁'), (0x2F96E, 'M', u'緇'), @@ -7990,6 +8011,10 @@ def _seg_76(): (0x2F9B8, 'M', u'蚈'), (0x2F9B9, 'M', u'蜎'), (0x2F9BA, 'M', u'蛢'), + ] + +def _seg_77(): + return [ (0x2F9BB, 'M', u'蝹'), (0x2F9BC, 'M', u'蜨'), (0x2F9BD, 'M', u'蝫'), @@ -8011,10 +8036,6 @@ def _seg_76(): (0x2F9CD, 'M', u'䚾'), (0x2F9CE, 'M', u'䛇'), (0x2F9CF, 'M', u'誠'), - ] - -def _seg_77(): - return [ (0x2F9D0, 'M', u'諭'), (0x2F9D1, 'M', u'變'), (0x2F9D2, 'M', u'豕'), @@ -8094,6 +8115,10 @@ def _seg_77(): (0x2FA1D, 'M', u'𪘀'), (0x2FA1E, 'X'), (0xE0100, 'I'), + ] + +def _seg_78(): + return [ (0xE01F0, 'X'), ] @@ -8176,4 +8201,5 @@ def _seg_77(): + _seg_75() + _seg_76() + _seg_77() + + _seg_78() ) diff --git a/ext/jsonrpclib/SimpleJSONRPCServer.py b/ext/jsonrpclib/SimpleJSONRPCServer.py index 10b90947b9..d09ff165dd 100644 --- a/ext/jsonrpclib/SimpleJSONRPCServer.py +++ b/ext/jsonrpclib/SimpleJSONRPCServer.py @@ -5,13 +5,13 @@ CGI request handler. :authors: Josh Marshall, Thomas Calmant -:copyright: Copyright 2018, Thomas Calmant +:copyright: Copyright 2019, Thomas Calmant :license: Apache License 2.0 -:version: 0.3.2 +:version: 0.4.0 .. - Copyright 2018 Thomas Calmant + Copyright 2019 Thomas Calmant Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -26,6 +26,9 @@ limitations under the License. """ +# We use print() in the CGI request handler +from __future__ import print_function + # Standard library import logging import socket @@ -41,6 +44,7 @@ # variant of this package. SimpleXMLRPCDispatcher = xmlrpcserver.SimpleXMLRPCDispatcher SimpleXMLRPCRequestHandler = xmlrpcserver.SimpleXMLRPCRequestHandler + CGIXMLRPCRequestHandler = xmlrpcserver.CGIXMLRPCRequestHandler resolve_dotted_attribute = xmlrpcserver.resolve_dotted_attribute import socketserver except (ImportError, AttributeError): @@ -49,6 +53,7 @@ import SimpleXMLRPCServer as xmlrpcserver SimpleXMLRPCDispatcher = xmlrpcserver.SimpleXMLRPCDispatcher SimpleXMLRPCRequestHandler = xmlrpcserver.SimpleXMLRPCRequestHandler + CGIXMLRPCRequestHandler = xmlrpcserver.CGIXMLRPCRequestHandler resolve_dotted_attribute = xmlrpcserver.resolve_dotted_attribute import SocketServer as socketserver @@ -60,6 +65,13 @@ # pylint: disable=C0103 fcntl = None +try: + # Python with support for Unix socket + _AF_UNIX = socket.AF_UNIX +except AttributeError: + # Unix sockets are not supported, use a dummy value + _AF_UNIX = -1 + # Local modules from jsonrpclib import Fault import jsonrpclib.config @@ -69,7 +81,7 @@ # ------------------------------------------------------------------------------ # Module version -__version_info__ = (0, 3, 2) +__version_info__ = (0, 4, 0) __version__ = ".".join(str(x) for x in __version_info__) # Documentation strings format @@ -385,8 +397,9 @@ def _dispatch(self, method, params, config=None): except: # Method exception err_lines = traceback.format_exception(*sys.exc_info()) - trace_string = '{0} | {1}'.format(err_lines[-2].splitlines()[0].strip(), err_lines[-1]) - fault = Fault(-32603, 'Server error: {0}'.format(trace_string), + trace_string = "{0} | {1}".format( + err_lines[-2].splitlines()[0].strip(), err_lines[-1]) + fault = Fault(-32603, "Server error: {0}".format(trace_string), config=config) _logger.exception("Server-side exception: %s", fault) return fault @@ -452,8 +465,9 @@ def do_POST(self): # Exception: send 500 Server Error self.send_response(500) err_lines = traceback.format_exception(*sys.exc_info()) - trace_string = '{0} | {1}'.format(err_lines[-2].splitlines()[0].strip(), err_lines[-1]) - fault = jsonrpclib.Fault(-32603, 'Server error: {0}' + trace_string = "{0} | {1}".format( + err_lines[-2].splitlines()[0].strip(), err_lines[-1]) + fault = jsonrpclib.Fault(-32603, "Server error: {0}" .format(trace_string), config=config) _logger.exception("Server-side error: %s", fault) response = fault.response() @@ -501,12 +515,22 @@ def __init__(self, addr, requestHandler=SimpleJSONRPCRequestHandler, # Set up the dispatcher fields SimpleJSONRPCDispatcher.__init__(self, encoding, config) + # Flag to ease handling of Unix socket mode + unix_socket = address_family == _AF_UNIX + + # Disable the reuse address flag when in Unix socket mode, or an + # exception will raise when binding the socket + self.allow_reuse_address = self.allow_reuse_address and not unix_socket + # Prepare the server configuration - # logRequests is used by SimpleXMLRPCRequestHandler - self.logRequests = logRequests self.address_family = address_family self.json_config = config + # logRequests is used by SimpleXMLRPCRequestHandler + # This must be disabled in Unix socket mode (or an exception will raise + # at each connection) + self.logRequests = logRequests and not unix_socket + # Work on the request handler class RequestHandlerWrapper(requestHandler, object): """ @@ -517,10 +541,16 @@ def __init__(self, *args, **kwargs): Constructs the wrapper after having stored the configuration """ self.config = config + + if unix_socket: + # Disable TCP features over Unix socket, or an + # "invalid argument" error will raise + self.disable_nagle_algorithm = False + super(RequestHandlerWrapper, self).__init__(*args, **kwargs) # Set up the server - socketserver.TCPServer.__init__(self, addr, requestHandler, + socketserver.TCPServer.__init__(self, addr, RequestHandlerWrapper, bind_and_activate) # Windows-specific @@ -585,11 +615,11 @@ def server_close(self): # ------------------------------------------------------------------------------ -class CGIJSONRPCRequestHandler(SimpleJSONRPCDispatcher): +class CGIJSONRPCRequestHandler(SimpleJSONRPCDispatcher, CGIXMLRPCRequestHandler): """ JSON-RPC CGI handler (and dispatcher) """ - def __init__(self, encoding=None, config=jsonrpclib.config.DEFAULT): + def __init__(self, encoding="UTF-8", config=jsonrpclib.config.DEFAULT): """ Sets up the dispatcher @@ -597,17 +627,25 @@ def __init__(self, encoding=None, config=jsonrpclib.config.DEFAULT): :param config: A JSONRPClib Config instance """ SimpleJSONRPCDispatcher.__init__(self, encoding, config) + CGIXMLRPCRequestHandler.__init__(self, encoding=encoding) def handle_jsonrpc(self, request_text): """ Handle a JSON-RPC request """ + try: + writer = sys.stdout.buffer + except AttributeError: + writer = sys.stdout + response = self._marshaled_dispatch(request_text) - sys.stdout.write('Content-Type: {0}\r\n' - .format(self.json_config.content_type)) - sys.stdout.write('Content-Length: {0:d}\r\n'.format(len(response))) - sys.stdout.write('\r\n') - sys.stdout.write(response) + response = response.encode(self.encoding) + print("Content-Type:", self.json_config.content_type) + print("Content-Length:", len(response)) + print() + sys.stdout.flush() + writer.write(response) + writer.flush() # XML-RPC alias handle_xmlrpc = handle_jsonrpc diff --git a/ext/jsonrpclib/__init__.py b/ext/jsonrpclib/__init__.py index a178e8bb25..2a547dec42 100644 --- a/ext/jsonrpclib/__init__.py +++ b/ext/jsonrpclib/__init__.py @@ -4,13 +4,13 @@ Aliases to ease access to jsonrpclib classes :authors: Josh Marshall, Thomas Calmant -:copyright: Copyright 2018, Thomas Calmant +:copyright: Copyright 2019, Thomas Calmant :license: Apache License 2.0 -:version: 0.3.2 +:version: 0.4.0 .. - Copyright 2018 Thomas Calmant + Copyright 2019 Thomas Calmant Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -37,7 +37,7 @@ # Module version -__version_info__ = (0, 3, 2) +__version_info__ = (0, 4, 0) __version__ = ".".join(str(x) for x in __version_info__) # Documentation strings format diff --git a/ext/jsonrpclib/config.py b/ext/jsonrpclib/config.py index b681ad793d..b61533f0e1 100644 --- a/ext/jsonrpclib/config.py +++ b/ext/jsonrpclib/config.py @@ -3,13 +3,13 @@ """ The configuration module. -:copyright: Copyright 2018, Thomas Calmant +:copyright: Copyright 2019, Thomas Calmant :license: Apache License 2.0 -:version: 0.3.2 +:version: 0.4.0 .. - Copyright 2018 Thomas Calmant + Copyright 2019 Thomas Calmant Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ # ------------------------------------------------------------------------------ # Module version -__version_info__ = (0, 3, 2) +__version_info__ = (0, 4, 0) __version__ = ".".join(str(x) for x in __version_info__) # Documentation strings format diff --git a/ext/jsonrpclib/history.py b/ext/jsonrpclib/history.py index 0773799eb2..363b823a3f 100644 --- a/ext/jsonrpclib/history.py +++ b/ext/jsonrpclib/history.py @@ -4,13 +4,13 @@ The history module. :authors: Josh Marshall, Thomas Calmant -:copyright: Copyright 2018, Thomas Calmant +:copyright: Copyright 2019, Thomas Calmant :license: Apache License 2.0 -:version: 0.3.2 +:version: 0.4.0 .. - Copyright 2018 Thomas Calmant + Copyright 2019 Thomas Calmant Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ """ # Module version -__version_info__ = (0, 3, 2) +__version_info__ = (0, 4, 0) __version__ = ".".join(str(x) for x in __version_info__) # Documentation strings format diff --git a/ext/jsonrpclib/jsonclass.py b/ext/jsonrpclib/jsonclass.py index 2aed0fd724..608a834759 100644 --- a/ext/jsonrpclib/jsonclass.py +++ b/ext/jsonrpclib/jsonclass.py @@ -4,13 +4,13 @@ The serialization module :authors: Josh Marshall, Thomas Calmant -:copyright: Copyright 2018, Thomas Calmant +:copyright: Copyright 2019, Thomas Calmant :license: Apache License 2.0 -:version: 0.3.2 +:version: 0.4.0 .. - Copyright 2018 Thomas Calmant + Copyright 2019 Thomas Calmant Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ # ------------------------------------------------------------------------------ # Module version -__version_info__ = (0, 3, 2) +__version_info__ = (0, 4, 0) __version__ = ".".join(str(x) for x in __version_info__) # Documentation strings format diff --git a/ext/jsonrpclib/jsonrpc.py b/ext/jsonrpclib/jsonrpc.py index 6e2f3127df..484aec317f 100644 --- a/ext/jsonrpclib/jsonrpc.py +++ b/ext/jsonrpclib/jsonrpc.py @@ -36,13 +36,13 @@ See https://github.com/tcalmant/jsonrpclib for more info. :authors: Josh Marshall, Thomas Calmant -:copyright: Copyright 2018, Thomas Calmant +:copyright: Copyright 2019, Thomas Calmant :license: Apache License 2.0 -:version: 0.3.2 +:version: 0.4.0 .. - Copyright 2018 Thomas Calmant + Copyright 2019 Thomas Calmant Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -60,12 +60,15 @@ # Standard library import contextlib import logging +import os +import socket import sys import uuid try: # Python 3 # pylint: disable=F0401,E0611 + from http.client import HTTPConnection from urllib.parse import splittype, splithost from xmlrpc.client import Transport as XMLTransport from xmlrpc.client import SafeTransport as XMLSafeTransport @@ -74,6 +77,7 @@ except ImportError: # Python 2 # pylint: disable=F0401,E0611 + from httplib import HTTPConnection from urllib import splittype, splithost from xmlrpclib import Transport as XMLTransport from xmlrpclib import SafeTransport as XMLSafeTransport @@ -96,7 +100,7 @@ # ------------------------------------------------------------------------------ # Module version -__version_info__ = (0, 3, 2) +__version_info__ = (0, 4, 0) __version__ = ".".join(str(x) for x in __version_info__) # Documentation strings format @@ -461,7 +465,79 @@ class SafeTransport(TransportMixIn, XMLSafeTransport): """ def __init__(self, config, context): TransportMixIn.__init__(self, config, context) - XMLSafeTransport.__init__(self) + try: + # Give the context to XMLSafeTransport, to avoid it setting the + # context to None. + # See https://github.com/tcalmant/jsonrpclib/issues/39 + XMLSafeTransport.__init__(self, context=context) + except TypeError: + # On old versions of Python (Pre-2014), the context argument + # wasn't available + XMLSafeTransport.__init__(self) + +# ------------------------------------------------------------------------------ + + +class UnixHTTPConnection(HTTPConnection): + """ + Replaces the connect() method of HTTPConnection to use a Unix socket + """ + def __init__(self, path, *args, **kwargs): + """ + Constructs the HTTP connection. + + Forwards all given arguments except ``path`` to the constructor of + HTTPConnection + + :param path: Path to the Unix socket + """ + HTTPConnection.__init__(self, path, *args, **kwargs) + self.path = path + + def connect(self): + """ + Connects to the described server + """ + self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self.sock.connect(self.path) + + +class UnixTransport(TransportMixIn, XMLTransport): + """ + Mixed-in HTTP transport over a UNIX socket + """ + def __init__(self, config, path=None): + """ + :param config: The jsonrpclib configuration + :param path: Path to the Unix socket (overrides the host name later) + """ + TransportMixIn.__init__(self, config) + XMLTransport.__init__(self) + # Keep track of the given path, if any + self.__unix_path = os.path.abspath(path) if path else None + + def make_connection(self, host): + """ + Connect to server. + + Return an existing connection if possible. + This allows HTTP/1.1 keep-alive. + + Code copied from xmlrpc.client (Python 3) + + :param host: Target host (ignored if a path was given) + :return A UnixHTTPConnection object + """ + if self.__unix_path: + host = self.__unix_path + + if self._connection and host == self._connection[0]: + return self._connection[1] + + # create a HTTP connection object from a host descriptor + path, self._extra_headers, _ = self.get_host_info(host) + self._connection = host, UnixHTTPConnection(path) + return self._connection[1] # ------------------------------------------------------------------------------ @@ -492,21 +568,43 @@ def __init__(self, uri, transport=None, encoding=None, self.__version = version or config.version schema, uri = splittype(uri) + use_unix = False + if schema.startswith("unix+"): + schema = schema[len("unix+"):] + use_unix = True + if schema not in ('http', 'https'): _logger.error("jsonrpclib only support http(s) URIs, not %s", schema) raise IOError('Unsupported JSON-RPC protocol.') self.__host, self.__handler = splithost(uri) - if not self.__handler: + if use_unix: + unix_path = self.__handler + self.__handler = '/' + elif not self.__handler: # Not sure if this is in the JSON spec? self.__handler = '/' if transport is None: - if schema == 'https': + if use_unix: + if schema == "http": + # In Unix mode, we use the path part of the URL (handler) + # as the path to the socket file + transport = UnixTransport( + config=config, path=unix_path + ) + elif schema == 'https': transport = SafeTransport(config=config, context=context) else: transport = Transport(config=config) + + if transport is None: + raise IOError( + "Unhandled combination: UNIX={}, protocol={}" + .format(use_unix, schema) + ) + self.__transport = transport self.__encoding = encoding @@ -787,7 +885,10 @@ def __iter__(self): """ for item in self.results: yield self.__get_result(item) - raise StopIteration + + # Since Python 3.7, we must return instead of raising a StopIteration + # (see PEP-479) + return def __getitem__(self, i): """ diff --git a/ext/jsonrpclib/threadpool.py b/ext/jsonrpclib/threadpool.py index 1d09e54e66..80ab79596b 100644 --- a/ext/jsonrpclib/threadpool.py +++ b/ext/jsonrpclib/threadpool.py @@ -4,13 +4,13 @@ Cached thread pool, inspired from Pelix/iPOPO Thread Pool :author: Thomas Calmant -:copyright: Copyright 2018, Thomas Calmant +:copyright: Copyright 2019, Thomas Calmant :license: Apache License 2.0 -:version: 0.3.2 +:version: 0.4.0 .. - Copyright 2018 Thomas Calmant + Copyright 2019 Thomas Calmant Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -41,7 +41,7 @@ # ------------------------------------------------------------------------------ # Module version -__version_info__ = (0, 3, 2) +__version_info__ = (0, 4, 0) __version__ = ".".join(str(x) for x in __version_info__) # Documentation strings format diff --git a/ext/jsonrpclib/utils.py b/ext/jsonrpclib/utils.py index ae5a839583..58fe3b93af 100644 --- a/ext/jsonrpclib/utils.py +++ b/ext/jsonrpclib/utils.py @@ -4,13 +4,13 @@ Utility methods, for compatibility between Python version :author: Thomas Calmant -:copyright: Copyright 2018, Thomas Calmant +:copyright: Copyright 2019, Thomas Calmant :license: Apache License 2.0 -:version: 0.3.2 +:version: 0.4.0 .. - Copyright 2018 Thomas Calmant + Copyright 2019 Thomas Calmant Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ # ------------------------------------------------------------------------------ # Module version -__version_info__ = (0, 3, 2) +__version_info__ = (0, 4, 0) __version__ = ".".join(str(x) for x in __version_info__) # Documentation strings format diff --git a/ext/jwt/__init__.py b/ext/jwt/__init__.py index e557dcfba1..946983f022 100644 --- a/ext/jwt/__init__.py +++ b/ext/jwt/__init__.py @@ -10,7 +10,7 @@ __title__ = 'pyjwt' -__version__ = '1.6.4' +__version__ = '1.7.1' __author__ = 'José Padilla' __license__ = 'MIT' __copyright__ = 'Copyright 2015-2018 José Padilla' diff --git a/ext/jwt/api_jws.py b/ext/jwt/api_jws.py index 8039e9beb2..a9354adb06 100644 --- a/ext/jwt/api_jws.py +++ b/ext/jwt/api_jws.py @@ -1,7 +1,6 @@ import binascii import json import warnings -from collections import Mapping try: # import required by mypy to perform type checking, not used for normal execution from typing import Callable, Dict, List, Optional, Union # NOQA @@ -11,7 +10,7 @@ from .algorithms import ( Algorithm, get_default_algorithms, has_crypto, requires_cryptography # NOQA ) -from .compat import binary_type, string_types, text_type +from .compat import Mapping, binary_type, string_types, text_type from .exceptions import ( DecodeError, InvalidAlgorithmError, InvalidSignatureError, InvalidTokenError diff --git a/ext/jwt/api_jwt.py b/ext/jwt/api_jwt.py index 6caeecf5ca..85504acf93 100644 --- a/ext/jwt/api_jwt.py +++ b/ext/jwt/api_jwt.py @@ -1,7 +1,6 @@ import json import warnings from calendar import timegm -from collections import Iterable, Mapping from datetime import datetime, timedelta try: # import required by mypy to perform type checking, not used for normal execution @@ -11,7 +10,7 @@ from .api_jws import PyJWS from .algorithms import Algorithm, get_default_algorithms # NOQA -from .compat import string_types +from .compat import Iterable, Mapping, string_types from .exceptions import ( DecodeError, ExpiredSignatureError, ImmatureSignatureError, InvalidAudienceError, InvalidIssuedAtError, diff --git a/ext/jwt/compat.py b/ext/jwt/compat.py index c30f109ca4..e79e258e56 100644 --- a/ext/jwt/compat.py +++ b/ext/jwt/compat.py @@ -20,6 +20,11 @@ string_types = (text_type, binary_type) +try: + # Importing ABCs from collections will be removed in PY3.8 + from collections.abc import Iterable, Mapping +except ImportError: + from collections import Iterable, Mapping try: constant_time_compare = hmac.compare_digest diff --git a/ext/jwt/contrib/__init__.py b/ext/jwt/contrib/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ext/jwt/contrib/algorithms/__init__.py b/ext/jwt/contrib/algorithms/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ext/jwt/contrib/algorithms/py_ecdsa.py b/ext/jwt/contrib/algorithms/py_ecdsa.py new file mode 100644 index 0000000000..bf0dea5ae2 --- /dev/null +++ b/ext/jwt/contrib/algorithms/py_ecdsa.py @@ -0,0 +1,60 @@ +# Note: This file is named py_ecdsa.py because import behavior in Python 2 +# would cause ecdsa.py to squash the ecdsa library that it depends upon. + +import hashlib + +import ecdsa + +from jwt.algorithms import Algorithm +from jwt.compat import string_types, text_type + + +class ECAlgorithm(Algorithm): + """ + Performs signing and verification operations using + ECDSA and the specified hash function + + This class requires the ecdsa package to be installed. + + This is based off of the implementation in PyJWT 0.3.2 + """ + SHA256 = hashlib.sha256 + SHA384 = hashlib.sha384 + SHA512 = hashlib.sha512 + + def __init__(self, hash_alg): + self.hash_alg = hash_alg + + def prepare_key(self, key): + + if isinstance(key, ecdsa.SigningKey) or \ + isinstance(key, ecdsa.VerifyingKey): + return key + + if isinstance(key, string_types): + if isinstance(key, text_type): + key = key.encode('utf-8') + + # Attempt to load key. We don't know if it's + # a Signing Key or a Verifying Key, so we try + # the Verifying Key first. + try: + key = ecdsa.VerifyingKey.from_pem(key) + except ecdsa.der.UnexpectedDER: + key = ecdsa.SigningKey.from_pem(key) + + else: + raise TypeError('Expecting a PEM-formatted key.') + + return key + + def sign(self, msg, key): + return key.sign(msg, hashfunc=self.hash_alg, + sigencode=ecdsa.util.sigencode_string) + + def verify(self, msg, key, sig): + try: + return key.verify(sig, msg, hashfunc=self.hash_alg, + sigdecode=ecdsa.util.sigdecode_string) + except AssertionError: + return False diff --git a/ext/jwt/contrib/algorithms/pycrypto.py b/ext/jwt/contrib/algorithms/pycrypto.py new file mode 100644 index 0000000000..e49cdbfe40 --- /dev/null +++ b/ext/jwt/contrib/algorithms/pycrypto.py @@ -0,0 +1,46 @@ +import Crypto.Hash.SHA256 +import Crypto.Hash.SHA384 +import Crypto.Hash.SHA512 +from Crypto.PublicKey import RSA +from Crypto.Signature import PKCS1_v1_5 + +from jwt.algorithms import Algorithm +from jwt.compat import string_types, text_type + + +class RSAAlgorithm(Algorithm): + """ + Performs signing and verification operations using + RSASSA-PKCS-v1_5 and the specified hash function. + + This class requires PyCrypto package to be installed. + + This is based off of the implementation in PyJWT 0.3.2 + """ + SHA256 = Crypto.Hash.SHA256 + SHA384 = Crypto.Hash.SHA384 + SHA512 = Crypto.Hash.SHA512 + + def __init__(self, hash_alg): + self.hash_alg = hash_alg + + def prepare_key(self, key): + + if isinstance(key, RSA._RSAobj): + return key + + if isinstance(key, string_types): + if isinstance(key, text_type): + key = key.encode('utf-8') + + key = RSA.importKey(key) + else: + raise TypeError('Expecting a PEM- or RSA-formatted key.') + + return key + + def sign(self, msg, key): + return PKCS1_v1_5.new(key).sign(self.hash_alg.new(msg)) + + def verify(self, msg, key, sig): + return PKCS1_v1_5.new(key).verify(self.hash_alg.new(msg), sig) diff --git a/ext/markdown2.py b/ext/markdown2.py index c406865d0e..16672f51d3 100644 --- a/ext/markdown2.py +++ b/ext/markdown2.py @@ -3,8 +3,6 @@ # Copyright (c) 2007-2008 ActiveState Corp. # License: MIT (http://www.opensource.org/licenses/mit-license.php) -from __future__ import generators - r"""A fast and complete Python implementation of Markdown. [from http://daringfireball.net/projects/markdown/] @@ -98,7 +96,7 @@ # not yet sure if there implications with this. Compare 'pydoc sre' # and 'perldoc perlre'. -__version_info__ = (2, 3, 6) +__version_info__ = (2, 3, 7) __version__ = '.'.join(map(str, __version_info__)) __author__ = "Trent Mick" @@ -109,6 +107,7 @@ import optparse from random import random, randint import codecs +from collections import defaultdict try: from urllib import quote_plus except ImportError: @@ -117,11 +116,6 @@ # ---- Python version compat -if sys.version_info[:2] < (2, 4): - def reversed(sequence): - for i in sequence[::-1]: - yield i - # Use `bytes` for byte strings and `unicode` for unicode strings (str in Py3). if sys.version_info[0] <= 2: py3 = False @@ -242,8 +236,11 @@ def __init__(self, html4tags=False, tab_width=4, safe_mode=None, extras = dict([(e, None) for e in extras]) self.extras.update(extras) assert isinstance(self.extras, dict) - if "toc" in self.extras and "header-ids" not in self.extras: - self.extras["header-ids"] = None # "toc" implies "header-ids" + + if "toc" in self.extras: + if "header-ids" not in self.extras: + self.extras["header-ids"] = None # "toc" implies "header-ids" + if self.extras["toc"] is None: self._toc_depth = 6 else: @@ -273,7 +270,7 @@ def reset(self): self.footnotes = {} self.footnote_ids = [] if "header-ids" in self.extras: - self._count_from_header_id = {} # no `defaultdict` in Python 2.4 + self._count_from_header_id = defaultdict(int) if "metadata" in self.extras: self.metadata = {} @@ -1505,13 +1502,10 @@ def header_id_from_text(self, text, prefix, n): header_id = _slugify(text) if prefix and isinstance(prefix, base_string_type): header_id = prefix + '-' + header_id - if header_id in self._count_from_header_id: - self._count_from_header_id[header_id] += 1 + + self._count_from_header_id[header_id] += 1 + if 0 == len(header_id) or self._count_from_header_id[header_id] > 1: header_id += '-%s' % self._count_from_header_id[header_id] - else: - self._count_from_header_id[header_id] = 1 - if 0 == len(header_id): - header_id += '-%s' % self._count_from_header_id[header_id] return header_id @@ -2140,7 +2134,7 @@ def _encode_amps_and_angles(self, text): text = self._naked_gt_re.sub('>', text) return text - _incomplete_tags_re = re.compile("<(/?\w+\s+)") + _incomplete_tags_re = re.compile("<(/?\w+[\s/]+?)") def _encode_incomplete_tags(self, text): if self.safe_mode not in ("replace", "escape"): diff --git a/ext/oauthlib/__init__.py b/ext/oauthlib/__init__.py index 3393efeba0..b37d288c31 100644 --- a/ext/oauthlib/__init__.py +++ b/ext/oauthlib/__init__.py @@ -5,21 +5,13 @@ A generic, spec-compliant, thorough implementation of the OAuth request-signing logic. - :copyright: (c) 2011 by Idan Gazit. + :copyright: (c) 2019 by The OAuthlib Community :license: BSD, see LICENSE for details. """ - -__author__ = 'The OAuthlib Community' -__version__ = '2.1.0' - - import logging -try: # Python 2.7+ - from logging import NullHandler -except ImportError: - class NullHandler(logging.Handler): +from logging import NullHandler - def emit(self, record): - pass +__author__ = 'The OAuthlib Community' +__version__ = '3.0.0' logging.getLogger('oauthlib').addHandler(NullHandler()) diff --git a/ext/oauthlib/common.py b/ext/oauthlib/common.py index f25656ffc2..970d7a5b59 100644 --- a/ext/oauthlib/common.py +++ b/ext/oauthlib/common.py @@ -54,10 +54,8 @@ if PY3: unicode_type = str - bytes_type = bytes else: unicode_type = unicode - bytes_type = str # 'safe' must be bytes (Python 2.6 requires bytes, other versions allow either) @@ -66,7 +64,7 @@ def quote(s, safe=b'/'): s = _quote(s, safe) # PY3 always returns unicode. PY2 may return either, depending on whether # it had to modify the string. - if isinstance(s, bytes_type): + if isinstance(s, bytes): s = s.decode('utf-8') return s @@ -76,7 +74,7 @@ def unquote(s): # PY3 always returns unicode. PY2 seems to always return what you give it, # which differs from quote's behavior. Just to be safe, make sure it is # unicode before we return. - if isinstance(s, bytes_type): + if isinstance(s, bytes): s = s.decode('utf-8') return s @@ -109,12 +107,12 @@ def decode_params_utf8(params): decoded = [] for k, v in params: decoded.append(( - k.decode('utf-8') if isinstance(k, bytes_type) else k, - v.decode('utf-8') if isinstance(v, bytes_type) else v)) + k.decode('utf-8') if isinstance(k, bytes) else k, + v.decode('utf-8') if isinstance(v, bytes) else v)) return decoded -urlencoded = set(always_safe) | set('=&;:%+~,*@!()/?') +urlencoded = set(always_safe) | set('=&;:%+~,*@!()/?\'$') def urldecode(query): @@ -174,7 +172,7 @@ def extract_params(raw): empty list of parameters. Any other input will result in a return value of None. """ - if isinstance(raw, bytes_type) or isinstance(raw, unicode_type): + if isinstance(raw, bytes) or isinstance(raw, unicode_type): try: params = urldecode(raw) except ValueError: @@ -309,7 +307,7 @@ def to_unicode(data, encoding='UTF-8'): if isinstance(data, unicode_type): return data - if isinstance(data, bytes_type): + if isinstance(data, bytes): return unicode_type(data, encoding=encoding) if hasattr(data, '__iter__'): @@ -399,6 +397,9 @@ def __init__(self, uri, http_method='GET', body=None, headers=None, "client_id": None, "client_secret": None, "code": None, + "code_challenge": None, + "code_challenge_method": None, + "code_verifier": None, "extra_credentials": None, "grant_type": None, "redirect_uri": None, @@ -426,7 +427,6 @@ def __init__(self, uri, http_method='GET', body=None, headers=None, } self._params.update(dict(urldecode(self.uri_query))) self._params.update(dict(self.decoded_body or [])) - self._params.update(self.headers) def __getattr__(self, name): if name in self._params: diff --git a/ext/oauthlib/oauth1/__init__.py b/ext/oauthlib/oauth1/__init__.py index f9dff74d99..dc908d4eba 100644 --- a/ext/oauthlib/oauth1/__init__.py +++ b/ext/oauthlib/oauth1/__init__.py @@ -9,7 +9,7 @@ from __future__ import absolute_import, unicode_literals from .rfc5849 import Client -from .rfc5849 import SIGNATURE_HMAC, SIGNATURE_RSA, SIGNATURE_PLAINTEXT +from .rfc5849 import SIGNATURE_HMAC, SIGNATURE_HMAC_SHA1, SIGNATURE_HMAC_SHA256, SIGNATURE_RSA, SIGNATURE_PLAINTEXT from .rfc5849 import SIGNATURE_TYPE_AUTH_HEADER, SIGNATURE_TYPE_QUERY from .rfc5849 import SIGNATURE_TYPE_BODY from .rfc5849.request_validator import RequestValidator diff --git a/ext/oauthlib/oauth1/rfc5849/__init__.py b/ext/oauthlib/oauth1/rfc5849/__init__.py index 6d8960eb2f..7313286c29 100644 --- a/ext/oauthlib/oauth1/rfc5849/__init__.py +++ b/ext/oauthlib/oauth1/rfc5849/__init__.py @@ -18,19 +18,16 @@ except ImportError: import urllib.parse as urlparse -if sys.version_info[0] == 3: - bytes_type = bytes -else: - bytes_type = str - from oauthlib.common import Request, urlencode, generate_nonce from oauthlib.common import generate_timestamp, to_unicode from . import parameters, signature -SIGNATURE_HMAC = "HMAC-SHA1" +SIGNATURE_HMAC_SHA1 = "HMAC-SHA1" +SIGNATURE_HMAC_SHA256 = "HMAC-SHA256" +SIGNATURE_HMAC = SIGNATURE_HMAC_SHA1 SIGNATURE_RSA = "RSA-SHA1" SIGNATURE_PLAINTEXT = "PLAINTEXT" -SIGNATURE_METHODS = (SIGNATURE_HMAC, SIGNATURE_RSA, SIGNATURE_PLAINTEXT) +SIGNATURE_METHODS = (SIGNATURE_HMAC_SHA1, SIGNATURE_HMAC_SHA256, SIGNATURE_RSA, SIGNATURE_PLAINTEXT) SIGNATURE_TYPE_AUTH_HEADER = 'AUTH_HEADER' SIGNATURE_TYPE_QUERY = 'QUERY' @@ -43,7 +40,8 @@ class Client(object): """A client used to sign OAuth 1.0 RFC 5849 requests.""" SIGNATURE_METHODS = { - SIGNATURE_HMAC: signature.sign_hmac_sha1_with_client, + SIGNATURE_HMAC_SHA1: signature.sign_hmac_sha1_with_client, + SIGNATURE_HMAC_SHA256: signature.sign_hmac_sha256_with_client, SIGNATURE_RSA: signature.sign_rsa_sha1_with_client, SIGNATURE_PLAINTEXT: signature.sign_plaintext_with_client } @@ -57,7 +55,7 @@ def __init__(self, client_key, resource_owner_key=None, resource_owner_secret=None, callback_uri=None, - signature_method=SIGNATURE_HMAC, + signature_method=SIGNATURE_HMAC_SHA1, signature_type=SIGNATURE_TYPE_AUTH_HEADER, rsa_key=None, verifier=None, realm=None, encoding='utf-8', decoding=None, @@ -175,10 +173,12 @@ def get_oauth_params(self, request): params.append(('oauth_verifier', self.verifier)) # providing body hash for requests other than x-www-form-urlencoded - # as described in http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html + # as described in https://tools.ietf.org/html/draft-eaton-oauth-bodyhash-00#section-4.1.1 # 4.1.1. When to include the body hash # * [...] MUST NOT include an oauth_body_hash parameter on requests with form-encoded request bodies # * [...] SHOULD include the oauth_body_hash parameter on all other requests. + # Note that SHA-1 is vulnerable. The spec acknowledges that in https://tools.ietf.org/html/draft-eaton-oauth-bodyhash-00#section-6.2 + # At this time, no further effort has been made to replace SHA-1 for the OAuth Request Body Hash extension. content_type = request.headers.get('Content-Type', None) content_type_eligible = content_type and content_type.find('application/x-www-form-urlencoded') < 0 if request.body is not None and content_type_eligible: diff --git a/ext/oauthlib/oauth1/rfc5849/endpoints/access_token.py b/ext/oauthlib/oauth1/rfc5849/endpoints/access_token.py index 12d13e9b98..bea8274174 100644 --- a/ext/oauthlib/oauth1/rfc5849/endpoints/access_token.py +++ b/ext/oauthlib/oauth1/rfc5849/endpoints/access_token.py @@ -37,7 +37,8 @@ def create_access_token(self, request, credentials): Similar to OAuth 2, indication of granted scopes will be included as a space separated list in ``oauth_authorized_realms``. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: The token as an urlencoded string. """ request.realms = self.request_validator.get_realms( @@ -120,7 +121,8 @@ def create_access_token_response(self, uri, http_method='GET', body=None, def validate_access_token_request(self, request): """Validate an access token request. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :raises: OAuth1Error if the request is invalid. :returns: A tuple of 2 elements. 1. The validation result (True or False). diff --git a/ext/oauthlib/oauth1/rfc5849/endpoints/authorization.py b/ext/oauthlib/oauth1/rfc5849/endpoints/authorization.py index 1751a45e9c..b465946f9c 100644 --- a/ext/oauthlib/oauth1/rfc5849/endpoints/authorization.py +++ b/ext/oauthlib/oauth1/rfc5849/endpoints/authorization.py @@ -42,7 +42,8 @@ class AuthorizationEndpoint(BaseEndpoint): def create_verifier(self, request, credentials): """Create and save a new request token. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :param credentials: A dict of extra token credentials. :returns: The verifier as a dict. """ diff --git a/ext/oauthlib/oauth1/rfc5849/endpoints/request_token.py b/ext/oauthlib/oauth1/rfc5849/endpoints/request_token.py index 88fd6c0901..e9ca331d18 100644 --- a/ext/oauthlib/oauth1/rfc5849/endpoints/request_token.py +++ b/ext/oauthlib/oauth1/rfc5849/endpoints/request_token.py @@ -34,7 +34,8 @@ class RequestTokenEndpoint(BaseEndpoint): def create_request_token(self, request, credentials): """Create and save a new request token. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :param credentials: A dict of extra token credentials. :returns: The token as an urlencoded string. """ @@ -111,7 +112,8 @@ def create_request_token_response(self, uri, http_method='GET', body=None, def validate_request_token_request(self, request): """Validate a request token request. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :raises: OAuth1Error if the request is invalid. :returns: A tuple of 2 elements. 1. The validation result (True or False). diff --git a/ext/oauthlib/oauth1/rfc5849/parameters.py b/ext/oauthlib/oauth1/rfc5849/parameters.py index 2f068a7c78..db4400e941 100644 --- a/ext/oauthlib/oauth1/rfc5849/parameters.py +++ b/ext/oauthlib/oauth1/rfc5849/parameters.py @@ -15,7 +15,7 @@ try: from urlparse import urlparse, urlunparse -except ImportError: +except ImportError: # noqa from urllib.parse import urlparse, urlunparse diff --git a/ext/oauthlib/oauth1/rfc5849/request_validator.py b/ext/oauthlib/oauth1/rfc5849/request_validator.py index bc62ea0407..330bcbb81e 100644 --- a/ext/oauthlib/oauth1/rfc5849/request_validator.py +++ b/ext/oauthlib/oauth1/rfc5849/request_validator.py @@ -267,7 +267,8 @@ def get_client_secret(self, client_key, request): """Retrieves the client secret associated with the client key. :param client_key: The client/consumer key. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: The client secret as a string. This method must allow the use of a dummy client_key value. @@ -303,7 +304,8 @@ def get_request_token_secret(self, client_key, token, request): :param client_key: The client/consumer key. :param token: The request token string. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: The token secret as a string. This method must allow the use of a dummy values and the running time @@ -335,7 +337,8 @@ def get_access_token_secret(self, client_key, token, request): :param client_key: The client/consumer key. :param token: The access token string. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: The token secret as a string. This method must allow the use of a dummy values and the running time @@ -366,7 +369,8 @@ def get_default_realms(self, client_key, request): """Get the default realms for a client. :param client_key: The client/consumer key. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: The list of default realms associated with the client. The list of default realms will be set during client registration and @@ -382,7 +386,8 @@ def get_realms(self, token, request): """Get realms associated with a request token. :param token: The request token string. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: The list of realms associated with the request token. This method is used by @@ -396,7 +401,8 @@ def get_redirect_uri(self, token, request): """Get the redirect URI associated with a request token. :param token: The request token string. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: The redirect URI associated with the request token. It may be desirable to return a custom URI if the redirect is set to "oob". @@ -413,7 +419,8 @@ def get_rsa_key(self, client_key, request): """Retrieves a previously stored client provided RSA key. :param client_key: The client/consumer key. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: The rsa public key as a string. This method must allow the use of a dummy client_key value. Fetching @@ -437,7 +444,8 @@ def invalidate_request_token(self, client_key, request_token, request): :param client_key: The client/consumer key. :param request_token: The request token string. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: None Per `Section 2.3`__ of the spec: @@ -462,7 +470,8 @@ def validate_client_key(self, client_key, request): """Validates that supplied client key is a registered and valid client. :param client_key: The client/consumer key. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: True or False Note that if the dummy client is supplied it should validate in same @@ -499,7 +508,8 @@ def validate_request_token(self, client_key, token, request): :param client_key: The client/consumer key. :param token: The request token string. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: True or False Note that if the dummy request_token is supplied it should validate in @@ -533,7 +543,8 @@ def validate_access_token(self, client_key, token, request): :param client_key: The client/consumer key. :param token: The access token string. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: True or False Note that if the dummy access token is supplied it should validate in @@ -571,7 +582,8 @@ def validate_timestamp_and_nonce(self, client_key, timestamp, nonce, :param nonce: The ``oauth_nonce`` parameter. :param request_token: Request token string, if any. :param access_token: Access token string, if any. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: True or False Per `Section 3.3`_ of the spec. @@ -618,7 +630,8 @@ def validate_redirect_uri(self, client_key, redirect_uri, request): :param client_key: The client/consumer key. :param redirect_uri: The URI the client which to redirect back to after authorization is successful. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: True or False It is highly recommended that OAuth providers require their clients @@ -650,7 +663,8 @@ def validate_requested_realms(self, client_key, realms, request): :param client_key: The client/consumer key. :param realms: The list of realms that client is requesting access to. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: True or False This method is invoked when obtaining a request token and should @@ -669,7 +683,8 @@ def validate_realms(self, client_key, token, request, uri=None, :param client_key: The client/consumer key. :param token: A request token string. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :param uri: The URI the realms is protecting. :param realms: A list of realms that must have been granted to the access token. @@ -703,7 +718,8 @@ def validate_verifier(self, client_key, token, verifier, request): :param client_key: The client/consumer key. :param token: A request token string. :param verifier: The authorization verifier string. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: True or False OAuth providers issue a verification code to clients after the @@ -732,7 +748,8 @@ def verify_request_token(self, token, request): """Verify that the given OAuth1 request token is valid. :param token: A request token string. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: True or False This method is used only in AuthorizationEndpoint to check whether the @@ -751,7 +768,8 @@ def verify_realms(self, token, realms, request): :param token: An access token string. :param realms: A list of realms the client attempts to access. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :returns: True or False This prevents the list of authorized realms sent by the client during @@ -773,7 +791,8 @@ def save_access_token(self, token, request): """Save an OAuth1 access token. :param token: A dict with token credentials. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request The token dictionary will at minimum include @@ -796,7 +815,8 @@ def save_request_token(self, token, request): """Save an OAuth1 request token. :param token: A dict with token credentials. - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request The token dictionary will at minimum include @@ -818,7 +838,8 @@ def save_verifier(self, token, verifier, request): :param token: A request token string. :param verifier A dictionary containing the oauth_verifier and oauth_token - :param request: An oauthlib.common.Request object. + :param request: OAuthlib request. + :type request: oauthlib.common.Request We need to associate verifiers with tokens for validation during the access token request. diff --git a/ext/oauthlib/oauth1/rfc5849/signature.py b/ext/oauthlib/oauth1/rfc5849/signature.py index 881d8d4798..e90d6f37af 100644 --- a/ext/oauthlib/oauth1/rfc5849/signature.py +++ b/ext/oauthlib/oauth1/rfc5849/signature.py @@ -28,7 +28,7 @@ import hmac import logging -from oauthlib.common import (bytes_type, extract_params, safe_string_equals, +from oauthlib.common import (extract_params, safe_string_equals, unicode_type, urldecode) from . import utils @@ -469,6 +469,63 @@ def sign_hmac_sha1(base_string, client_secret, resource_owner_secret): # .. _`RFC2045, Section 6.8`: https://tools.ietf.org/html/rfc2045#section-6.8 return binascii.b2a_base64(signature.digest())[:-1].decode('utf-8') + +def sign_hmac_sha256_with_client(base_string, client): + return sign_hmac_sha256(base_string, + client.client_secret, + client.resource_owner_secret + ) + + +def sign_hmac_sha256(base_string, client_secret, resource_owner_secret): + """**HMAC-SHA256** + + The "HMAC-SHA256" signature method uses the HMAC-SHA256 signature + algorithm as defined in `RFC4634`_:: + + digest = HMAC-SHA256 (key, text) + + Per `section 3.4.2`_ of the spec. + + .. _`RFC4634`: https://tools.ietf.org/html/rfc4634 + .. _`section 3.4.2`: https://tools.ietf.org/html/rfc5849#section-3.4.2 + """ + + # The HMAC-SHA256 function variables are used in following way: + + # text is set to the value of the signature base string from + # `Section 3.4.1.1`_. + # + # .. _`Section 3.4.1.1`: https://tools.ietf.org/html/rfc5849#section-3.4.1.1 + text = base_string + + # key is set to the concatenated values of: + # 1. The client shared-secret, after being encoded (`Section 3.6`_). + # + # .. _`Section 3.6`: https://tools.ietf.org/html/rfc5849#section-3.6 + key = utils.escape(client_secret or '') + + # 2. An "&" character (ASCII code 38), which MUST be included + # even when either secret is empty. + key += '&' + + # 3. The token shared-secret, after being encoded (`Section 3.6`_). + # + # .. _`Section 3.6`: https://tools.ietf.org/html/rfc5849#section-3.6 + key += utils.escape(resource_owner_secret or '') + + # FIXME: HMAC does not support unicode! + key_utf8 = key.encode('utf-8') + text_utf8 = text.encode('utf-8') + signature = hmac.new(key_utf8, text_utf8, hashlib.sha256) + + # digest is used to set the value of the "oauth_signature" protocol + # parameter, after the result octet string is base64-encoded + # per `RFC2045, Section 6.8`. + # + # .. _`RFC2045, Section 6.8`: https://tools.ietf.org/html/rfc2045#section-6.8 + return binascii.b2a_base64(signature.digest())[:-1].decode('utf-8') + _jwtrs1 = None #jwt has some nice pycrypto/cryptography abstractions @@ -578,7 +635,7 @@ def verify_hmac_sha1(request, client_secret=None, def _prepare_key_plus(alg, keystr): - if isinstance(keystr, bytes_type): + if isinstance(keystr, bytes): keystr = keystr.decode('utf-8') return alg.prepare_key(keystr) diff --git a/ext/oauthlib/oauth1/rfc5849/utils.py b/ext/oauthlib/oauth1/rfc5849/utils.py index 3762e3b5c6..735f21d65a 100644 --- a/ext/oauthlib/oauth1/rfc5849/utils.py +++ b/ext/oauthlib/oauth1/rfc5849/utils.py @@ -8,7 +8,7 @@ """ from __future__ import absolute_import, unicode_literals -from oauthlib.common import bytes_type, quote, unicode_type, unquote +from oauthlib.common import quote, unicode_type, unquote try: import urllib2 diff --git a/ext/oauthlib/oauth2/__init__.py b/ext/oauthlib/oauth2/__init__.py index c8d934e901..3f4375569d 100644 --- a/ext/oauthlib/oauth2/__init__.py +++ b/ext/oauthlib/oauth2/__init__.py @@ -15,6 +15,8 @@ from .rfc6749.clients import BackendApplicationClient from .rfc6749.clients import ServiceApplicationClient from .rfc6749.endpoints import AuthorizationEndpoint +from .rfc6749.endpoints import IntrospectEndpoint +from .rfc6749.endpoints import MetadataEndpoint from .rfc6749.endpoints import TokenEndpoint from .rfc6749.endpoints import ResourceEndpoint from .rfc6749.endpoints import RevocationEndpoint @@ -23,7 +25,7 @@ from .rfc6749.endpoints import MobileApplicationServer from .rfc6749.endpoints import LegacyApplicationServer from .rfc6749.endpoints import BackendApplicationServer -from .rfc6749.errors import AccessDeniedError, AccountSelectionRequired, ConsentRequired, FatalClientError, FatalOpenIDClientError, InsecureTransportError, InteractionRequired, InvalidClientError, InvalidClientIdError, InvalidGrantError, InvalidRedirectURIError, InvalidRequestError, InvalidRequestFatalError, InvalidScopeError, LoginRequired, MismatchingRedirectURIError, MismatchingStateError, MissingClientIdError, MissingCodeError, MissingRedirectURIError, MissingResponseTypeError, MissingTokenError, MissingTokenTypeError, OAuth2Error, OpenIDClientError, ServerError, TemporarilyUnavailableError, TokenExpiredError, UnauthorizedClientError, UnsupportedGrantTypeError, UnsupportedResponseTypeError, UnsupportedTokenTypeError +from .rfc6749.errors import AccessDeniedError, OAuth2Error, FatalClientError, InsecureTransportError, InvalidClientError, InvalidClientIdError, InvalidGrantError, InvalidRedirectURIError, InvalidRequestError, InvalidRequestFatalError, InvalidScopeError, MismatchingRedirectURIError, MismatchingStateError, MissingClientIdError, MissingCodeError, MissingRedirectURIError, MissingResponseTypeError, MissingTokenError, MissingTokenTypeError, ServerError, TemporarilyUnavailableError, TokenExpiredError, UnauthorizedClientError, UnsupportedGrantTypeError, UnsupportedResponseTypeError, UnsupportedTokenTypeError from .rfc6749.grant_types import AuthorizationCodeGrant from .rfc6749.grant_types import ImplicitGrant from .rfc6749.grant_types import ResourceOwnerPasswordCredentialsGrant diff --git a/ext/oauthlib/oauth2/rfc6749/clients/backend_application.py b/ext/oauthlib/oauth2/rfc6749/clients/backend_application.py index cbad8b7466..a000ecf5d1 100644 --- a/ext/oauthlib/oauth2/rfc6749/clients/backend_application.py +++ b/ext/oauthlib/oauth2/rfc6749/clients/backend_application.py @@ -29,16 +29,29 @@ class BackendApplicationClient(Client): Since the client authentication is used as the authorization grant, no additional authorization request is needed. """ - - def prepare_request_body(self, body='', scope=None, **kwargs): + + grant_type = 'client_credentials' + + def prepare_request_body(self, body='', scope=None, + include_client_id=None, **kwargs): """Add the client credentials to the request body. The client makes a request to the token endpoint by adding the following parameters using the "application/x-www-form-urlencoded" format per `Appendix B`_ in the HTTP request entity-body: + :param body: Existing request body (URL encoded string) to embed parameters + into. This may contain extra paramters. Default ''. :param scope: The scope of the access request as described by `Section 3.3`_. + + :param include_client_id: `True` to send the `client_id` in the body of + the upstream request. Default `None`. This is + required if the client is not authenticating + with the authorization server as described + in `Section 3.2.1`_. + :type include_client_id: Boolean + :param kwargs: Extra credentials to include in the token request. The client MUST authenticate with the authorization server as @@ -56,5 +69,7 @@ def prepare_request_body(self, body='', scope=None, **kwargs): .. _`Section 3.3`: https://tools.ietf.org/html/rfc6749#section-3.3 .. _`Section 3.2.1`: https://tools.ietf.org/html/rfc6749#section-3.2.1 """ - return prepare_token_request('client_credentials', body=body, + kwargs['client_id'] = self.client_id + kwargs['include_client_id'] = include_client_id + return prepare_token_request(self.grant_type, body=body, scope=scope, **kwargs) diff --git a/ext/oauthlib/oauth2/rfc6749/clients/base.py b/ext/oauthlib/oauth2/rfc6749/clients/base.py index 07ef894942..1a50644e69 100644 --- a/ext/oauthlib/oauth2/rfc6749/clients/base.py +++ b/ext/oauthlib/oauth2/rfc6749/clients/base.py @@ -47,6 +47,7 @@ class Client(object): Python, this is usually :py:class:`oauthlib.oauth2.WebApplicationClient`. """ + refresh_token_key = 'refresh_token' def __init__(self, client_id, default_token_placement=AUTH_HEADER, @@ -143,6 +144,7 @@ def prepare_request_body(self, *args, **kwargs): def parse_request_uri_response(self, *args, **kwargs): """Abstract method used to parse redirection responses.""" + raise NotImplementedError("Must be implemented by inheriting classes.") def add_token(self, uri, http_method='GET', body=None, headers=None, token_placement=None, **kwargs): @@ -253,7 +255,8 @@ def prepare_token_request(self, token_url, authorization_response=None, :param redirect_url: The redirect_url supplied with the authorization request (if there was one). - :param body: Request body (URL encoded string). + :param body: Existing request body (URL encoded string) to embed parameters + into. This may contain extra paramters. Default ''. :param kwargs: Additional parameters to included in the request. @@ -285,7 +288,8 @@ def prepare_refresh_token_request(self, token_url, refresh_token=None, :param refresh_token: Refresh token string. - :param body: Request body (URL encoded string). + :param body: Existing request body (URL encoded string) to embed parameters + into. This may contain extra paramters. Default ''. :param scope: List of scopes to request. Must be equal to or a subset of the scopes granted when obtaining the refresh @@ -432,7 +436,7 @@ def prepare_refresh_body(self, body='', refresh_token=None, scope=None, **kwargs resource owner. """ refresh_token = refresh_token or self.refresh_token - return prepare_token_request('refresh_token', body=body, scope=scope, + return prepare_token_request(self.refresh_token_key, body=body, scope=scope, refresh_token=refresh_token, **kwargs) def _add_bearer_token(self, uri, http_method='GET', body=None, diff --git a/ext/oauthlib/oauth2/rfc6749/clients/legacy_application.py b/ext/oauthlib/oauth2/rfc6749/clients/legacy_application.py index b16fc9f880..2449363afb 100644 --- a/ext/oauthlib/oauth2/rfc6749/clients/legacy_application.py +++ b/ext/oauthlib/oauth2/rfc6749/clients/legacy_application.py @@ -34,11 +34,14 @@ class LegacyApplicationClient(Client): credentials is beyond the scope of this specification. The client MUST discard the credentials once an access token has been obtained. """ + + grant_type = 'password' def __init__(self, client_id, **kwargs): super(LegacyApplicationClient, self).__init__(client_id, **kwargs) - def prepare_request_body(self, username, password, body='', scope=None, **kwargs): + def prepare_request_body(self, username, password, body='', scope=None, + include_client_id=None, **kwargs): """Add the resource owner password and username to the request body. The client makes a request to the token endpoint by adding the @@ -47,8 +50,16 @@ def prepare_request_body(self, username, password, body='', scope=None, **kwargs :param username: The resource owner username. :param password: The resource owner password. + :param body: Existing request body (URL encoded string) to embed parameters + into. This may contain extra paramters. Default ''. :param scope: The scope of the access request as described by `Section 3.3`_. + :param include_client_id: `True` to send the `client_id` in the body of + the upstream request. Default `None`. This is + required if the client is not authenticating + with the authorization server as described + in `Section 3.2.1`_. + :type include_client_id: Boolean :param kwargs: Extra credentials to include in the token request. If the client type is confidential or the client was issued client @@ -68,5 +79,7 @@ def prepare_request_body(self, username, password, body='', scope=None, **kwargs .. _`Section 3.3`: https://tools.ietf.org/html/rfc6749#section-3.3 .. _`Section 3.2.1`: https://tools.ietf.org/html/rfc6749#section-3.2.1 """ - return prepare_token_request('password', body=body, username=username, + kwargs['client_id'] = self.client_id + kwargs['include_client_id'] = include_client_id + return prepare_token_request(self.grant_type, body=body, username=username, password=password, scope=scope, **kwargs) diff --git a/ext/oauthlib/oauth2/rfc6749/clients/mobile_application.py b/ext/oauthlib/oauth2/rfc6749/clients/mobile_application.py index aa20daabbe..11c6c51c95 100644 --- a/ext/oauthlib/oauth2/rfc6749/clients/mobile_application.py +++ b/ext/oauthlib/oauth2/rfc6749/clients/mobile_application.py @@ -45,6 +45,8 @@ class MobileApplicationClient(Client): redirection URI, it may be exposed to the resource owner and other applications residing on the same device. """ + + response_type = 'token' def prepare_request_uri(self, uri, redirect_uri=None, scope=None, state=None, **kwargs): @@ -91,7 +93,7 @@ def prepare_request_uri(self, uri, redirect_uri=None, scope=None, .. _`Section 3.3`: https://tools.ietf.org/html/rfc6749#section-3.3 .. _`Section 10.12`: https://tools.ietf.org/html/rfc6749#section-10.12 """ - return prepare_grant_uri(uri, self.client_id, 'token', + return prepare_grant_uri(uri, self.client_id, self.response_type, redirect_uri=redirect_uri, state=state, scope=scope, **kwargs) def parse_request_uri_response(self, uri, state=None, scope=None): diff --git a/ext/oauthlib/oauth2/rfc6749/clients/service_application.py b/ext/oauthlib/oauth2/rfc6749/clients/service_application.py index 7f336bbc91..35333d8141 100644 --- a/ext/oauthlib/oauth2/rfc6749/clients/service_application.py +++ b/ext/oauthlib/oauth2/rfc6749/clients/service_application.py @@ -54,7 +54,7 @@ def __init__(self, client_id, private_key=None, subject=None, issuer=None, ``https://provider.com/oauth2/token``. :param kwargs: Additional arguments to pass to base client, such as - state and token. See Client.__init__.__doc__ for + state and token. See ``Client.__init__.__doc__`` for details. """ super(ServiceApplicationClient, self).__init__(client_id, **kwargs) @@ -72,7 +72,8 @@ def prepare_request_body(self, issued_at=None, extra_claims=None, body='', - scope=None, + scope=None, + include_client_id=None, **kwargs): """Create and add a JWT assertion to the request body. @@ -97,20 +98,32 @@ def prepare_request_body(self, :param issued_at: A unix timestamp of when the JWT was created. Defaults to now, i.e. ``time.time()``. - :param not_before: A unix timestamp after which the JWT may be used. - Not included unless provided. - - :param jwt_id: A unique JWT token identifier. Not included unless - provided. - :param extra_claims: A dict of additional claims to include in the JWT. + :param body: Existing request body (URL encoded string) to embed parameters + into. This may contain extra paramters. Default ''. + :param scope: The scope of the access request. - :param body: Request body (string) with extra parameters. + :param include_client_id: `True` to send the `client_id` in the body of + the upstream request. Default `None`. This is + required if the client is not authenticating + with the authorization server as described + in `Section 3.2.1`_. + :type include_client_id: Boolean + + :param not_before: A unix timestamp after which the JWT may be used. + Not included unless provided. * + + :param jwt_id: A unique JWT token identifier. Not included unless + provided. * :param kwargs: Extra credentials to include in the token request. + Parameters marked with a `*` above are not explicit arguments in the + function signature, but are specially documented arguments for items + appearing in the generic `**kwargs` keyworded input. + The "scope" parameter may be used, as defined in the Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants [I-D.ietf-oauth-assertions] specification, to indicate the requested @@ -168,6 +181,8 @@ def prepare_request_body(self, assertion = jwt.encode(claim, key, 'RS256') assertion = to_unicode(assertion) + kwargs['client_id'] = self.client_id + kwargs['include_client_id'] = include_client_id return prepare_token_request(self.grant_type, body=body, assertion=assertion, diff --git a/ext/oauthlib/oauth2/rfc6749/clients/web_application.py b/ext/oauthlib/oauth2/rfc6749/clients/web_application.py index 25280bf86e..0cd39ce510 100644 --- a/ext/oauthlib/oauth2/rfc6749/clients/web_application.py +++ b/ext/oauthlib/oauth2/rfc6749/clients/web_application.py @@ -8,6 +8,8 @@ """ from __future__ import absolute_import, unicode_literals +import warnings + from ..parameters import (parse_authorization_code_response, parse_token_response, prepare_grant_uri, prepare_token_request) @@ -32,6 +34,8 @@ class WebApplicationClient(Client): browser) and capable of receiving incoming requests (via redirection) from the authorization server. """ + + grant_type = 'authorization_code' def __init__(self, client_id, code=None, **kwargs): super(WebApplicationClient, self).__init__(client_id, **kwargs) @@ -85,17 +89,14 @@ def prepare_request_uri(self, uri, redirect_uri=None, scope=None, return prepare_grant_uri(uri, self.client_id, 'code', redirect_uri=redirect_uri, scope=scope, state=state, **kwargs) - def prepare_request_body(self, client_id=None, code=None, body='', - redirect_uri=None, **kwargs): + def prepare_request_body(self, code=None, redirect_uri=None, body='', + include_client_id=True, **kwargs): """Prepare the access token request body. The client makes a request to the token endpoint by adding the following parameters using the "application/x-www-form-urlencoded" format in the HTTP request entity-body: - :param client_id: REQUIRED, if the client is not authenticating with the - authorization server as described in `Section 3.2.1`_. - :param code: REQUIRED. The authorization code received from the authorization server. @@ -103,6 +104,15 @@ def prepare_request_body(self, client_id=None, code=None, body='', authorization request as described in `Section 4.1.1`_, and their values MUST be identical. + :param body: Existing request body (URL encoded string) to embed parameters + into. This may contain extra paramters. Default ''. + + :param include_client_id: `True` (default) to send the `client_id` in the + body of the upstream request. This is required + if the client is not authenticating with the + authorization server as described in `Section 3.2.1`_. + :type include_client_id: Boolean + :param kwargs: Extra parameters to include in the token request. In addition OAuthLib will add the ``grant_type`` parameter set to @@ -120,12 +130,31 @@ def prepare_request_body(self, client_id=None, code=None, body='', >>> client.prepare_request_body(code='sh35ksdf09sf', foo='bar') 'grant_type=authorization_code&code=sh35ksdf09sf&foo=bar' + `Section 3.2.1` also states: + In the "authorization_code" "grant_type" request to the token + endpoint, an unauthenticated client MUST send its "client_id" to + prevent itself from inadvertently accepting a code intended for a + client with a different "client_id". This protects the client from + substitution of the authentication code. (It provides no additional + security for the protected resource.) + .. _`Section 4.1.1`: https://tools.ietf.org/html/rfc6749#section-4.1.1 .. _`Section 3.2.1`: https://tools.ietf.org/html/rfc6749#section-3.2.1 """ code = code or self.code - return prepare_token_request('authorization_code', code=code, body=body, - client_id=self.client_id, redirect_uri=redirect_uri, **kwargs) + if 'client_id' in kwargs: + warnings.warn("`client_id` has been deprecated in favor of " + "`include_client_id`, a boolean value which will " + "include the already configured `self.client_id`.", + DeprecationWarning) + if kwargs['client_id'] != self.client_id: + raise ValueError("`client_id` was supplied as an argument, but " + "it does not match `self.client_id`") + + kwargs['client_id'] = self.client_id + kwargs['include_client_id'] = include_client_id + return prepare_token_request(self.grant_type, code=code, body=body, + redirect_uri=redirect_uri, **kwargs) def parse_request_uri_response(self, uri, state=None): """Parse the URI query for code and state. diff --git a/ext/oauthlib/oauth2/rfc6749/endpoints/__init__.py b/ext/oauthlib/oauth2/rfc6749/endpoints/__init__.py index 848bec6bd8..51e173df3c 100644 --- a/ext/oauthlib/oauth2/rfc6749/endpoints/__init__.py +++ b/ext/oauthlib/oauth2/rfc6749/endpoints/__init__.py @@ -9,6 +9,8 @@ from __future__ import absolute_import, unicode_literals from .authorization import AuthorizationEndpoint +from .introspect import IntrospectEndpoint +from .metadata import MetadataEndpoint from .token import TokenEndpoint from .resource import ResourceEndpoint from .revocation import RevocationEndpoint diff --git a/ext/oauthlib/oauth2/rfc6749/endpoints/base.py b/ext/oauthlib/oauth2/rfc6749/endpoints/base.py index cdb015f3e5..c0fc726911 100644 --- a/ext/oauthlib/oauth2/rfc6749/endpoints/base.py +++ b/ext/oauthlib/oauth2/rfc6749/endpoints/base.py @@ -12,7 +12,8 @@ import logging from ..errors import (FatalClientError, OAuth2Error, ServerError, - TemporarilyUnavailableError) + TemporarilyUnavailableError, InvalidRequestError, + InvalidClientError, UnsupportedTokenTypeError) log = logging.getLogger(__name__) @@ -39,6 +40,28 @@ def catch_errors(self): def catch_errors(self, catch_errors): self._catch_errors = catch_errors + def _raise_on_missing_token(self, request): + """Raise error on missing token.""" + if not request.token: + raise InvalidRequestError(request=request, + description='Missing token parameter.') + def _raise_on_invalid_client(self, request): + """Raise on failed client authentication.""" + if self.request_validator.client_authentication_required(request): + if not self.request_validator.authenticate_client(request): + log.debug('Client authentication failed, %r.', request) + raise InvalidClientError(request=request) + elif not self.request_validator.authenticate_client_id(request.client_id, request): + log.debug('Client authentication failed, %r.', request) + raise InvalidClientError(request=request) + + def _raise_on_unsupported_token(self, request): + """Raise on unsupported tokens.""" + if (request.token_type_hint and + request.token_type_hint in self.valid_token_types and + request.token_type_hint not in self.supported_token_types): + raise UnsupportedTokenTypeError(request=request) + def catch_errors_and_unavailability(f): @functools.wraps(f) diff --git a/ext/oauthlib/oauth2/rfc6749/endpoints/introspect.py b/ext/oauthlib/oauth2/rfc6749/endpoints/introspect.py new file mode 100644 index 0000000000..ff7a32d79b --- /dev/null +++ b/ext/oauthlib/oauth2/rfc6749/endpoints/introspect.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- +""" +oauthlib.oauth2.rfc6749.endpoint.introspect +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An implementation of the OAuth 2.0 `Token Introspection`. + +.. _`Token Introspection`: https://tools.ietf.org/html/rfc7662 +""" +from __future__ import absolute_import, unicode_literals + +import json +import logging + +from oauthlib.common import Request + +from ..errors import OAuth2Error, UnsupportedTokenTypeError +from .base import BaseEndpoint, catch_errors_and_unavailability + +log = logging.getLogger(__name__) + + +class IntrospectEndpoint(BaseEndpoint): + + """Introspect token endpoint. + + This endpoint defines a method to query an OAuth 2.0 authorization + server to determine the active state of an OAuth 2.0 token and to + determine meta-information about this token. OAuth 2.0 deployments + can use this method to convey information about the authorization + context of the token from the authorization server to the protected + resource. + + To prevent the values of access tokens from leaking into + server-side logs via query parameters, an authorization server + offering token introspection MAY disallow the use of HTTP GET on + the introspection endpoint and instead require the HTTP POST method + to be used at the introspection endpoint. + """ + + valid_token_types = ('access_token', 'refresh_token') + + def __init__(self, request_validator, supported_token_types=None): + BaseEndpoint.__init__(self) + self.request_validator = request_validator + self.supported_token_types = ( + supported_token_types or self.valid_token_types) + + @catch_errors_and_unavailability + def create_introspect_response(self, uri, http_method='POST', body=None, + headers=None): + """Create introspect valid or invalid response + + If the authorization server is unable to determine the state + of the token without additional information, it SHOULD return + an introspection response indicating the token is not active + as described in Section 2.2. + """ + headers = { + 'Content-Type': 'application/json', + 'Cache-Control': 'no-store', + 'Pragma': 'no-cache', + } + request = Request(uri, http_method, body, headers) + try: + self.validate_introspect_request(request) + log.debug('Token introspect valid for %r.', request) + except OAuth2Error as e: + log.debug('Client error during validation of %r. %r.', request, e) + headers.update(e.headers) + return headers, e.json, e.status_code + + claims = self.request_validator.introspect_token( + request.token, + request.token_type_hint, + request + ) + if claims is None: + return headers, json.dumps(dict(active=False)), 200 + if "active" in claims: + claims.pop("active") + return headers, json.dumps(dict(active=True, **claims)), 200 + + def validate_introspect_request(self, request): + """Ensure the request is valid. + + The protected resource calls the introspection endpoint using + an HTTP POST request with parameters sent as + "application/x-www-form-urlencoded". + + token REQUIRED. The string value of the token. + + token_type_hint OPTIONAL. + A hint about the type of the token submitted for + introspection. The protected resource MAY pass this parameter to + help the authorization server optimize the token lookup. If the + server is unable to locate the token using the given hint, it MUST + extend its search across all of its supported token types. An + authorization server MAY ignore this parameter, particularly if it + is able to detect the token type automatically. + * access_token: An Access Token as defined in [`RFC6749`], + `section 1.4`_ + + * refresh_token: A Refresh Token as defined in [`RFC6749`], + `section 1.5`_ + + The introspection endpoint MAY accept other OPTIONAL + parameters to provide further context to the query. For + instance, an authorization server may desire to know the IP + address of the client accessing the protected resource to + determine if the correct client is likely to be presenting the + token. The definition of this or any other parameters are + outside the scope of this specification, to be defined by + service documentation or extensions to this specification. + + .. _`section 1.4`: http://tools.ietf.org/html/rfc6749#section-1.4 + .. _`section 1.5`: http://tools.ietf.org/html/rfc6749#section-1.5 + .. _`RFC6749`: http://tools.ietf.org/html/rfc6749 + """ + self._raise_on_missing_token(request) + self._raise_on_invalid_client(request) + self._raise_on_unsupported_token(request) diff --git a/ext/oauthlib/oauth2/rfc6749/endpoints/metadata.py b/ext/oauthlib/oauth2/rfc6749/endpoints/metadata.py new file mode 100644 index 0000000000..936e878863 --- /dev/null +++ b/ext/oauthlib/oauth2/rfc6749/endpoints/metadata.py @@ -0,0 +1,242 @@ +# -*- coding: utf-8 -*- +""" +oauthlib.oauth2.rfc6749.endpoint.metadata +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An implementation of the `OAuth 2.0 Authorization Server Metadata`. + +.. _`OAuth 2.0 Authorization Server Metadata`: https://tools.ietf.org/html/rfc8414 +""" +from __future__ import absolute_import, unicode_literals + +import copy +import json +import logging + +from ....common import unicode_type +from .base import BaseEndpoint, catch_errors_and_unavailability +from .authorization import AuthorizationEndpoint +from .introspect import IntrospectEndpoint +from .token import TokenEndpoint +from .revocation import RevocationEndpoint +from .. import grant_types + + +log = logging.getLogger(__name__) + + +class MetadataEndpoint(BaseEndpoint): + + """OAuth2.0 Authorization Server Metadata endpoint. + + This specification generalizes the metadata format defined by + `OpenID Connect Discovery 1.0` in a way that is compatible + with OpenID Connect Discovery while being applicable to a wider set + of OAuth 2.0 use cases. This is intentionally parallel to the way + that OAuth 2.0 Dynamic Client Registration Protocol [`RFC7591`_] + generalized the dynamic client registration mechanisms defined by + OpenID Connect Dynamic Client Registration 1.0 + in a way that is compatible with it. + + .. _`OpenID Connect Discovery 1.0`: https://openid.net/specs/openid-connect-discovery-1_0.html + .. _`RFC7591`: https://tools.ietf.org/html/rfc7591 + """ + + def __init__(self, endpoints, claims={}, raise_errors=True): + assert isinstance(claims, dict) + for endpoint in endpoints: + assert isinstance(endpoint, BaseEndpoint) + + BaseEndpoint.__init__(self) + self.raise_errors = raise_errors + self.endpoints = endpoints + self.initial_claims = claims + self.claims = self.validate_metadata_server() + + @catch_errors_and_unavailability + def create_metadata_response(self, uri, http_method='GET', body=None, + headers=None): + """Create metadata response + """ + headers = { + 'Content-Type': 'application/json' + } + return headers, json.dumps(self.claims), 200 + + def validate_metadata(self, array, key, is_required=False, is_list=False, is_url=False, is_issuer=False): + if not self.raise_errors: + return + + if key not in array: + if is_required: + raise ValueError("key {} is a mandatory metadata.".format(key)) + + elif is_issuer: + if not array[key].startswith("https"): + raise ValueError("key {}: {} must be an HTTPS URL".format(key, array[key])) + if "?" in array[key] or "&" in array[key] or "#" in array[key]: + raise ValueError("key {}: {} must not contain query or fragment components".format(key, array[key])) + + elif is_url: + if not array[key].startswith("http"): + raise ValueError("key {}: {} must be an URL".format(key, array[key])) + + elif is_list: + if not isinstance(array[key], list): + raise ValueError("key {}: {} must be an Array".format(key, array[key])) + for elem in array[key]: + if not isinstance(elem, unicode_type): + raise ValueError("array {}: {} must contains only string (not {})".format(key, array[key], elem)) + + def validate_metadata_token(self, claims, endpoint): + """ + If the token endpoint is used in the grant type, the value of this + parameter MUST be the same as the value of the "grant_type" + parameter passed to the token endpoint defined in the grant type + definition. + """ + self._grant_types.extend(endpoint._grant_types.keys()) + claims.setdefault("token_endpoint_auth_methods_supported", ["client_secret_post", "client_secret_basic"]) + + self.validate_metadata(claims, "token_endpoint_auth_methods_supported", is_list=True) + self.validate_metadata(claims, "token_endpoint_auth_signing_alg_values_supported", is_list=True) + self.validate_metadata(claims, "token_endpoint", is_required=True, is_url=True) + + def validate_metadata_authorization(self, claims, endpoint): + claims.setdefault("response_types_supported", + list(filter(lambda x: x != "none", endpoint._response_types.keys()))) + claims.setdefault("response_modes_supported", ["query", "fragment"]) + + # The OAuth2.0 Implicit flow is defined as a "grant type" but it is not + # using the "token" endpoint, as such, we have to add it explicitly to + # the list of "grant_types_supported" when enabled. + if "token" in claims["response_types_supported"]: + self._grant_types.append("implicit") + + self.validate_metadata(claims, "response_types_supported", is_required=True, is_list=True) + self.validate_metadata(claims, "response_modes_supported", is_list=True) + if "code" in claims["response_types_supported"]: + code_grant = endpoint._response_types["code"] + if not isinstance(code_grant, grant_types.AuthorizationCodeGrant) and hasattr(code_grant, "default_grant"): + code_grant = code_grant.default_grant + + claims.setdefault("code_challenge_methods_supported", + list(code_grant._code_challenge_methods.keys())) + self.validate_metadata(claims, "code_challenge_methods_supported", is_list=True) + self.validate_metadata(claims, "authorization_endpoint", is_required=True, is_url=True) + + def validate_metadata_revocation(self, claims, endpoint): + claims.setdefault("revocation_endpoint_auth_methods_supported", + ["client_secret_post", "client_secret_basic"]) + + self.validate_metadata(claims, "revocation_endpoint_auth_methods_supported", is_list=True) + self.validate_metadata(claims, "revocation_endpoint_auth_signing_alg_values_supported", is_list=True) + self.validate_metadata(claims, "revocation_endpoint", is_required=True, is_url=True) + + def validate_metadata_introspection(self, claims, endpoint): + claims.setdefault("introspection_endpoint_auth_methods_supported", + ["client_secret_post", "client_secret_basic"]) + + self.validate_metadata(claims, "introspection_endpoint_auth_methods_supported", is_list=True) + self.validate_metadata(claims, "introspection_endpoint_auth_signing_alg_values_supported", is_list=True) + self.validate_metadata(claims, "introspection_endpoint", is_required=True, is_url=True) + + def validate_metadata_server(self): + """ + Authorization servers can have metadata describing their + configuration. The following authorization server metadata values + are used by this specification. More details can be found in + `RFC8414 section 2`_ : + + issuer + REQUIRED + + authorization_endpoint + URL of the authorization server's authorization endpoint + [`RFC6749#Authorization`_]. This is REQUIRED unless no grant types are supported + that use the authorization endpoint. + + token_endpoint + URL of the authorization server's token endpoint [`RFC6749#Token`_]. This + is REQUIRED unless only the implicit grant type is supported. + + scopes_supported + RECOMMENDED. + + response_types_supported + REQUIRED. + + * Other OPTIONAL fields: + jwks_uri + registration_endpoint + response_modes_supported + + grant_types_supported + OPTIONAL. JSON array containing a list of the OAuth 2.0 grant + type values that this authorization server supports. The array + values used are the same as those used with the "grant_types" + parameter defined by "OAuth 2.0 Dynamic Client Registration + Protocol" [`RFC7591`_]. If omitted, the default value is + "["authorization_code", "implicit"]". + + token_endpoint_auth_methods_supported + + token_endpoint_auth_signing_alg_values_supported + + service_documentation + + ui_locales_supported + + op_policy_uri + + op_tos_uri + + revocation_endpoint + + revocation_endpoint_auth_methods_supported + + revocation_endpoint_auth_signing_alg_values_supported + + introspection_endpoint + + introspection_endpoint_auth_methods_supported + + introspection_endpoint_auth_signing_alg_values_supported + + code_challenge_methods_supported + + Additional authorization server metadata parameters MAY also be used. + Some are defined by other specifications, such as OpenID Connect + Discovery 1.0 [`OpenID.Discovery`_]. + + .. _`RFC8414 section 2`: https://tools.ietf.org/html/rfc8414#section-2 + .. _`RFC6749#Authorization`: https://tools.ietf.org/html/rfc6749#section-3.1 + .. _`RFC6749#Token`: https://tools.ietf.org/html/rfc6749#section-3.2 + .. _`RFC7591`: https://tools.ietf.org/html/rfc7591 + .. _`OpenID.Discovery`: https://openid.net/specs/openid-connect-discovery-1_0.html + """ + claims = copy.deepcopy(self.initial_claims) + self.validate_metadata(claims, "issuer", is_required=True, is_issuer=True) + self.validate_metadata(claims, "jwks_uri", is_url=True) + self.validate_metadata(claims, "scopes_supported", is_list=True) + self.validate_metadata(claims, "service_documentation", is_url=True) + self.validate_metadata(claims, "ui_locales_supported", is_list=True) + self.validate_metadata(claims, "op_policy_uri", is_url=True) + self.validate_metadata(claims, "op_tos_uri", is_url=True) + + self._grant_types = [] + for endpoint in self.endpoints: + if isinstance(endpoint, TokenEndpoint): + self.validate_metadata_token(claims, endpoint) + if isinstance(endpoint, AuthorizationEndpoint): + self.validate_metadata_authorization(claims, endpoint) + if isinstance(endpoint, RevocationEndpoint): + self.validate_metadata_revocation(claims, endpoint) + if isinstance(endpoint, IntrospectEndpoint): + self.validate_metadata_introspection(claims, endpoint) + + # "grant_types_supported" is a combination of all OAuth2 grant types + # allowed in the current provider implementation. + claims.setdefault("grant_types_supported", self._grant_types) + self.validate_metadata(claims, "grant_types_supported", is_list=True) + return claims diff --git a/ext/oauthlib/oauth2/rfc6749/endpoints/pre_configured.py b/ext/oauthlib/oauth2/rfc6749/endpoints/pre_configured.py index 6428b8d12b..e2cc9db717 100644 --- a/ext/oauthlib/oauth2/rfc6749/endpoints/pre_configured.py +++ b/ext/oauthlib/oauth2/rfc6749/endpoints/pre_configured.py @@ -1,27 +1,28 @@ # -*- coding: utf-8 -*- """ -oauthlib.oauth2.rfc6749 -~~~~~~~~~~~~~~~~~~~~~~~ +oauthlib.oauth2.rfc6749.endpoints.pre_configured +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This module is an implementation of various logic needed -for consuming and providing OAuth 2.0 RFC6749. +This module is an implementation of various endpoints needed +for providing OAuth 2.0 RFC6749 servers. """ from __future__ import absolute_import, unicode_literals -from ..grant_types import (AuthCodeGrantDispatcher, AuthorizationCodeGrant, - ClientCredentialsGrant, ImplicitGrant, - OpenIDConnectAuthCode, OpenIDConnectImplicit, +from ..grant_types import (AuthorizationCodeGrant, + ClientCredentialsGrant, + ImplicitGrant, RefreshTokenGrant, ResourceOwnerPasswordCredentialsGrant) from ..tokens import BearerToken from .authorization import AuthorizationEndpoint +from .introspect import IntrospectEndpoint from .resource import ResourceEndpoint from .revocation import RevocationEndpoint from .token import TokenEndpoint -class Server(AuthorizationEndpoint, TokenEndpoint, ResourceEndpoint, - RevocationEndpoint): +class Server(AuthorizationEndpoint, IntrospectEndpoint, TokenEndpoint, + ResourceEndpoint, RevocationEndpoint): """An all-in-one endpoint featuring all four major grant types.""" @@ -47,44 +48,34 @@ def __init__(self, request_validator, token_expires_in=None, request_validator) credentials_grant = ClientCredentialsGrant(request_validator) refresh_grant = RefreshTokenGrant(request_validator) - openid_connect_auth = OpenIDConnectAuthCode(request_validator) - openid_connect_implicit = OpenIDConnectImplicit(request_validator) bearer = BearerToken(request_validator, token_generator, token_expires_in, refresh_token_generator) - auth_grant_choice = AuthCodeGrantDispatcher( default_auth_grant=auth_grant, oidc_auth_grant=openid_connect_auth) - - # See http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#Combinations for valid combinations - # internally our AuthorizationEndpoint will ensure they can appear in any order for any valid combination AuthorizationEndpoint.__init__(self, default_response_type='code', response_types={ - 'code': auth_grant_choice, + 'code': auth_grant, 'token': implicit_grant, - 'id_token': openid_connect_implicit, - 'id_token token': openid_connect_implicit, - 'code token': openid_connect_auth, - 'code id_token': openid_connect_auth, - 'code token id_token': openid_connect_auth, 'none': auth_grant }, default_token_type=bearer) + TokenEndpoint.__init__(self, default_grant_type='authorization_code', grant_types={ 'authorization_code': auth_grant, 'password': password_grant, 'client_credentials': credentials_grant, 'refresh_token': refresh_grant, - 'openid': openid_connect_auth }, default_token_type=bearer) ResourceEndpoint.__init__(self, default_token='Bearer', token_types={'Bearer': bearer}) RevocationEndpoint.__init__(self, request_validator) + IntrospectEndpoint.__init__(self, request_validator) -class WebApplicationServer(AuthorizationEndpoint, TokenEndpoint, ResourceEndpoint, - RevocationEndpoint): +class WebApplicationServer(AuthorizationEndpoint, IntrospectEndpoint, TokenEndpoint, + ResourceEndpoint, RevocationEndpoint): """An all-in-one endpoint featuring Authorization code grant and Bearer tokens.""" @@ -119,10 +110,11 @@ def __init__(self, request_validator, token_generator=None, ResourceEndpoint.__init__(self, default_token='Bearer', token_types={'Bearer': bearer}) RevocationEndpoint.__init__(self, request_validator) + IntrospectEndpoint.__init__(self, request_validator) -class MobileApplicationServer(AuthorizationEndpoint, ResourceEndpoint, - RevocationEndpoint): +class MobileApplicationServer(AuthorizationEndpoint, IntrospectEndpoint, + ResourceEndpoint, RevocationEndpoint): """An all-in-one endpoint featuring Implicit code grant and Bearer tokens.""" @@ -152,10 +144,12 @@ def __init__(self, request_validator, token_generator=None, token_types={'Bearer': bearer}) RevocationEndpoint.__init__(self, request_validator, supported_token_types=['access_token']) + IntrospectEndpoint.__init__(self, request_validator, + supported_token_types=['access_token']) -class LegacyApplicationServer(TokenEndpoint, ResourceEndpoint, - RevocationEndpoint): +class LegacyApplicationServer(TokenEndpoint, IntrospectEndpoint, + ResourceEndpoint, RevocationEndpoint): """An all-in-one endpoint featuring Resource Owner Password Credentials grant and Bearer tokens.""" @@ -188,10 +182,11 @@ def __init__(self, request_validator, token_generator=None, ResourceEndpoint.__init__(self, default_token='Bearer', token_types={'Bearer': bearer}) RevocationEndpoint.__init__(self, request_validator) + IntrospectEndpoint.__init__(self, request_validator) -class BackendApplicationServer(TokenEndpoint, ResourceEndpoint, - RevocationEndpoint): +class BackendApplicationServer(TokenEndpoint, IntrospectEndpoint, + ResourceEndpoint, RevocationEndpoint): """An all-in-one endpoint featuring Client Credentials grant and Bearer tokens.""" @@ -221,3 +216,5 @@ def __init__(self, request_validator, token_generator=None, token_types={'Bearer': bearer}) RevocationEndpoint.__init__(self, request_validator, supported_token_types=['access_token']) + IntrospectEndpoint.__init__(self, request_validator, + supported_token_types=['access_token']) diff --git a/ext/oauthlib/oauth2/rfc6749/endpoints/resource.py b/ext/oauthlib/oauth2/rfc6749/endpoints/resource.py index d03ed2145b..f19c60c369 100644 --- a/ext/oauthlib/oauth2/rfc6749/endpoints/resource.py +++ b/ext/oauthlib/oauth2/rfc6749/endpoints/resource.py @@ -83,5 +83,5 @@ def find_token_type(self, request): to give an estimation based on the request. """ estimates = sorted(((t.estimate_type(request), n) - for n, t in self.tokens.items())) + for n, t in self.tokens.items()), reverse=True) return estimates[0][1] if len(estimates) else None diff --git a/ext/oauthlib/oauth2/rfc6749/endpoints/revocation.py b/ext/oauthlib/oauth2/rfc6749/endpoints/revocation.py index d5b5b78294..4cd96a7e1a 100644 --- a/ext/oauthlib/oauth2/rfc6749/endpoints/revocation.py +++ b/ext/oauthlib/oauth2/rfc6749/endpoints/revocation.py @@ -13,8 +13,7 @@ from oauthlib.common import Request -from ..errors import (InvalidClientError, InvalidRequestError, OAuth2Error, - UnsupportedTokenTypeError) +from ..errors import OAuth2Error, UnsupportedTokenTypeError from .base import BaseEndpoint, catch_errors_and_unavailability log = logging.getLogger(__name__) @@ -59,6 +58,11 @@ def create_revocation_response(self, uri, http_method='POST', body=None, An invalid token type hint value is ignored by the authorization server and does not influence the revocation response. """ + headers = { + 'Content-Type': 'application/json', + 'Cache-Control': 'no-store', + 'Pragma': 'no-cache', + } request = Request( uri, http_method=http_method, body=body, headers=headers) try: @@ -69,7 +73,8 @@ def create_revocation_response(self, uri, http_method='POST', body=None, response_body = e.json if self.enable_jsonp and request.callback: response_body = '%s(%s);' % (request.callback, response_body) - return {}, response_body, e.status_code + headers.update(e.headers) + return headers, response_body, e.status_code self.request_validator.revoke_token(request.token, request.token_type_hint, request) @@ -116,19 +121,6 @@ def validate_revocation_request(self, request): .. _`Section 4.1.2`: https://tools.ietf.org/html/draft-ietf-oauth-revocation-11#section-4.1.2 .. _`RFC6749`: https://tools.ietf.org/html/rfc6749 """ - if not request.token: - raise InvalidRequestError(request=request, - description='Missing token parameter.') - - if self.request_validator.client_authentication_required(request): - if not self.request_validator.authenticate_client(request): - log.debug('Client authentication failed, %r.', request) - raise InvalidClientError(request=request) - elif not self.request_validator.authenticate_client_id(request.client_id, request): - log.debug('Client authentication failed, %r.', request) - raise InvalidClientError(request=request) - - if (request.token_type_hint and - request.token_type_hint in self.valid_token_types and - request.token_type_hint not in self.supported_token_types): - raise UnsupportedTokenTypeError(request=request) + self._raise_on_missing_token(request) + self._raise_on_invalid_client(request) + self._raise_on_unsupported_token(request) diff --git a/ext/oauthlib/oauth2/rfc6749/errors.py b/ext/oauthlib/oauth2/rfc6749/errors.py index 180f636329..d2a14026a9 100644 --- a/ext/oauthlib/oauth2/rfc6749/errors.py +++ b/ext/oauthlib/oauth2/rfc6749/errors.py @@ -21,23 +21,26 @@ class OAuth2Error(Exception): def __init__(self, description=None, uri=None, state=None, status_code=None, request=None): """ - description: A human-readable ASCII [USASCII] text providing - additional information, used to assist the client - developer in understanding the error that occurred. - Values for the "error_description" parameter MUST NOT - include characters outside the set - x20-21 / x23-5B / x5D-7E. - - uri: A URI identifying a human-readable web page with information - about the error, used to provide the client developer with - additional information about the error. Values for the - "error_uri" parameter MUST conform to the URI- Reference - syntax, and thus MUST NOT include characters outside the set - x21 / x23-5B / x5D-7E. - - state: A CSRF protection value received from the client. - - request: Oauthlib Request object + :param description: A human-readable ASCII [USASCII] text providing + additional information, used to assist the client + developer in understanding the error that occurred. + Values for the "error_description" parameter + MUST NOT include characters outside the set + x20-21 / x23-5B / x5D-7E. + + :param uri: A URI identifying a human-readable web page with information + about the error, used to provide the client developer with + additional information about the error. Values for the + "error_uri" parameter MUST conform to the URI- Reference + syntax, and thus MUST NOT include characters outside the set + x21 / x23-5B / x5D-7E. + + :param state: A CSRF protection value received from the client. + + :param status_code: + + :param request: OAuthlib request. + :type request: oauthlib.common.Request """ if description is not None: self.description = description @@ -93,6 +96,27 @@ def urlencoded(self): def json(self): return json.dumps(dict(self.twotuples)) + @property + def headers(self): + if self.status_code == 401: + """ + https://tools.ietf.org/html/rfc6750#section-3 + + All challenges defined by this specification MUST use the auth-scheme + value "Bearer". This scheme MUST be followed by one or more + auth-param values. + """ + authvalues = [ + "Bearer", + 'error="{}"'.format(self.error) + ] + if self.description: + authvalues.append('error_description="{}"'.format(self.description)) + if self.uri: + authvalues.append('error_uri="{}"'.format(self.uri)) + return {"WWW-Authenticate": ", ".join(authvalues)} + return {} + class TokenExpiredError(OAuth2Error): error = 'token_expired' @@ -177,12 +201,31 @@ class MissingResponseTypeError(InvalidRequestError): description = 'Missing response_type parameter.' +class MissingCodeChallengeError(InvalidRequestError): + """ + If the server requires Proof Key for Code Exchange (PKCE) by OAuth + public clients and the client does not send the "code_challenge" in + the request, the authorization endpoint MUST return the authorization + error response with the "error" value set to "invalid_request". The + "error_description" or the response of "error_uri" SHOULD explain the + nature of error, e.g., code challenge required. + """ + description = 'Code challenge required.' + + +class MissingCodeVerifierError(InvalidRequestError): + """ + The request to the token endpoint, when PKCE is enabled, has + the parameter `code_verifier` REQUIRED. + """ + description = 'Code verifier required.' + + class AccessDeniedError(OAuth2Error): """ The resource owner or authorization server denied the request. """ error = 'access_denied' - status_code = 401 class UnsupportedResponseTypeError(OAuth2Error): @@ -193,12 +236,26 @@ class UnsupportedResponseTypeError(OAuth2Error): error = 'unsupported_response_type' +class UnsupportedCodeChallengeMethodError(InvalidRequestError): + """ + If the server supporting PKCE does not support the requested + transformation, the authorization endpoint MUST return the + authorization error response with "error" value set to + "invalid_request". The "error_description" or the response of + "error_uri" SHOULD explain the nature of error, e.g., transform + algorithm not supported. + """ + description = 'Transform algorithm not supported.' + + class InvalidScopeError(OAuth2Error): """ - The requested scope is invalid, unknown, or malformed. + The requested scope is invalid, unknown, or malformed, or + exceeds the scope granted by the resource owner. + + https://tools.ietf.org/html/rfc6749#section-5.2 """ error = 'invalid_scope' - status_code = 401 class ServerError(OAuth2Error): @@ -221,7 +278,7 @@ class TemporarilyUnavailableError(OAuth2Error): error = 'temporarily_unavailable' -class InvalidClientError(OAuth2Error): +class InvalidClientError(FatalClientError): """ Client authentication failed (e.g. unknown client, no client authentication included, or unsupported authentication method). @@ -243,9 +300,11 @@ class InvalidGrantError(OAuth2Error): owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. + + https://tools.ietf.org/html/rfc6749#section-5.2 """ error = 'invalid_grant' - status_code = 401 + status_code = 400 class UnauthorizedClientError(OAuth2Error): @@ -254,7 +313,6 @@ class UnauthorizedClientError(OAuth2Error): grant type. """ error = 'unauthorized_client' - status_code = 401 class UnsupportedGrantTypeError(OAuth2Error): @@ -267,113 +325,13 @@ class UnsupportedGrantTypeError(OAuth2Error): class UnsupportedTokenTypeError(OAuth2Error): """ - The authorization server does not support the revocation of the + The authorization server does not support the hint of the presented token type. I.e. the client tried to revoke an access token on a server not supporting this feature. """ error = 'unsupported_token_type' -class FatalOpenIDClientError(FatalClientError): - pass - - -class OpenIDClientError(OAuth2Error): - pass - - -class InteractionRequired(OpenIDClientError): - """ - The Authorization Server requires End-User interaction to proceed. - - This error MAY be returned when the prompt parameter value in the - Authentication Request is none, but the Authentication Request cannot be - completed without displaying a user interface for End-User interaction. - """ - error = 'interaction_required' - status_code = 401 - - -class LoginRequired(OpenIDClientError): - """ - The Authorization Server requires End-User authentication. - - This error MAY be returned when the prompt parameter value in the - Authentication Request is none, but the Authentication Request cannot be - completed without displaying a user interface for End-User authentication. - """ - error = 'login_required' - status_code = 401 - - -class AccountSelectionRequired(OpenIDClientError): - """ - The End-User is REQUIRED to select a session at the Authorization Server. - - The End-User MAY be authenticated at the Authorization Server with - different associated accounts, but the End-User did not select a session. - This error MAY be returned when the prompt parameter value in the - Authentication Request is none, but the Authentication Request cannot be - completed without displaying a user interface to prompt for a session to - use. - """ - error = 'account_selection_required' - - -class ConsentRequired(OpenIDClientError): - """ - The Authorization Server requires End-User consent. - - This error MAY be returned when the prompt parameter value in the - Authentication Request is none, but the Authentication Request cannot be - completed without displaying a user interface for End-User consent. - """ - error = 'consent_required' - status_code = 401 - - -class InvalidRequestURI(OpenIDClientError): - """ - The request_uri in the Authorization Request returns an error or - contains invalid data. - """ - error = 'invalid_request_uri' - description = 'The request_uri in the Authorization Request returns an ' \ - 'error or contains invalid data.' - - -class InvalidRequestObject(OpenIDClientError): - """ - The request parameter contains an invalid Request Object. - """ - error = 'invalid_request_object' - description = 'The request parameter contains an invalid Request Object.' - - -class RequestNotSupported(OpenIDClientError): - """ - The OP does not support use of the request parameter. - """ - error = 'request_not_supported' - description = 'The request parameter is not supported.' - - -class RequestURINotSupported(OpenIDClientError): - """ - The OP does not support use of the request_uri parameter. - """ - error = 'request_uri_not_supported' - description = 'The request_uri parameter is not supported.' - - -class RegistrationNotSupported(OpenIDClientError): - """ - The OP does not support use of the registration parameter. - """ - error = 'registration_not_supported' - description = 'The registration parameter is not supported.' - - class InvalidTokenError(OAuth2Error): """ The access token provided is expired, revoked, malformed, or @@ -402,6 +360,38 @@ class InsufficientScopeError(OAuth2Error): "the access token.") +class ConsentRequired(OAuth2Error): + """ + The Authorization Server requires End-User consent. + + This error MAY be returned when the prompt parameter value in the + Authentication Request is none, but the Authentication Request cannot be + completed without displaying a user interface for End-User consent. + """ + error = 'consent_required' + + +class LoginRequired(OAuth2Error): + """ + The Authorization Server requires End-User authentication. + + This error MAY be returned when the prompt parameter value in the + Authentication Request is none, but the Authentication Request cannot be + completed without displaying a user interface for End-User authentication. + """ + error = 'login_required' + + +class CustomOAuth2Error(OAuth2Error): + """ + This error is a placeholder for all custom errors not described by the RFC. + Some of the popular OAuth2 providers are using custom errors. + """ + def __init__(self, error, *args, **kwargs): + self.error = error + super(CustomOAuth2Error, self).__init__(*args, **kwargs) + + def raise_from_error(error, params=None): import inspect import sys @@ -413,3 +403,4 @@ def raise_from_error(error, params=None): for _, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass): if cls.error == error: raise cls(**kwargs) + raise CustomOAuth2Error(error=error, **kwargs) diff --git a/ext/oauthlib/oauth2/rfc6749/grant_types/__init__.py b/ext/oauthlib/oauth2/rfc6749/grant_types/__init__.py index 1da1281f01..2ec8e4faa4 100644 --- a/ext/oauthlib/oauth2/rfc6749/grant_types/__init__.py +++ b/ext/oauthlib/oauth2/rfc6749/grant_types/__init__.py @@ -10,9 +10,3 @@ from .resource_owner_password_credentials import ResourceOwnerPasswordCredentialsGrant from .client_credentials import ClientCredentialsGrant from .refresh_token import RefreshTokenGrant -from .openid_connect import OpenIDConnectBase -from .openid_connect import OpenIDConnectAuthCode -from .openid_connect import OpenIDConnectImplicit -from .openid_connect import OpenIDConnectHybrid -from .openid_connect import OIDCNoPrompt -from .openid_connect import AuthCodeGrantDispatcher diff --git a/ext/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py b/ext/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py index 0660263400..64633917f3 100644 --- a/ext/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py +++ b/ext/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py @@ -5,11 +5,12 @@ """ from __future__ import absolute_import, unicode_literals +import base64 +import hashlib import json import logging from oauthlib import common -from oauthlib.uri_validate import is_absolute_uri from .. import errors from .base import GrantTypeBase @@ -17,6 +18,52 @@ log = logging.getLogger(__name__) +def code_challenge_method_s256(verifier, challenge): + """ + If the "code_challenge_method" from `Section 4.3`_ was "S256", the + received "code_verifier" is hashed by SHA-256, base64url-encoded, and + then compared to the "code_challenge", i.e.: + + BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) == code_challenge + + How to implement a base64url-encoding + function without padding, based upon the standard base64-encoding + function that uses padding. + + To be concrete, example C# code implementing these functions is shown + below. Similar code could be used in other languages. + + static string base64urlencode(byte [] arg) + { + string s = Convert.ToBase64String(arg); // Regular base64 encoder + s = s.Split('=')[0]; // Remove any trailing '='s + s = s.Replace('+', '-'); // 62nd char of encoding + s = s.Replace('/', '_'); // 63rd char of encoding + return s; + } + + In python urlsafe_b64encode is already replacing '+' and '/', but preserve + the trailing '='. So we have to remove it. + + .. _`Section 4.3`: https://tools.ietf.org/html/rfc7636#section-4.3 + """ + return base64.urlsafe_b64encode( + hashlib.sha256(verifier.encode()).digest() + ).decode().rstrip('=') == challenge + + +def code_challenge_method_plain(verifier, challenge): + """ + If the "code_challenge_method" from `Section 4.3`_ was "plain", they are + compared directly, i.e.: + + code_verifier == code_challenge. + + .. _`Section 4.3`: https://tools.ietf.org/html/rfc7636#section-4.3 + """ + return verifier == challenge + + class AuthorizationCodeGrant(GrantTypeBase): """`Authorization Code Grant`_ @@ -91,14 +138,35 @@ class AuthorizationCodeGrant(GrantTypeBase): step (C). If valid, the authorization server responds back with an access token and, optionally, a refresh token. + OAuth 2.0 public clients utilizing the Authorization Code Grant are + susceptible to the authorization code interception attack. + + A technique to mitigate against the threat through the use of Proof Key for Code + Exchange (PKCE, pronounced "pixy") is implemented in the current oauthlib + implementation. + .. _`Authorization Code Grant`: https://tools.ietf.org/html/rfc6749#section-4.1 + .. _`PKCE`: https://tools.ietf.org/html/rfc7636 """ default_response_mode = 'query' response_types = ['code'] + # This dict below is private because as RFC mention it: + # "S256" is Mandatory To Implement (MTI) on the server. + # + _code_challenge_methods = { + 'plain': code_challenge_method_plain, + 'S256': code_challenge_method_s256 + } + def create_authorization_code(self, request): - """Generates an authorization grant represented as a dictionary.""" + """ + Generates an authorization grant represented as a dictionary. + + :param request: OAuthlib request. + :type request: oauthlib.common.Request + """ grant = {'code': common.generate_token()} if hasattr(request, 'state') and request.state: grant['state'] = request.state @@ -135,12 +203,12 @@ def create_authorization_response(self, request, token_handler): HTTP redirection response, or by other means available to it via the user-agent. - :param request: oauthlib.commong.Request - :param token_handler: A token handler instace, for example of type + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :param token_handler: A token handler instance, for example of type oauthlib.oauth2.BearerToken. :returns: headers, body, status :raises: FatalClientError on invalid redirect URI or client id. - ValueError if scopes are not set on the request object. A few examples:: @@ -151,12 +219,6 @@ def create_authorization_response(self, request, token_handler): >>> from oauthlib.oauth2 import AuthorizationCodeGrant, BearerToken >>> token = BearerToken(your_validator) >>> grant = AuthorizationCodeGrant(your_validator) - >>> grant.create_authorization_response(request, token) - Traceback (most recent call last): - File "", line 1, in - File "oauthlib/oauth2/rfc6749/grant_types.py", line 513, in create_authorization_response - raise ValueError('Scopes must be set on post auth.') - ValueError: Scopes must be set on post auth. >>> request.scopes = ['authorized', 'in', 'some', 'form'] >>> grant.create_authorization_response(request, token) (u'http://client.com/?error=invalid_request&error_description=Missing+response_type+parameter.', None, None, 400) @@ -182,11 +244,6 @@ def create_authorization_response(self, request, token_handler): .. _`Section 10.12`: https://tools.ietf.org/html/rfc6749#section-10.12 """ try: - # request.scopes is only mandated in post auth and both pre and - # post auth use validate_authorization_request - if not request.scopes: - raise ValueError('Scopes must be set on post auth.') - self.validate_authorization_request(request) log.debug('Pre resource owner authorization validation ok for %r.', request) @@ -232,17 +289,20 @@ def create_token_response(self, request, token_handler): MUST deny the request and SHOULD revoke (when possible) all tokens previously issued based on that authorization code. The authorization code is bound to the client identifier and redirection URI. + + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :param token_handler: A token handler instance, for example of type + oauthlib.oauth2.BearerToken. + """ - headers = { - 'Content-Type': 'application/json', - 'Cache-Control': 'no-store', - 'Pragma': 'no-cache', - } + headers = self._get_default_headers() try: self.validate_token_request(request) log.debug('Token request validation ok for %r.', request) except errors.OAuth2Error as e: log.debug('Client error during validation of %r. %r.', request, e) + headers.update(e.headers) return headers, e.json, e.status_code token = token_handler.create_token(request, refresh_token=self.refresh_token, save_token=False) @@ -265,6 +325,9 @@ def validate_authorization_request(self, request): missing. These must be caught by the provider and handled, how this is done is outside of the scope of OAuthLib but showing an error page describing the issue is a good idea. + + :param request: OAuthlib request. + :type request: oauthlib.common.Request """ # First check for fatal errors @@ -296,22 +359,10 @@ def validate_authorization_request(self, request): # https://tools.ietf.org/html/rfc6749#section-3.1.2 log.debug('Validating redirection uri %s for client %s.', request.redirect_uri, request.client_id) - if request.redirect_uri is not None: - request.using_default_redirect_uri = False - log.debug('Using provided redirect_uri %s', request.redirect_uri) - if not is_absolute_uri(request.redirect_uri): - raise errors.InvalidRedirectURIError(request=request) - if not self.request_validator.validate_redirect_uri( - request.client_id, request.redirect_uri, request): - raise errors.MismatchingRedirectURIError(request=request) - else: - request.redirect_uri = self.request_validator.get_default_redirect_uri( - request.client_id, request) - request.using_default_redirect_uri = True - log.debug('Using default redirect_uri %s.', request.redirect_uri) - if not request.redirect_uri: - raise errors.MissingRedirectURIError(request=request) + # OPTIONAL. As described in Section 3.1.2. + # https://tools.ietf.org/html/rfc6749#section-3.1.2 + self._handle_redirects(request) # Then check for normal errors. @@ -345,6 +396,20 @@ def validate_authorization_request(self, request): request.client_id, request.response_type) raise errors.UnauthorizedClientError(request=request) + # OPTIONAL. Validate PKCE request or reply with "error"/"invalid_request" + # https://tools.ietf.org/html/rfc6749#section-4.4.1 + if self.request_validator.is_pkce_required(request.client_id, request) is True: + if request.code_challenge is None: + raise errors.MissingCodeChallengeError(request=request) + + if request.code_challenge is not None: + # OPTIONAL, defaults to "plain" if not present in the request. + if request.code_challenge_method is None: + request.code_challenge_method = "plain" + + if request.code_challenge_method not in self._code_challenge_methods: + raise errors.UnsupportedCodeChallengeMethodError(request=request) + # OPTIONAL. The scope of the access request as described by Section 3.3 # https://tools.ietf.org/html/rfc6749#section-3.3 self.validate_scopes(request) @@ -363,6 +428,10 @@ def validate_authorization_request(self, request): return request.scopes, request_info def validate_token_request(self, request): + """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + """ # REQUIRED. Value MUST be set to "authorization_code". if request.grant_type not in ('authorization_code', 'openid'): raise errors.UnsupportedGrantTypeError(request=request) @@ -413,6 +482,33 @@ def validate_token_request(self, request): request.client_id, request.client, request.scopes) raise errors.InvalidGrantError(request=request) + # OPTIONAL. Validate PKCE code_verifier + challenge = self.request_validator.get_code_challenge(request.code, request) + + if challenge is not None: + if request.code_verifier is None: + raise errors.MissingCodeVerifierError(request=request) + + challenge_method = self.request_validator.get_code_challenge_method(request.code, request) + if challenge_method is None: + raise errors.InvalidGrantError(request=request, description="Challenge method not found") + + if challenge_method not in self._code_challenge_methods: + raise errors.ServerError( + description="code_challenge_method {} is not supported.".format(challenge_method), + request=request + ) + + if not self.validate_code_challenge(challenge, + challenge_method, + request.code_verifier): + log.debug('request provided a invalid code_verifier.') + raise errors.InvalidGrantError(request=request) + elif self.request_validator.is_pkce_required(request.client_id, request) is True: + if request.code_verifier is None: + raise errors.MissingCodeVerifierError(request=request) + raise errors.InvalidGrantError(request=request, description="Challenge not found") + for attr in ('user', 'scopes'): if getattr(request, attr, None) is None: log.debug('request.%s was not set on code validation.', attr) @@ -420,6 +516,17 @@ def validate_token_request(self, request): # REQUIRED, if the "redirect_uri" parameter was included in the # authorization request as described in Section 4.1.1, and their # values MUST be identical. + if request.redirect_uri is None: + request.using_default_redirect_uri = True + request.redirect_uri = self.request_validator.get_default_redirect_uri( + request.client_id, request) + log.debug('Using default redirect_uri %s.', request.redirect_uri) + if not request.redirect_uri: + raise errors.MissingRedirectURIError(request=request) + else: + request.using_default_redirect_uri = False + log.debug('Using provided redirect_uri %s', request.redirect_uri) + if not self.request_validator.confirm_redirect_uri(request.client_id, request.code, request.redirect_uri, request.client, request): @@ -429,3 +536,8 @@ def validate_token_request(self, request): for validator in self.custom_validators.post_token: validator(request) + + def validate_code_challenge(self, challenge, challenge_method, verifier): + if challenge_method in self._code_challenge_methods: + return self._code_challenge_methods[challenge_method](verifier, challenge) + raise NotImplementedError('Unknown challenge_method %s' % challenge_method) diff --git a/ext/oauthlib/oauth2/rfc6749/grant_types/base.py b/ext/oauthlib/oauth2/rfc6749/grant_types/base.py index e5d8ddd12a..f0772e2874 100644 --- a/ext/oauthlib/oauth2/rfc6749/grant_types/base.py +++ b/ext/oauthlib/oauth2/rfc6749/grant_types/base.py @@ -9,51 +9,53 @@ from itertools import chain from oauthlib.common import add_params_to_uri +from oauthlib.uri_validate import is_absolute_uri from oauthlib.oauth2.rfc6749 import errors, utils from ..request_validator import RequestValidator log = logging.getLogger(__name__) + class ValidatorsContainer(object): """ - Container object for holding custom validator callables to be invoked - as part of the grant type `validate_authorization_request()` or - `validate_authorization_request()` methods on the various grant types. + Container object for holding custom validator callables to be invoked + as part of the grant type `validate_authorization_request()` or + `validate_authorization_request()` methods on the various grant types. - Authorization validators must be callables that take a request object and - return a dict, which may contain items to be added to the `request_info` - returned from the grant_type after validation. + Authorization validators must be callables that take a request object and + return a dict, which may contain items to be added to the `request_info` + returned from the grant_type after validation. - Token validators must be callables that take a request object and - return None. + Token validators must be callables that take a request object and + return None. - Both authorization validators and token validators may raise OAuth2 - exceptions if validation conditions fail. + Both authorization validators and token validators may raise OAuth2 + exceptions if validation conditions fail. - Authorization validators added to `pre_auth` will be run BEFORE - the standard validations (but after the critical ones that raise - fatal errors) as part of `validate_authorization_request()` + Authorization validators added to `pre_auth` will be run BEFORE + the standard validations (but after the critical ones that raise + fatal errors) as part of `validate_authorization_request()` - Authorization validators added to `post_auth` will be run AFTER - the standard validations as part of `validate_authorization_request()` + Authorization validators added to `post_auth` will be run AFTER + the standard validations as part of `validate_authorization_request()` - Token validators added to `pre_token` will be run BEFORE - the standard validations as part of `validate_token_request()` + Token validators added to `pre_token` will be run BEFORE + the standard validations as part of `validate_token_request()` - Token validators added to `post_token` will be run AFTER - the standard validations as part of `validate_token_request()` + Token validators added to `post_token` will be run AFTER + the standard validations as part of `validate_token_request()` - For example: + For example: - >>> def my_auth_validator(request): - ... return {'myval': True} - >>> auth_code_grant = AuthorizationCodeGrant(request_validator) - >>> auth_code_grant.custom_validators.pre_auth.append(my_auth_validator) - >>> def my_token_validator(request): - ... if not request.everything_okay: - ... raise errors.OAuth2Error("uh-oh") - >>> auth_code_grant.custom_validators.post_token.append(my_token_validator) + >>> def my_auth_validator(request): + ... return {'myval': True} + >>> auth_code_grant = AuthorizationCodeGrant(request_validator) + >>> auth_code_grant.custom_validators.pre_auth.append(my_auth_validator) + >>> def my_token_validator(request): + ... if not request.everything_okay: + ... raise errors.OAuth2Error("uh-oh") + >>> auth_code_grant.custom_validators.post_token.append(my_token_validator) """ def __init__(self, post_auth, post_token, @@ -116,14 +118,32 @@ def register_code_modifier(self, modifier): def register_token_modifier(self, modifier): self._token_modifiers.append(modifier) - def create_authorization_response(self, request, token_handler): + """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :param token_handler: A token handler instance, for example of type + oauthlib.oauth2.BearerToken. + """ raise NotImplementedError('Subclasses must implement this method.') def create_token_response(self, request, token_handler): + """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :param token_handler: A token handler instance, for example of type + oauthlib.oauth2.BearerToken. + """ raise NotImplementedError('Subclasses must implement this method.') def add_token(self, token, token_handler, request): + """ + :param token: + :param token_handler: A token handler instance, for example of type + oauthlib.oauth2.BearerToken. + :param request: OAuthlib request. + :type request: oauthlib.common.Request + """ # Only add a hybrid access token on auth step if asked for if not request.response_type in ["token", "code token", "id_token token", "code id_token token"]: return token @@ -132,6 +152,10 @@ def add_token(self, token, token_handler, request): return token def validate_grant_type(self, request): + """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + """ client_id = getattr(request, 'client_id', None) if not self.request_validator.validate_grant_type(client_id, request.grant_type, request.client, request): @@ -140,6 +164,10 @@ def validate_grant_type(self, request): raise errors.UnauthorizedClientError(request=request) def validate_scopes(self, request): + """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + """ if not request.scopes: request.scopes = utils.scope_to_list(request.scope) or utils.scope_to_list( self.request_validator.get_default_scopes(request.client_id, request)) @@ -154,6 +182,13 @@ def prepare_authorization_response(self, request, token, headers, body, status): Base classes can define a default response mode for their authorization response by overriding the static `default_response_mode` member. + + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :param token: + :param headers: + :param body: + :param status: """ request.response_mode = request.response_mode or self.default_response_mode @@ -183,3 +218,36 @@ def prepare_authorization_response(self, request, token, headers, body, status): raise NotImplementedError( 'Subclasses must set a valid default_response_mode') + + def _get_default_headers(self): + """Create default headers for grant responses.""" + return { + 'Content-Type': 'application/json', + 'Cache-Control': 'no-store', + 'Pragma': 'no-cache', + } + + def _handle_redirects(self, request): + if request.redirect_uri is not None: + request.using_default_redirect_uri = False + log.debug('Using provided redirect_uri %s', request.redirect_uri) + if not is_absolute_uri(request.redirect_uri): + raise errors.InvalidRedirectURIError(request=request) + + # The authorization server MUST verify that the redirection URI + # to which it will redirect the access token matches a + # redirection URI registered by the client as described in + # Section 3.1.2. + # https://tools.ietf.org/html/rfc6749#section-3.1.2 + if not self.request_validator.validate_redirect_uri( + request.client_id, request.redirect_uri, request): + raise errors.MismatchingRedirectURIError(request=request) + else: + request.redirect_uri = self.request_validator.get_default_redirect_uri( + request.client_id, request) + request.using_default_redirect_uri = True + log.debug('Using default redirect_uri %s.', request.redirect_uri) + if not request.redirect_uri: + raise errors.MissingRedirectURIError(request=request) + if not is_absolute_uri(request.redirect_uri): + raise errors.InvalidRedirectURIError(request=request) diff --git a/ext/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py b/ext/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py index 4c50a78a8c..c966795fd1 100644 --- a/ext/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py +++ b/ext/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py @@ -53,6 +53,11 @@ class ClientCredentialsGrant(GrantTypeBase): def create_token_response(self, request, token_handler): """Return token or error in JSON format. + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :param token_handler: A token handler instance, for example of type + oauthlib.oauth2.BearerToken. + If the access token request is valid and authorized, the authorization server issues an access token as described in `Section 5.1`_. A refresh token SHOULD NOT be included. If the request @@ -62,16 +67,13 @@ def create_token_response(self, request, token_handler): .. _`Section 5.1`: https://tools.ietf.org/html/rfc6749#section-5.1 .. _`Section 5.2`: https://tools.ietf.org/html/rfc6749#section-5.2 """ - headers = { - 'Content-Type': 'application/json', - 'Cache-Control': 'no-store', - 'Pragma': 'no-cache', - } + headers = self._get_default_headers() try: log.debug('Validating access token request, %r.', request) self.validate_token_request(request) except errors.OAuth2Error as e: log.debug('Client error in token request. %s.', e) + headers.update(e.headers) return headers, e.json, e.status_code token = token_handler.create_token(request, refresh_token=False, save_token=False) @@ -85,6 +87,10 @@ def create_token_response(self, request, token_handler): return headers, json.dumps(token), 200 def validate_token_request(self, request): + """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + """ for validator in self.custom_validators.pre_token: validator(request) diff --git a/ext/oauthlib/oauth2/rfc6749/grant_types/implicit.py b/ext/oauthlib/oauth2/rfc6749/grant_types/implicit.py index 569282e555..d6de90613c 100644 --- a/ext/oauthlib/oauth2/rfc6749/grant_types/implicit.py +++ b/ext/oauthlib/oauth2/rfc6749/grant_types/implicit.py @@ -8,10 +8,8 @@ import logging from oauthlib import common -from oauthlib.uri_validate import is_absolute_uri from .. import errors -from ..request_validator import RequestValidator from .base import GrantTypeBase log = logging.getLogger(__name__) @@ -122,6 +120,12 @@ class ImplicitGrant(GrantTypeBase): def create_authorization_response(self, request, token_handler): """Create an authorization response. + + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :param token_handler: A token handler instance, for example of type + oauthlib.oauth2.BearerToken. + The client constructs the request URI by adding the following parameters to the query component of the authorization endpoint URI using the "application/x-www-form-urlencoded" format, per `Appendix B`_: @@ -164,6 +168,11 @@ def create_authorization_response(self, request, token_handler): def create_token_response(self, request, token_handler): """Return token or error embedded in the URI fragment. + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :param token_handler: A token handler instance, for example of type + oauthlib.oauth2.BearerToken. + If the resource owner grants the access request, the authorization server issues an access token and delivers it to the client by adding the following parameters to the fragment component of the redirection @@ -201,11 +210,6 @@ def create_token_response(self, request, token_handler): .. _`Section 7.1`: https://tools.ietf.org/html/rfc6749#section-7.1 """ try: - # request.scopes is only mandated in post auth and both pre and - # post auth use validate_authorization_request - if not request.scopes: - raise ValueError('Scopes must be set on post auth.') - self.validate_token_request(request) # If the request fails due to a missing, invalid, or mismatching @@ -229,7 +233,7 @@ def create_token_response(self, request, token_handler): return {'Location': common.add_params_to_uri(request.redirect_uri, e.twotuples, fragment=True)}, None, 302 - # In OIDC implicit flow it is possible to have a request_type that does not include the access token! + # In OIDC implicit flow it is possible to have a request_type that does not include the access_token! # "id_token token" - return the access token and the id token # "id_token" - don't return the access token if "token" in request.response_type.split(): @@ -239,16 +243,28 @@ def create_token_response(self, request, token_handler): for modifier in self._token_modifiers: token = modifier(token, token_handler, request) - self.request_validator.save_token(token, request) + + # In OIDC implicit flow it is possible to have a request_type that does + # not include the access_token! In this case there is no need to save a token. + if "token" in request.response_type.split(): + self.request_validator.save_token(token, request) + return self.prepare_authorization_response( request, token, {}, None, 302) def validate_authorization_request(self, request): + """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + """ return self.validate_token_request(request) def validate_token_request(self, request): """Check the token request for normal and fatal errors. + :param request: OAuthlib request. + :type request: oauthlib.common.Request + This method is very similar to validate_authorization_request in the AuthorizationCodeGrant but differ in a few subtle areas. @@ -290,35 +306,12 @@ def validate_token_request(self, request): # OPTIONAL. As described in Section 3.1.2. # https://tools.ietf.org/html/rfc6749#section-3.1.2 - if request.redirect_uri is not None: - request.using_default_redirect_uri = False - log.debug('Using provided redirect_uri %s', request.redirect_uri) - if not is_absolute_uri(request.redirect_uri): - raise errors.InvalidRedirectURIError(request=request) - - # The authorization server MUST verify that the redirection URI - # to which it will redirect the access token matches a - # redirection URI registered by the client as described in - # Section 3.1.2. - # https://tools.ietf.org/html/rfc6749#section-3.1.2 - if not self.request_validator.validate_redirect_uri( - request.client_id, request.redirect_uri, request): - raise errors.MismatchingRedirectURIError(request=request) - else: - request.redirect_uri = self.request_validator.get_default_redirect_uri( - request.client_id, request) - request.using_default_redirect_uri = True - log.debug('Using default redirect_uri %s.', request.redirect_uri) - if not request.redirect_uri: - raise errors.MissingRedirectURIError(request=request) - if not is_absolute_uri(request.redirect_uri): - raise errors.InvalidRedirectURIError(request=request) + self._handle_redirects(request) # Then check for normal errors. request_info = self._run_custom_validators(request, - self.custom_validators.all_pre) - + self.custom_validators.all_pre) # If the resource owner denies the access request or if the request # fails for reasons other than a missing or invalid redirection URI, @@ -352,20 +345,21 @@ def validate_token_request(self, request): self.validate_scopes(request) request_info.update({ - 'client_id': request.client_id, - 'redirect_uri': request.redirect_uri, - 'response_type': request.response_type, - 'state': request.state, - 'request': request, + 'client_id': request.client_id, + 'redirect_uri': request.redirect_uri, + 'response_type': request.response_type, + 'state': request.state, + 'request': request, }) - request_info = self._run_custom_validators(request, - self.custom_validators.all_post, - request_info) + request_info = self._run_custom_validators( + request, + self.custom_validators.all_post, + request_info + ) return request.scopes, request_info - def _run_custom_validators(self, request, validations, diff --git a/ext/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py b/ext/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py index c2d86f7951..bd519e81a6 100644 --- a/ext/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py +++ b/ext/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py @@ -33,6 +33,11 @@ def __init__(self, request_validator=None, def create_token_response(self, request, token_handler): """Create a new access token from a refresh_token. + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :param token_handler: A token handler instance, for example of type + oauthlib.oauth2.BearerToken. + If valid and authorized, the authorization server issues an access token as described in `Section 5.1`_. If the request failed verification or is invalid, the authorization server returns an error @@ -49,15 +54,13 @@ def create_token_response(self, request, token_handler): .. _`Section 5.1`: https://tools.ietf.org/html/rfc6749#section-5.1 .. _`Section 5.2`: https://tools.ietf.org/html/rfc6749#section-5.2 """ - headers = { - 'Content-Type': 'application/json', - 'Cache-Control': 'no-store', - 'Pragma': 'no-cache', - } + headers = self._get_default_headers() try: log.debug('Validating refresh token request, %r.', request) self.validate_token_request(request) except errors.OAuth2Error as e: + log.debug('Client error in token request, %s.', e) + headers.update(e.headers) return headers, e.json, e.status_code token = token_handler.create_token(request, @@ -72,6 +75,10 @@ def create_token_response(self, request, token_handler): return headers, json.dumps(token), 200 def validate_token_request(self, request): + """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + """ # REQUIRED. Value MUST be set to "refresh_token". if request.grant_type != 'refresh_token': raise errors.UnsupportedGrantTypeError(request=request) diff --git a/ext/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py b/ext/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py index e5f04af475..f765d91bcf 100644 --- a/ext/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py +++ b/ext/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py @@ -73,6 +73,11 @@ class ResourceOwnerPasswordCredentialsGrant(GrantTypeBase): def create_token_response(self, request, token_handler): """Return token or error in json format. + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :param token_handler: A token handler instance, for example of type + oauthlib.oauth2.BearerToken. + If the access token request is valid and authorized, the authorization server issues an access token and optional refresh token as described in `Section 5.1`_. If the request failed client @@ -82,11 +87,7 @@ def create_token_response(self, request, token_handler): .. _`Section 5.1`: https://tools.ietf.org/html/rfc6749#section-5.1 .. _`Section 5.2`: https://tools.ietf.org/html/rfc6749#section-5.2 """ - headers = { - 'Content-Type': 'application/json', - 'Cache-Control': 'no-store', - 'Pragma': 'no-cache', - } + headers = self._get_default_headers() try: if self.request_validator.client_authentication_required(request): log.debug('Authenticating client, %r.', request) @@ -100,6 +101,7 @@ def create_token_response(self, request, token_handler): self.validate_token_request(request) except errors.OAuth2Error as e: log.debug('Client error in token request, %s.', e) + headers.update(e.headers) return headers, e.json, e.status_code token = token_handler.create_token(request, self.refresh_token, save_token=False) @@ -114,6 +116,9 @@ def create_token_response(self, request, token_handler): def validate_token_request(self, request): """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + The client makes a request to the token endpoint by adding the following parameters using the "application/x-www-form-urlencoded" format per Appendix B with a character encoding of UTF-8 in the HTTP diff --git a/ext/oauthlib/oauth2/rfc6749/parameters.py b/ext/oauthlib/oauth2/rfc6749/parameters.py index 01079338fe..4d0baee7a0 100644 --- a/ext/oauthlib/oauth2/rfc6749/parameters.py +++ b/ext/oauthlib/oauth2/rfc6749/parameters.py @@ -37,14 +37,14 @@ def prepare_grant_uri(uri, client_id, response_type, redirect_uri=None, using the ``application/x-www-form-urlencoded`` format as defined by [`W3C.REC-html401-19991224`_]: + :param uri: + :param client_id: The client identifier as described in `Section 2.2`_. :param response_type: To indicate which OAuth 2 grant/flow is required, "code" and "token". - :param client_id: The client identifier as described in `Section 2.2`_. :param redirect_uri: The client provided URI to redirect back to after authorization as described in `Section 3.1.2`_. :param scope: The scope of the access request as described by `Section 3.3`_. - :param state: An opaque value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent @@ -87,7 +87,7 @@ def prepare_grant_uri(uri, client_id, response_type, redirect_uri=None, return add_params_to_uri(uri, params) -def prepare_token_request(grant_type, body='', **kwargs): +def prepare_token_request(grant_type, body='', include_client_id=True, **kwargs): """Prepare the access token request. The client makes a request to the token endpoint by adding the @@ -95,15 +95,39 @@ def prepare_token_request(grant_type, body='', **kwargs): format in the HTTP request entity-body: :param grant_type: To indicate grant type being used, i.e. "password", - "authorization_code" or "client_credentials". - :param body: Existing request body to embed parameters in. - :param code: If using authorization code grant, pass the previously - obtained authorization code as the ``code`` argument. + "authorization_code" or "client_credentials". + + :param body: Existing request body (URL encoded string) to embed parameters + into. This may contain extra paramters. Default ''. + + :param include_client_id: `True` (default) to send the `client_id` in the + body of the upstream request. This is required + if the client is not authenticating with the + authorization server as described in + `Section 3.2.1`_. + :type include_client_id: Boolean + + :param client_id: Unicode client identifier. Will only appear if + `include_client_id` is True. * + + :param client_secret: Unicode client secret. Will only appear if set to a + value that is not `None`. Invoking this function with + an empty string will send an empty `client_secret` + value to the server. * + + :param code: If using authorization_code grant, pass the previously + obtained authorization code as the ``code`` argument. * + :param redirect_uri: If the "redirect_uri" parameter was included in the authorization request as described in - `Section 4.1.1`_, and their values MUST be identical. + `Section 4.1.1`_, and their values MUST be identical. * + :param kwargs: Extra arguments to embed in the request body. + Parameters marked with a `*` above are not explicit arguments in the + function signature, but are specially documented arguments for items + appearing in the generic `**kwargs` keyworded input. + An example of an authorization code token request body: .. code-block:: http @@ -118,6 +142,19 @@ def prepare_token_request(grant_type, body='', **kwargs): if 'scope' in kwargs: kwargs['scope'] = list_to_scope(kwargs['scope']) + # pull the `client_id` out of the kwargs. + client_id = kwargs.pop('client_id', None) + if include_client_id: + if client_id is not None: + params.append((unicode_type('client_id'), client_id)) + + # the kwargs iteration below only supports including boolean truth (truthy) + # values, but some servers may require an empty string for `client_secret` + client_secret = kwargs.pop('client_secret', None) + if client_secret is not None: + params.append((unicode_type('client_secret'), client_secret)) + + # this handles: `code`, `redirect_uri`, and other undocumented params for k in kwargs: if kwargs[k]: params.append((unicode_type(k), kwargs[k])) @@ -133,15 +170,19 @@ def prepare_token_revocation_request(url, token, token_type_hint="access_token", using the "application/x-www-form-urlencoded" format in the HTTP request entity-body: - token REQUIRED. The token that the client wants to get revoked. + :param token: REQUIRED. The token that the client wants to get revoked. - token_type_hint OPTIONAL. A hint about the type of the token submitted - for revocation. Clients MAY pass this parameter in order to help the - authorization server to optimize the token lookup. If the server is unable - to locate the token using the given hint, it MUST extend its search across - all of its supported token types. An authorization server MAY ignore this - parameter, particularly if it is able to detect the token type - automatically. This specification defines two such values: + :param token_type_hint: OPTIONAL. A hint about the type of the token + submitted for revocation. Clients MAY pass this + parameter in order to help the authorization server + to optimize the token lookup. If the server is + unable to locate the token using the given hint, it + MUST extend its search across all of its supported + token types. An authorization server MAY ignore + this parameter, particularly if it is able to detect + the token type automatically. + + This specification defines two values for `token_type_hint`: * access_token: An access token as defined in [RFC6749], `Section 1.4`_ @@ -264,6 +305,10 @@ def parse_implicit_response(uri, state=None, scope=None): authorization request. The exact value received from the client. + :param uri: + :param state: + :param scope: + Similar to the authorization code response, but with a full token provided in the URL fragment: @@ -279,6 +324,10 @@ def parse_implicit_response(uri, state=None, scope=None): fragment = urlparse.urlparse(uri).fragment params = dict(urlparse.parse_qsl(fragment, keep_blank_values=True)) + for key in ('expires_in',): + if key in params: # cast things to int + params[key] = int(params[key]) + if 'scope' in params: params['scope'] = scope_to_list(params['scope']) @@ -362,16 +411,13 @@ def parse_token_response(body, scope=None): # https://github.com/oauthlib/oauthlib/issues/267 params = dict(urlparse.parse_qsl(body)) - for key in ('expires_in', 'expires'): - if key in params: # cast a couple things to int + for key in ('expires_in',): + if key in params: # cast things to int params[key] = int(params[key]) if 'scope' in params: params['scope'] = scope_to_list(params['scope']) - if 'expires' in params: - params['expires_in'] = params.pop('expires') - if 'expires_in' in params: params['expires_at'] = time.time() + int(params['expires_in']) diff --git a/ext/oauthlib/oauth2/rfc6749/request_validator.py b/ext/oauthlib/oauth2/rfc6749/request_validator.py index fee7b8cb78..193a9e1fff 100644 --- a/ext/oauthlib/oauth2/rfc6749/request_validator.py +++ b/ext/oauthlib/oauth2/rfc6749/request_validator.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -oauthlib.oauth2.rfc6749.grant_types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +oauthlib.oauth2.rfc6749.request_validator +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """ from __future__ import absolute_import, unicode_literals @@ -26,7 +26,8 @@ def client_authentication_required(self, request, *args, **kwargs): client credentials or whenever Client provided client authentication, see `Section 6`_ - :param request: oauthlib.common.Request + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -51,7 +52,8 @@ def authenticate_client(self, request, *args, **kwargs): both body and query can be obtained by direct attribute access, i.e. request.client_id for client_id in the URL query. - :param request: oauthlib.common.Request + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -74,7 +76,9 @@ def authenticate_client_id(self, client_id, request, *args, **kwargs): to set request.client to the client object associated with the given client_id. - :param request: oauthlib.common.Request + :param client_id: Unicode client identifier. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -93,11 +97,12 @@ def confirm_redirect_uri(self, client_id, code, redirect_uri, client, request, the client's allowed redirect URIs, but against the URI used when the code was saved. - :param client_id: Unicode client identifier + :param client_id: Unicode client identifier. :param code: Unicode authorization_code. - :param redirect_uri: Unicode absolute URI - :param client: Client object set by you, see authenticate_client. - :param request: The HTTP Request (oauthlib.common.Request) + :param redirect_uri: Unicode absolute URI. + :param client: Client object set by you, see ``.authenticate_client``. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -108,8 +113,9 @@ def confirm_redirect_uri(self, client_id, code, redirect_uri, client, request, def get_default_redirect_uri(self, client_id, request, *args, **kwargs): """Get the default redirect URI for the client. - :param client_id: Unicode client identifier - :param request: The HTTP Request (oauthlib.common.Request) + :param client_id: Unicode client identifier. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: The default redirect URI for the client Method is used by: @@ -121,8 +127,9 @@ def get_default_redirect_uri(self, client_id, request, *args, **kwargs): def get_default_scopes(self, client_id, request, *args, **kwargs): """Get the default scopes for the client. - :param client_id: Unicode client identifier - :param request: The HTTP Request (oauthlib.common.Request) + :param client_id: Unicode client identifier. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: List of default scopes Method is used by all core grant types: @@ -136,8 +143,9 @@ def get_default_scopes(self, client_id, request, *args, **kwargs): def get_original_scopes(self, refresh_token, request, *args, **kwargs): """Get the list of scopes associated with the refresh token. - :param refresh_token: Unicode refresh token - :param request: The HTTP Request (oauthlib.common.Request) + :param refresh_token: Unicode refresh token. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: List of scopes. Method is used by: @@ -156,9 +164,10 @@ def is_within_original_scope(self, request_scopes, refresh_token, request, *args used in situations where returning all valid scopes from the get_original_scopes is not practical. - :param request_scopes: A list of scopes that were requested by client - :param refresh_token: Unicode refresh_token - :param request: The HTTP Request (oauthlib.common.Request) + :param request_scopes: A list of scopes that were requested by client. + :param refresh_token: Unicode refresh_token. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -166,12 +175,54 @@ def is_within_original_scope(self, request_scopes, refresh_token, request, *args """ return False + def introspect_token(self, token, token_type_hint, request, *args, **kwargs): + """Introspect an access or refresh token. + + Called once the introspect request is validated. This method should + verify the *token* and either return a dictionary with the list of + claims associated, or `None` in case the token is unknown. + + Below the list of registered claims you should be interested in: + - scope : space-separated list of scopes + - client_id : client identifier + - username : human-readable identifier for the resource owner + - token_type : type of the token + - exp : integer timestamp indicating when this token will expire + - iat : integer timestamp indicating when this token was issued + - nbf : integer timestamp indicating when it can be "not-before" used + - sub : subject of the token - identifier of the resource owner + - aud : list of string identifiers representing the intended audience + - iss : string representing issuer of this token + - jti : string identifier for the token + + Note that most of them are coming directly from JWT RFC. More details + can be found in `Introspect Claims`_ or `_JWT Claims`_. + + The implementation can use *token_type_hint* to improve lookup + efficency, but must fallback to other types to be compliant with RFC. + + The dict of claims is added to request.token after this method. + + :param token: The token string. + :param token_type_hint: access_token or refresh_token. + :param request: OAuthlib request. + :type request: oauthlib.common.Request + + Method is used by: + - Introspect Endpoint (all grants are compatible) + + .. _`Introspect Claims`: https://tools.ietf.org/html/rfc7662#section-2.2 + .. _`JWT Claims`: https://tools.ietf.org/html/rfc7519#section-4 + """ + raise NotImplementedError('Subclasses must implement this method.') + def invalidate_authorization_code(self, client_id, code, request, *args, **kwargs): """Invalidate an authorization code after use. - :param client_id: Unicode client identifier + :param client_id: Unicode client identifier. :param code: The authorization code grant (request.code). - :param request: The HTTP Request (oauthlib.common.Request) + :param request: OAuthlib request. + :type request: oauthlib.common.Request Method is used by: - Authorization Code Grant @@ -183,7 +234,8 @@ def revoke_token(self, token, token_type_hint, request, *args, **kwargs): :param token: The token string. :param token_type_hint: access_token or refresh_token. - :param request: The HTTP Request (oauthlib.common.Request) + :param request: OAuthlib request. + :type request: oauthlib.common.Request Method is used by: - Revocation Endpoint @@ -197,7 +249,8 @@ def rotate_refresh_token(self, request): or replaced with a new one (rotated). Return True to rotate and and False for keeping original. - :param request: oauthlib.common.Request + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -209,39 +262,74 @@ def save_authorization_code(self, client_id, code, request, *args, **kwargs): """Persist the authorization_code. The code should at minimum be stored with: - - the client_id (client_id) - - the redirect URI used (request.redirect_uri) - - a resource owner / user (request.user) - - the authorized scopes (request.scopes) - - the client state, if given (code.get('state')) + - the client_id (``client_id``) + - the redirect URI used (``request.redirect_uri``) + - a resource owner / user (``request.user``) + - the authorized scopes (``request.scopes``) + - the client state, if given (``code.get('state')``) + + To support PKCE, you MUST associate the code with: + - Code Challenge (``request.code_challenge``) and + - Code Challenge Method (``request.code_challenge_method``) - The 'code' argument is actually a dictionary, containing at least a - 'code' key with the actual authorization code: + The ``code`` argument is actually a dictionary, containing at least a + ``code`` key with the actual authorization code: - {'code': 'sdf345jsdf0934f'} + ``{'code': 'sdf345jsdf0934f'}`` - It may also have a 'state' key containing a nonce for the client, if it + It may also have a ``state`` key containing a nonce for the client, if it chose to send one. That value should be saved and used in - 'validate_code'. + ``.validate_code``. - It may also have a 'claims' parameter which, when present, will be a dict + It may also have a ``claims`` parameter which, when present, will be a dict deserialized from JSON as described at http://openid.net/specs/openid-connect-core-1_0.html#ClaimsParameter - This value should be saved in this method and used again in 'validate_code'. + This value should be saved in this method and used again in ``.validate_code``. - :param client_id: Unicode client identifier + :param client_id: Unicode client identifier. :param code: A dict of the authorization code grant and, optionally, state. - :param request: The HTTP Request (oauthlib.common.Request) + :param request: OAuthlib request. + :type request: oauthlib.common.Request Method is used by: - Authorization Code Grant """ raise NotImplementedError('Subclasses must implement this method.') + def get_authorization_code_scopes(self, client_id, code, redirect_uri, request): + """ Extracts scopes from saved authorization code. + + The scopes returned by this method is used to route token requests + based on scopes passed to Authorization Code requests. + + With that the token endpoint knows when to include OpenIDConnect + id_token in token response only based on authorization code scopes. + + Only code param should be sufficient to retrieve grant code from + any storage you are using, `client_id` and `redirect_uri` can gave a + blank value `""` don't forget to check it before using those values + in a select query if a database is used. + + :param client_id: Unicode client identifier. + :param code: Unicode authorization code grant. + :param redirect_uri: Unicode absolute URI. + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :return: A list of scopes + + Method is used by: + - Authorization Token Grant Dispatcher + """ + raise NotImplementedError('Subclasses must implement this method.') + def save_token(self, token, request, *args, **kwargs): """Persist the token with a token type specific method. Currently, only save_bearer_token is supported. + + :param token: A (Bearer) token dict. + :param request: OAuthlib request. + :type request: oauthlib.common.Request """ return self.save_bearer_token(token, request, *args, **kwargs) @@ -268,16 +356,23 @@ def save_bearer_token(self, token, request, *args, **kwargs): } Note that while "scope" is a string-separated list of authorized scopes, - the original list is still available in request.scopes + the original list is still available in request.scopes. + + The token dict is passed as a reference so any changes made to the dictionary + will go back to the user. If additional information must return to the client + user, and it is only possible to get this information after writing the token + to storage, it should be added to the token dictionary. If the token + dictionary must be modified but the changes should not go back to the user, + a copy of the dictionary must be made before making the changes. Also note that if an Authorization Code grant request included a valid claims parameter (for OpenID Connect) then the request.claims property will contain the claims dict, which should be saved for later use when generating the id_token and/or UserInfo response content. - :param client_id: Unicode client identifier - :param token: A Bearer token dict - :param request: The HTTP Request (oauthlib.common.Request) + :param token: A Bearer token dict. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: The default redirect URI for the client Method is used by all core grant types issuing Bearer tokens: @@ -288,8 +383,25 @@ def save_bearer_token(self, token, request, *args, **kwargs): """ raise NotImplementedError('Subclasses must implement this method.') - def get_id_token(self, token, token_handler, request): + def get_jwt_bearer_token(self, token, token_handler, request): + """Get JWT Bearer token or OpenID Connect ID token + + If using OpenID Connect this SHOULD call `oauthlib.oauth2.RequestValidator.get_id_token` + + :param token: A Bearer token dict. + :param token_handler: The token handler (BearerToken class). + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :return: The JWT Bearer token or OpenID Connect ID token (a JWS signed JWT) + + Method is used by JWT Bearer and OpenID Connect tokens: + - JWTToken.create_token """ + raise NotImplementedError('Subclasses must implement this method.') + + def get_id_token(self, token, token_handler, request): + """Get OpenID Connect ID token + In the OpenID Connect workflows when an ID Token is requested this method is called. Subclasses should implement the construction, signing and optional encryption of the ID Token as described in the OpenID Connect spec. @@ -312,20 +424,70 @@ def get_id_token(self, token, token_handler, request): .. _`3.2.2.10`: http://openid.net/specs/openid-connect-core-1_0.html#ImplicitIDToken .. _`3.3.2.11`: http://openid.net/specs/openid-connect-core-1_0.html#HybridIDToken - :param token: A Bearer token dict - :param token_handler: the token handler (BearerToken class) - :param request: the HTTP Request (oauthlib.common.Request) + :param token: A Bearer token dict. + :param token_handler: The token handler (BearerToken class) + :param request: OAuthlib request. + :type request: oauthlib.common.Request :return: The ID Token (a JWS signed JWT) """ # the request.scope should be used by the get_id_token() method to determine which claims to include in the resulting id_token raise NotImplementedError('Subclasses must implement this method.') + def validate_jwt_bearer_token(self, token, scopes, request): + """Ensure the JWT Bearer token or OpenID Connect ID token are valids and authorized access to scopes. + + If using OpenID Connect this SHOULD call `oauthlib.oauth2.RequestValidator.get_id_token` + + If not using OpenID Connect this can `return None` to avoid 5xx rather 401/3 response. + + OpenID connect core 1.0 describe how to validate an id_token: + - http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation + - http://openid.net/specs/openid-connect-core-1_0.html#ImplicitIDTValidation + - http://openid.net/specs/openid-connect-core-1_0.html#HybridIDTValidation + - http://openid.net/specs/openid-connect-core-1_0.html#HybridIDTValidation2 + + :param token: Unicode Bearer token. + :param scopes: List of scopes (defined by you). + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :rtype: True or False + + Method is indirectly used by all core OpenID connect JWT token issuing grant types: + - Authorization Code Grant + - Implicit Grant + - Hybrid Grant + """ + raise NotImplementedError('Subclasses must implement this method.') + + def validate_id_token(self, token, scopes, request): + """Ensure the id token is valid and authorized access to scopes. + + OpenID connect core 1.0 describe how to validate an id_token: + - http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation + - http://openid.net/specs/openid-connect-core-1_0.html#ImplicitIDTValidation + - http://openid.net/specs/openid-connect-core-1_0.html#HybridIDTValidation + - http://openid.net/specs/openid-connect-core-1_0.html#HybridIDTValidation2 + + :param token: Unicode Bearer token. + :param scopes: List of scopes (defined by you). + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :rtype: True or False + + Method is indirectly used by all core OpenID connect JWT token issuing grant types: + - Authorization Code Grant + - Implicit Grant + - Hybrid Grant + """ + raise NotImplementedError('Subclasses must implement this method.') + def validate_bearer_token(self, token, scopes, request): """Ensure the Bearer token is valid and authorized access to scopes. :param token: A string of random characters. :param scopes: A list of scopes associated with the protected resource. - :param request: The HTTP Request (oauthlib.common.Request) + :param request: OAuthlib request. + :type request: oauthlib.common.Request A key to OAuth 2 security and restricting impact of leaked tokens is the short expiration time of tokens, *always ensure the token has not @@ -359,7 +521,8 @@ def validate_bearer_token(self, token, scopes, request): :param token: Unicode Bearer token :param scopes: List of scopes (defined by you) - :param request: The HTTP Request (oauthlib.common.Request) + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is indirectly used by all core Bearer token issuing grant types: @@ -377,7 +540,9 @@ def validate_client_id(self, client_id, request, *args, **kwargs): to set request.client to the client object associated with the given client_id. - :param request: oauthlib.common.Request + :param client_id: Unicode client identifier. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -403,10 +568,16 @@ def validate_code(self, client_id, code, client, request, *args, **kwargs): The request.claims property, if it was given, should assigned a dict. - :param client_id: Unicode client identifier - :param code: Unicode authorization code - :param client: Client object set by you, see authenticate_client. - :param request: The HTTP Request (oauthlib.common.Request) + If PKCE is enabled (see 'is_pkce_required' and 'save_authorization_code') + you MUST set the following based on the information stored: + - request.code_challenge + - request.code_challenge_method + + :param client_id: Unicode client identifier. + :param code: Unicode authorization code. + :param client: Client object set by you, see ``.authenticate_client``. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -417,10 +588,11 @@ def validate_code(self, client_id, code, client, request, *args, **kwargs): def validate_grant_type(self, client_id, grant_type, client, request, *args, **kwargs): """Ensure client is authorized to use the grant_type requested. - :param client_id: Unicode client identifier + :param client_id: Unicode client identifier. :param grant_type: Unicode grant type, i.e. authorization_code, password. - :param client: Client object set by you, see authenticate_client. - :param request: The HTTP Request (oauthlib.common.Request) + :param client: Client object set by you, see ``.authenticate_client``. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -437,9 +609,10 @@ def validate_redirect_uri(self, client_id, redirect_uri, request, *args, **kwarg All clients should register the absolute URIs of all URIs they intend to redirect to. The registration is outside of the scope of oauthlib. - :param client_id: Unicode client identifier - :param redirect_uri: Unicode absolute URI - :param request: The HTTP Request (oauthlib.common.Request) + :param client_id: Unicode client identifier. + :param redirect_uri: Unicode absolute URI. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -454,9 +627,10 @@ def validate_refresh_token(self, refresh_token, client, request, *args, **kwargs OBS! The request.user attribute should be set to the resource owner associated with this refresh token. - :param refresh_token: Unicode refresh token - :param client: Client object set by you, see authenticate_client. - :param request: The HTTP Request (oauthlib.common.Request) + :param refresh_token: Unicode refresh token. + :param client: Client object set by you, see ``.authenticate_client``. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -469,10 +643,11 @@ def validate_refresh_token(self, refresh_token, client, request, *args, **kwargs def validate_response_type(self, client_id, response_type, client, request, *args, **kwargs): """Ensure client is authorized to use the response_type requested. - :param client_id: Unicode client identifier + :param client_id: Unicode client identifier. :param response_type: Unicode response type, i.e. code, token. - :param client: Client object set by you, see authenticate_client. - :param request: The HTTP Request (oauthlib.common.Request) + :param client: Client object set by you, see ``.authenticate_client``. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -484,10 +659,11 @@ def validate_response_type(self, client_id, response_type, client, request, *arg def validate_scopes(self, client_id, scopes, client, request, *args, **kwargs): """Ensure the client is authorized access to requested scopes. - :param client_id: Unicode client identifier - :param scopes: List of scopes (defined by you) - :param client: Client object set by you, see authenticate_client. - :param request: The HTTP Request (oauthlib.common.Request) + :param client_id: Unicode client identifier. + :param scopes: List of scopes (defined by you). + :param client: Client object set by you, see ``.authenticate_client``. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by all core grant types: @@ -504,7 +680,8 @@ def validate_silent_authorization(self, request): Silent OpenID authorization allows access tokens and id tokens to be granted to clients without any user prompt or interaction. - :param request: The HTTP Request (oauthlib.common.Request) + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -524,7 +701,8 @@ def validate_silent_login(self, request): not selected which one to link to the token then this method should raise an oauthlib.oauth2.AccountSelectionRequired error. - :param request: The HTTP Request (oauthlib.common.Request) + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -542,10 +720,11 @@ def validate_user(self, username, password, client, request, *args, **kwargs): not set you will be unable to associate a token with a user in the persistance method used (commonly, save_bearer_token). - :param username: Unicode username - :param password: Unicode password - :param client: Client object set by you, see authenticate_client. - :param request: The HTTP Request (oauthlib.common.Request) + :param username: Unicode username. + :param password: Unicode password. + :param client: Client object set by you, see ``.authenticate_client``. + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -562,7 +741,8 @@ def validate_user_match(self, id_token_hint, scopes, claims, request): :param id_token_hint: User identifier string. :param scopes: List of OAuth 2 scopes and OpenID claims (strings). :param claims: OpenID Connect claims dict. - :param request: The HTTP Request (oauthlib.common.Request) + :param request: OAuthlib request. + :type request: oauthlib.common.Request :rtype: True or False Method is used by: @@ -571,3 +751,78 @@ def validate_user_match(self, id_token_hint, scopes, claims, request): - OpenIDConnectHybrid """ raise NotImplementedError('Subclasses must implement this method.') + + def is_pkce_required(self, client_id, request): + """Determine if current request requires PKCE. Default, False. + This is called for both "authorization" and "token" requests. + + Override this method by ``return True`` to enable PKCE for everyone. + You might want to enable it only for public clients. + Note that PKCE can also be used in addition of a client authentication. + + OAuth 2.0 public clients utilizing the Authorization Code Grant are + susceptible to the authorization code interception attack. This + specification describes the attack as well as a technique to mitigate + against the threat through the use of Proof Key for Code Exchange + (PKCE, pronounced "pixy"). See `RFC7636`_. + + :param client_id: Client identifier. + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :rtype: True or False + + Method is used by: + - Authorization Code Grant + + .. _`RFC7636`: https://tools.ietf.org/html/rfc7636 + """ + return False + + def get_code_challenge(self, code, request): + """Is called for every "token" requests. + + When the server issues the authorization code in the authorization + response, it MUST associate the ``code_challenge`` and + ``code_challenge_method`` values with the authorization code so it can + be verified later. + + Typically, the ``code_challenge`` and ``code_challenge_method`` values + are stored in encrypted form in the ``code`` itself but could + alternatively be stored on the server associated with the code. The + server MUST NOT include the ``code_challenge`` value in client requests + in a form that other entities can extract. + + Return the ``code_challenge`` associated to the code. + If ``None`` is returned, code is considered to not be associated to any + challenges. + + :param code: Authorization code. + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :rtype: code_challenge string + + Method is used by: + - Authorization Code Grant - when PKCE is active + + """ + return None + + def get_code_challenge_method(self, code, request): + """Is called during the "token" request processing, when a + ``code_verifier`` and a ``code_challenge`` has been provided. + + See ``.get_code_challenge``. + + Must return ``plain`` or ``S256``. You can return a custom value if you have + implemented your own ``AuthorizationCodeGrant`` class. + + :param code: Authorization code. + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :rtype: code_challenge_method string + + Method is used by: + - Authorization Code Grant - when PKCE is active + + """ + raise NotImplementedError('Subclasses must implement this method.') diff --git a/ext/oauthlib/oauth2/rfc6749/tokens.py b/ext/oauthlib/oauth2/rfc6749/tokens.py index 6cfa642f67..d78df09e66 100644 --- a/ext/oauthlib/oauth2/rfc6749/tokens.py +++ b/ext/oauthlib/oauth2/rfc6749/tokens.py @@ -24,8 +24,6 @@ from urllib.parse import urlparse - - class OAuth2Token(dict): def __init__(self, params, old_scope=None): @@ -98,10 +96,14 @@ def prepare_mac_header(token, uri, key, http_method, .. _`MAC Access Authentication`: https://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01 .. _`extension algorithms`: https://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01#section-7.1 + :param token: :param uri: Request URI. - :param headers: Request headers as a dictionary. - :param http_method: HTTP Request method. :param key: MAC given provided by token endpoint. + :param http_method: HTTP Request method. + :param nonce: + :param headers: Request headers as a dictionary. + :param body: + :param ext: :param hash_algorithm: HMAC algorithm provided by token endpoint. :param issue_time: Time when the MAC credentials were issued (datetime). :param draft: MAC authentication specification version. @@ -183,6 +185,9 @@ def prepare_bearer_uri(token, uri): http://www.example.com/path?access_token=h480djs93hd8 .. _`Bearer Token`: https://tools.ietf.org/html/rfc6750 + + :param token: + :param uri: """ return add_params_to_uri(uri, [(('access_token', token))]) @@ -194,6 +199,9 @@ def prepare_bearer_headers(token, headers=None): Authorization: Bearer h480djs93hd8 .. _`Bearer Token`: https://tools.ietf.org/html/rfc6750 + + :param token: + :param headers: """ headers = headers or {} headers['Authorization'] = 'Bearer %s' % token @@ -206,15 +214,26 @@ def prepare_bearer_body(token, body=''): access_token=h480djs93hd8 .. _`Bearer Token`: https://tools.ietf.org/html/rfc6750 + + :param token: + :param body: """ return add_params_to_qs(body, [(('access_token', token))]) def random_token_generator(request, refresh_token=False): + """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :param refresh_token: + """ return common.generate_token() def signed_token_generator(private_pem, **kwargs): + """ + :param private_pem: + """ def signed_token_generator(request): request.claims = kwargs return common.generate_signed_token(private_pem, request) @@ -222,15 +241,43 @@ def signed_token_generator(request): return signed_token_generator +def get_token_from_header(request): + """ + Helper function to extract a token from the request header. + + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :return: Return the token or None if the Authorization header is malformed. + """ + token = None + + if 'Authorization' in request.headers: + split_header = request.headers.get('Authorization').split() + if len(split_header) == 2 and split_header[0] == 'Bearer': + token = split_header[1] + else: + token = request.access_token + + return token + + class TokenBase(object): def __call__(self, request, refresh_token=False): raise NotImplementedError('Subclasses must implement this method.') def validate_request(self, request): + """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + """ raise NotImplementedError('Subclasses must implement this method.') def estimate_type(self, request): + """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + """ raise NotImplementedError('Subclasses must implement this method.') @@ -250,7 +297,14 @@ def __init__(self, request_validator=None, token_generator=None, self.expires_in = expires_in or 3600 def create_token(self, request, refresh_token=False, save_token=True): - """Create a BearerToken, by default without refresh token.""" + """ + Create a BearerToken, by default without refresh token. + + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :param refresh_token: + :param save_token: + """ if callable(self.expires_in): expires_in = self.expires_in(request) @@ -288,16 +342,20 @@ def create_token(self, request, refresh_token=False, save_token=True): return token def validate_request(self, request): - token = None - if 'Authorization' in request.headers: - token = request.headers.get('Authorization')[7:] - else: - token = request.access_token + """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + """ + token = get_token_from_header(request) return self.request_validator.validate_bearer_token( token, request.scopes, request) def estimate_type(self, request): - if request.headers.get('Authorization', '').startswith('Bearer'): + """ + :param request: OAuthlib request. + :type request: oauthlib.common.Request + """ + if request.headers.get('Authorization', '').split(' ')[0] == 'Bearer': return 9 elif request.access_token is not None: return 5 diff --git a/ext/oauthlib/openid/__init__.py b/ext/oauthlib/openid/__init__.py new file mode 100644 index 0000000000..03f0fa2e9e --- /dev/null +++ b/ext/oauthlib/openid/__init__.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +""" +oauthlib.openid +~~~~~~~~~~~~~~ + +""" +from __future__ import absolute_import, unicode_literals + +from .connect.core.endpoints import Server diff --git a/ext/oauthlib/openid/connect/__init__.py b/ext/oauthlib/openid/connect/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ext/oauthlib/openid/connect/core/__init__.py b/ext/oauthlib/openid/connect/core/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ext/oauthlib/openid/connect/core/endpoints/__init__.py b/ext/oauthlib/openid/connect/core/endpoints/__init__.py new file mode 100644 index 0000000000..719f883c35 --- /dev/null +++ b/ext/oauthlib/openid/connect/core/endpoints/__init__.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +""" +oauthlib.oopenid.core +~~~~~~~~~~~~~~~~~~~~~~~ + +This module is an implementation of various logic needed +for consuming and providing OpenID Connect +""" +from __future__ import absolute_import, unicode_literals + +from .pre_configured import Server diff --git a/ext/oauthlib/openid/connect/core/endpoints/pre_configured.py b/ext/oauthlib/openid/connect/core/endpoints/pre_configured.py new file mode 100644 index 0000000000..6367847bd9 --- /dev/null +++ b/ext/oauthlib/openid/connect/core/endpoints/pre_configured.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +""" +oauthlib.openid.connect.core.endpoints.pre_configured +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This module is an implementation of various endpoints needed +for providing OpenID Connect servers. +""" +from __future__ import absolute_import, unicode_literals + +from oauthlib.oauth2.rfc6749.endpoints import ( + AuthorizationEndpoint, + IntrospectEndpoint, + ResourceEndpoint, + RevocationEndpoint, + TokenEndpoint +) +from oauthlib.oauth2.rfc6749.grant_types import ( + AuthorizationCodeGrant as OAuth2AuthorizationCodeGrant, + ImplicitGrant as OAuth2ImplicitGrant, + ClientCredentialsGrant, + RefreshTokenGrant, + ResourceOwnerPasswordCredentialsGrant +) +from oauthlib.oauth2.rfc6749.tokens import BearerToken +from ..grant_types import ( + AuthorizationCodeGrant, + ImplicitGrant, + HybridGrant, +) +from ..grant_types.dispatchers import ( + AuthorizationCodeGrantDispatcher, + ImplicitTokenGrantDispatcher, + AuthorizationTokenGrantDispatcher +) +from ..tokens import JWTToken + + +class Server(AuthorizationEndpoint, IntrospectEndpoint, TokenEndpoint, + ResourceEndpoint, RevocationEndpoint): + + """An all-in-one endpoint featuring all four major grant types.""" + + def __init__(self, request_validator, token_expires_in=None, + token_generator=None, refresh_token_generator=None, + *args, **kwargs): + """Construct a new all-grants-in-one server. + + :param request_validator: An implementation of + oauthlib.oauth2.RequestValidator. + :param token_expires_in: An int or a function to generate a token + expiration offset (in seconds) given a + oauthlib.common.Request object. + :param token_generator: A function to generate a token from a request. + :param refresh_token_generator: A function to generate a token from a + request for the refresh token. + :param kwargs: Extra parameters to pass to authorization-, + token-, resource-, and revocation-endpoint constructors. + """ + auth_grant = OAuth2AuthorizationCodeGrant(request_validator) + implicit_grant = OAuth2ImplicitGrant(request_validator) + password_grant = ResourceOwnerPasswordCredentialsGrant( + request_validator) + credentials_grant = ClientCredentialsGrant(request_validator) + refresh_grant = RefreshTokenGrant(request_validator) + openid_connect_auth = AuthorizationCodeGrant(request_validator) + openid_connect_implicit = ImplicitGrant(request_validator) + openid_connect_hybrid = HybridGrant(request_validator) + + bearer = BearerToken(request_validator, token_generator, + token_expires_in, refresh_token_generator) + + jwt = JWTToken(request_validator, token_generator, + token_expires_in, refresh_token_generator) + + auth_grant_choice = AuthorizationCodeGrantDispatcher(default_grant=auth_grant, oidc_grant=openid_connect_auth) + implicit_grant_choice = ImplicitTokenGrantDispatcher(default_grant=implicit_grant, oidc_grant=openid_connect_implicit) + + # See http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#Combinations for valid combinations + # internally our AuthorizationEndpoint will ensure they can appear in any order for any valid combination + AuthorizationEndpoint.__init__(self, default_response_type='code', + response_types={ + 'code': auth_grant_choice, + 'token': implicit_grant_choice, + 'id_token': openid_connect_implicit, + 'id_token token': openid_connect_implicit, + 'code token': openid_connect_hybrid, + 'code id_token': openid_connect_hybrid, + 'code id_token token': openid_connect_hybrid, + 'none': auth_grant + }, + default_token_type=bearer) + + token_grant_choice = AuthorizationTokenGrantDispatcher(request_validator, default_grant=auth_grant, oidc_grant=openid_connect_auth) + + TokenEndpoint.__init__(self, default_grant_type='authorization_code', + grant_types={ + 'authorization_code': token_grant_choice, + 'password': password_grant, + 'client_credentials': credentials_grant, + 'refresh_token': refresh_grant, + }, + default_token_type=bearer) + ResourceEndpoint.__init__(self, default_token='Bearer', + token_types={'Bearer': bearer, 'JWT': jwt}) + RevocationEndpoint.__init__(self, request_validator) + IntrospectEndpoint.__init__(self, request_validator) diff --git a/ext/oauthlib/openid/connect/core/exceptions.py b/ext/oauthlib/openid/connect/core/exceptions.py new file mode 100644 index 0000000000..8b08d21f39 --- /dev/null +++ b/ext/oauthlib/openid/connect/core/exceptions.py @@ -0,0 +1,152 @@ +# coding=utf-8 +""" +oauthlib.oauth2.rfc6749.errors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Error used both by OAuth 2 clients and providers to represent the spec +defined error responses for all four core grant types. +""" +from __future__ import unicode_literals + +from oauthlib.oauth2.rfc6749.errors import FatalClientError, OAuth2Error + + +class FatalOpenIDClientError(FatalClientError): + pass + + +class OpenIDClientError(OAuth2Error): + pass + + +class InteractionRequired(OpenIDClientError): + """ + The Authorization Server requires End-User interaction to proceed. + + This error MAY be returned when the prompt parameter value in the + Authentication Request is none, but the Authentication Request cannot be + completed without displaying a user interface for End-User interaction. + """ + error = 'interaction_required' + status_code = 401 + + +class LoginRequired(OpenIDClientError): + """ + The Authorization Server requires End-User authentication. + + This error MAY be returned when the prompt parameter value in the + Authentication Request is none, but the Authentication Request cannot be + completed without displaying a user interface for End-User authentication. + """ + error = 'login_required' + status_code = 401 + + +class AccountSelectionRequired(OpenIDClientError): + """ + The End-User is REQUIRED to select a session at the Authorization Server. + + The End-User MAY be authenticated at the Authorization Server with + different associated accounts, but the End-User did not select a session. + This error MAY be returned when the prompt parameter value in the + Authentication Request is none, but the Authentication Request cannot be + completed without displaying a user interface to prompt for a session to + use. + """ + error = 'account_selection_required' + + +class ConsentRequired(OpenIDClientError): + """ + The Authorization Server requires End-User consent. + + This error MAY be returned when the prompt parameter value in the + Authentication Request is none, but the Authentication Request cannot be + completed without displaying a user interface for End-User consent. + """ + error = 'consent_required' + status_code = 401 + + +class InvalidRequestURI(OpenIDClientError): + """ + The request_uri in the Authorization Request returns an error or + contains invalid data. + """ + error = 'invalid_request_uri' + description = 'The request_uri in the Authorization Request returns an ' \ + 'error or contains invalid data.' + + +class InvalidRequestObject(OpenIDClientError): + """ + The request parameter contains an invalid Request Object. + """ + error = 'invalid_request_object' + description = 'The request parameter contains an invalid Request Object.' + + +class RequestNotSupported(OpenIDClientError): + """ + The OP does not support use of the request parameter. + """ + error = 'request_not_supported' + description = 'The request parameter is not supported.' + + +class RequestURINotSupported(OpenIDClientError): + """ + The OP does not support use of the request_uri parameter. + """ + error = 'request_uri_not_supported' + description = 'The request_uri parameter is not supported.' + + +class RegistrationNotSupported(OpenIDClientError): + """ + The OP does not support use of the registration parameter. + """ + error = 'registration_not_supported' + description = 'The registration parameter is not supported.' + + +class InvalidTokenError(OAuth2Error): + """ + The access token provided is expired, revoked, malformed, or + invalid for other reasons. The resource SHOULD respond with + the HTTP 401 (Unauthorized) status code. The client MAY + request a new access token and retry the protected resource + request. + """ + error = 'invalid_token' + status_code = 401 + description = ("The access token provided is expired, revoked, malformed, " + "or invalid for other reasons.") + + +class InsufficientScopeError(OAuth2Error): + """ + The request requires higher privileges than provided by the + access token. The resource server SHOULD respond with the HTTP + 403 (Forbidden) status code and MAY include the "scope" + attribute with the scope necessary to access the protected + resource. + """ + error = 'insufficient_scope' + status_code = 403 + description = ("The request requires higher privileges than provided by " + "the access token.") + + +def raise_from_error(error, params=None): + import inspect + import sys + kwargs = { + 'description': params.get('error_description'), + 'uri': params.get('error_uri'), + 'state': params.get('state') + } + for _, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass): + if cls.error == error: + raise cls(**kwargs) diff --git a/ext/oauthlib/openid/connect/core/grant_types/__init__.py b/ext/oauthlib/openid/connect/core/grant_types/__init__.py new file mode 100644 index 0000000000..63f30ac94c --- /dev/null +++ b/ext/oauthlib/openid/connect/core/grant_types/__init__.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +""" +oauthlib.openid.connect.core.grant_types +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +""" +from __future__ import unicode_literals, absolute_import + +from .authorization_code import AuthorizationCodeGrant +from .implicit import ImplicitGrant +from .base import GrantTypeBase +from .hybrid import HybridGrant +from .exceptions import OIDCNoPrompt +from .dispatchers import ( + AuthorizationCodeGrantDispatcher, + ImplicitTokenGrantDispatcher, + AuthorizationTokenGrantDispatcher +) diff --git a/ext/oauthlib/openid/connect/core/grant_types/authorization_code.py b/ext/oauthlib/openid/connect/core/grant_types/authorization_code.py new file mode 100644 index 0000000000..b0b1015591 --- /dev/null +++ b/ext/oauthlib/openid/connect/core/grant_types/authorization_code.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +""" +oauthlib.openid.connect.core.grant_types +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +""" +from __future__ import absolute_import, unicode_literals + +import logging + +from oauthlib.oauth2.rfc6749.grant_types.authorization_code import AuthorizationCodeGrant as OAuth2AuthorizationCodeGrant + +from .base import GrantTypeBase + +log = logging.getLogger(__name__) + + +class AuthorizationCodeGrant(GrantTypeBase): + + def __init__(self, request_validator=None, **kwargs): + self.proxy_target = OAuth2AuthorizationCodeGrant( + request_validator=request_validator, **kwargs) + self.custom_validators.post_auth.append( + self.openid_authorization_validator) + self.register_token_modifier(self.add_id_token) diff --git a/ext/oauthlib/oauth2/rfc6749/grant_types/openid_connect.py b/ext/oauthlib/openid/connect/core/grant_types/base.py similarity index 71% rename from ext/oauthlib/oauth2/rfc6749/grant_types/openid_connect.py rename to ext/oauthlib/openid/connect/core/grant_types/base.py index 4c988640a3..fa578a5732 100644 --- a/ext/oauthlib/oauth2/rfc6749/grant_types/openid_connect.py +++ b/ext/oauthlib/openid/connect/core/grant_types/base.py @@ -1,82 +1,15 @@ -# -*- coding: utf-8 -*- -""" -oauthlib.oauth2.rfc6749.grant_types.openid_connect -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -""" -from __future__ import absolute_import, unicode_literals +from .exceptions import OIDCNoPrompt import datetime import logging from json import loads -from ..errors import ConsentRequired, InvalidRequestError, LoginRequired -from ..request_validator import RequestValidator -from .authorization_code import AuthorizationCodeGrant -from .base import GrantTypeBase -from .implicit import ImplicitGrant +from oauthlib.oauth2.rfc6749.errors import ConsentRequired, InvalidRequestError, LoginRequired log = logging.getLogger(__name__) -class OIDCNoPrompt(Exception): - """Exception used to inform users that no explicit authorization is needed. - - Normally users authorize requests after validation of the request is done. - Then post-authorization validation is again made and a response containing - an auth code or token is created. However, when OIDC clients request - no prompting of user authorization the final response is created directly. - - Example (without the shortcut for no prompt) - - scopes, req_info = endpoint.validate_authorization_request(url, ...) - authorization_view = create_fancy_auth_form(scopes, req_info) - return authorization_view - - Example (with the no prompt shortcut) - try: - scopes, req_info = endpoint.validate_authorization_request(url, ...) - authorization_view = create_fancy_auth_form(scopes, req_info) - return authorization_view - except OIDCNoPrompt: - # Note: Location will be set for you - headers, body, status = endpoint.create_authorization_response(url, ...) - redirect_view = create_redirect(headers, body, status) - return redirect_view - """ - - def __init__(self): - msg = ("OIDC request for no user interaction received. Do not ask user " - "for authorization, it should been done using silent " - "authentication through create_authorization_response. " - "See OIDCNoPrompt.__doc__ for more details.") - super(OIDCNoPrompt, self).__init__(msg) - - -class AuthCodeGrantDispatcher(object): - """ - This is an adapter class that will route simple Authorization Code requests, those that have response_type=code and a scope - including 'openid' to either the default_auth_grant or the oidc_auth_grant based on the scopes requested. - """ - def __init__(self, default_auth_grant=None, oidc_auth_grant=None): - self.default_auth_grant = default_auth_grant - self.oidc_auth_grant = oidc_auth_grant - - def _handler_for_request(self, request): - handler = self.default_auth_grant - - if request.scopes and "openid" in request.scopes: - handler = self.oidc_auth_grant - - log.debug('Selecting handler for request %r.', handler) - return handler - - def create_authorization_response(self, request, token_handler): - return self._handler_for_request(request).create_authorization_response(request, token_handler) - def validate_authorization_request(self, request): - return self._handler_for_request(request).validate_authorization_request(request) - - -class OpenIDConnectBase(object): +class GrantTypeBase(object): # Just proxy the majority of method calls through to the # proxy_target grant type handler, which will usually be either @@ -292,12 +225,6 @@ def openid_authorization_validator(self, request): msg = "Prompt none is mutually exclusive with other values." raise InvalidRequestError(request=request, description=msg) - # prompt other than 'none' should be handled by the server code that - # uses oauthlib - if not request.id_token_hint: - msg = "Prompt is set to none yet id_token_hint is missing." - raise InvalidRequestError(request=request, description=msg) - if not self.request_validator.validate_silent_login(request): raise LoginRequired(request=request) @@ -307,7 +234,7 @@ def openid_authorization_validator(self, request): self._inflate_claims(request) if not self.request_validator.validate_user_match( - request.id_token_hint, request.scopes, request.claims, request): + request.id_token_hint, request.scopes, request.claims, request): msg = "Session user does not match client supplied user." raise LoginRequired(request=request, description=msg) @@ -347,44 +274,4 @@ def openid_implicit_authorization_validator(self, request): return {} -class OpenIDConnectAuthCode(OpenIDConnectBase): - - def __init__(self, request_validator=None, **kwargs): - self.proxy_target = AuthorizationCodeGrant( - request_validator=request_validator, **kwargs) - self.custom_validators.post_auth.append( - self.openid_authorization_validator) - self.register_token_modifier(self.add_id_token) - -class OpenIDConnectImplicit(OpenIDConnectBase): - - def __init__(self, request_validator=None, **kwargs): - self.proxy_target = ImplicitGrant( - request_validator=request_validator, **kwargs) - self.register_response_type('id_token') - self.register_response_type('id_token token') - self.custom_validators.post_auth.append( - self.openid_authorization_validator) - self.custom_validators.post_auth.append( - self.openid_implicit_authorization_validator) - self.register_token_modifier(self.add_id_token) - -class OpenIDConnectHybrid(OpenIDConnectBase): - - def __init__(self, request_validator=None, **kwargs): - self.request_validator = request_validator or RequestValidator() - - self.proxy_target = AuthorizationCodeGrant( - request_validator=request_validator, **kwargs) - # All hybrid response types should be fragment-encoded. - self.proxy_target.default_response_mode = "fragment" - self.register_response_type('code id_token') - self.register_response_type('code token') - self.register_response_type('code id_token token') - self.custom_validators.post_auth.append( - self.openid_authorization_validator) - # Hybrid flows can return the id_token from the authorization - # endpoint as part of the 'code' response - self.register_code_modifier(self.add_token) - self.register_code_modifier(self.add_id_token) - self.register_token_modifier(self.add_id_token) +OpenIDConnectBase = GrantTypeBase diff --git a/ext/oauthlib/openid/connect/core/grant_types/dispatchers.py b/ext/oauthlib/openid/connect/core/grant_types/dispatchers.py new file mode 100644 index 0000000000..be8e2f3cb2 --- /dev/null +++ b/ext/oauthlib/openid/connect/core/grant_types/dispatchers.py @@ -0,0 +1,91 @@ +import logging +log = logging.getLogger(__name__) + + +class Dispatcher(object): + default_grant = None + oidc_grant = None + + +class AuthorizationCodeGrantDispatcher(Dispatcher): + """ + This is an adapter class that will route simple Authorization Code requests, those that have response_type=code and a scope + including 'openid' to either the default_grant or the oidc_grant based on the scopes requested. + """ + def __init__(self, default_grant=None, oidc_grant=None): + self.default_grant = default_grant + self.oidc_grant = oidc_grant + + def _handler_for_request(self, request): + handler = self.default_grant + + if request.scopes and "openid" in request.scopes: + handler = self.oidc_grant + + log.debug('Selecting handler for request %r.', handler) + return handler + + def create_authorization_response(self, request, token_handler): + return self._handler_for_request(request).create_authorization_response(request, token_handler) + + def validate_authorization_request(self, request): + return self._handler_for_request(request).validate_authorization_request(request) + + +class ImplicitTokenGrantDispatcher(Dispatcher): + """ + This is an adapter class that will route simple Authorization Code requests, those that have response_type=code and a scope + including 'openid' to either the default_grant or the oidc_grant based on the scopes requested. + """ + def __init__(self, default_grant=None, oidc_grant=None): + self.default_grant = default_grant + self.oidc_grant = oidc_grant + + def _handler_for_request(self, request): + handler = self.default_grant + + if request.scopes and "openid" in request.scopes and 'id_token' in request.response_type: + handler = self.oidc_grant + + log.debug('Selecting handler for request %r.', handler) + return handler + + def create_authorization_response(self, request, token_handler): + return self._handler_for_request(request).create_authorization_response(request, token_handler) + + def validate_authorization_request(self, request): + return self._handler_for_request(request).validate_authorization_request(request) + + +class AuthorizationTokenGrantDispatcher(Dispatcher): + """ + This is an adapter class that will route simple Token requests, those that authorization_code have a scope + including 'openid' to either the default_grant or the oidc_grant based on the scopes requested. + """ + def __init__(self, request_validator, default_grant=None, oidc_grant=None): + self.default_grant = default_grant + self.oidc_grant = oidc_grant + self.request_validator = request_validator + + def _handler_for_request(self, request): + handler = self.default_grant + scopes = () + parameters = dict(request.decoded_body) + client_id = parameters.get('client_id', None) + code = parameters.get('code', None) + redirect_uri = parameters.get('redirect_uri', None) + + # If code is not pressent fallback to `default_grant` wich will + # raise an error for the missing `code` in `create_token_response` step. + if code: + scopes = self.request_validator.get_authorization_code_scopes(client_id, code, redirect_uri, request) + + if 'openid' in scopes: + handler = self.oidc_grant + + log.debug('Selecting handler for request %r.', handler) + return handler + + def create_token_response(self, request, token_handler): + handler = self._handler_for_request(request) + return handler.create_token_response(request, token_handler) diff --git a/ext/oauthlib/openid/connect/core/grant_types/exceptions.py b/ext/oauthlib/openid/connect/core/grant_types/exceptions.py new file mode 100644 index 0000000000..809f1b3be5 --- /dev/null +++ b/ext/oauthlib/openid/connect/core/grant_types/exceptions.py @@ -0,0 +1,32 @@ +class OIDCNoPrompt(Exception): + """Exception used to inform users that no explicit authorization is needed. + + Normally users authorize requests after validation of the request is done. + Then post-authorization validation is again made and a response containing + an auth code or token is created. However, when OIDC clients request + no prompting of user authorization the final response is created directly. + + Example (without the shortcut for no prompt) + + scopes, req_info = endpoint.validate_authorization_request(url, ...) + authorization_view = create_fancy_auth_form(scopes, req_info) + return authorization_view + + Example (with the no prompt shortcut) + try: + scopes, req_info = endpoint.validate_authorization_request(url, ...) + authorization_view = create_fancy_auth_form(scopes, req_info) + return authorization_view + except OIDCNoPrompt: + # Note: Location will be set for you + headers, body, status = endpoint.create_authorization_response(url, ...) + redirect_view = create_redirect(headers, body, status) + return redirect_view + """ + + def __init__(self): + msg = ("OIDC request for no user interaction received. Do not ask user " + "for authorization, it should been done using silent " + "authentication through create_authorization_response. " + "See OIDCNoPrompt.__doc__ for more details.") + super(OIDCNoPrompt, self).__init__(msg) diff --git a/ext/oauthlib/openid/connect/core/grant_types/hybrid.py b/ext/oauthlib/openid/connect/core/grant_types/hybrid.py new file mode 100644 index 0000000000..54669ae451 --- /dev/null +++ b/ext/oauthlib/openid/connect/core/grant_types/hybrid.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +""" +oauthlib.openid.connect.core.grant_types +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +""" +from __future__ import absolute_import, unicode_literals + +import logging + +from oauthlib.oauth2.rfc6749.grant_types.authorization_code import AuthorizationCodeGrant as OAuth2AuthorizationCodeGrant + +from .base import GrantTypeBase +from ..request_validator import RequestValidator + +log = logging.getLogger(__name__) + + +class HybridGrant(GrantTypeBase): + + def __init__(self, request_validator=None, **kwargs): + self.request_validator = request_validator or RequestValidator() + + self.proxy_target = OAuth2AuthorizationCodeGrant( + request_validator=request_validator, **kwargs) + # All hybrid response types should be fragment-encoded. + self.proxy_target.default_response_mode = "fragment" + self.register_response_type('code id_token') + self.register_response_type('code token') + self.register_response_type('code id_token token') + self.custom_validators.post_auth.append( + self.openid_authorization_validator) + # Hybrid flows can return the id_token from the authorization + # endpoint as part of the 'code' response + self.register_code_modifier(self.add_token) + self.register_code_modifier(self.add_id_token) + self.register_token_modifier(self.add_id_token) diff --git a/ext/oauthlib/openid/connect/core/grant_types/implicit.py b/ext/oauthlib/openid/connect/core/grant_types/implicit.py new file mode 100644 index 0000000000..0eaa5b38ea --- /dev/null +++ b/ext/oauthlib/openid/connect/core/grant_types/implicit.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +""" +oauthlib.openid.connect.core.grant_types +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +""" +from __future__ import absolute_import, unicode_literals + +import logging + +from .base import GrantTypeBase + +from oauthlib.oauth2.rfc6749.grant_types.implicit import ImplicitGrant as OAuth2ImplicitGrant + +log = logging.getLogger(__name__) + + +class ImplicitGrant(GrantTypeBase): + + def __init__(self, request_validator=None, **kwargs): + self.proxy_target = OAuth2ImplicitGrant( + request_validator=request_validator, **kwargs) + self.register_response_type('id_token') + self.register_response_type('id_token token') + self.custom_validators.post_auth.append( + self.openid_authorization_validator) + self.custom_validators.post_auth.append( + self.openid_implicit_authorization_validator) + self.register_token_modifier(self.add_id_token) diff --git a/ext/oauthlib/openid/connect/core/request_validator.py b/ext/oauthlib/openid/connect/core/request_validator.py new file mode 100644 index 0000000000..15877541b6 --- /dev/null +++ b/ext/oauthlib/openid/connect/core/request_validator.py @@ -0,0 +1,195 @@ +# -*- coding: utf-8 -*- +""" +oauthlib.openid.connect.core.request_validator +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +""" +from __future__ import absolute_import, unicode_literals + +import logging + +from oauthlib.oauth2.rfc6749.request_validator import RequestValidator as OAuth2RequestValidator + +log = logging.getLogger(__name__) + + +class RequestValidator(OAuth2RequestValidator): + + def get_authorization_code_scopes(self, client_id, code, redirect_uri, request): + """ Extracts scopes from saved authorization code. + + The scopes returned by this method is used to route token requests + based on scopes passed to Authorization Code requests. + + With that the token endpoint knows when to include OpenIDConnect + id_token in token response only based on authorization code scopes. + + Only code param should be sufficient to retrieve grant code from + any storage you are using, `client_id` and `redirect_uri` can gave a + blank value `""` don't forget to check it before using those values + in a select query if a database is used. + + :param client_id: Unicode client identifier + :param code: Unicode authorization code grant + :param redirect_uri: Unicode absolute URI + :return: A list of scope + + Method is used by: + - Authorization Token Grant Dispatcher + """ + raise NotImplementedError('Subclasses must implement this method.') + + def get_jwt_bearer_token(self, token, token_handler, request): + """Get JWT Bearer token or OpenID Connect ID token + + If using OpenID Connect this SHOULD call `oauthlib.oauth2.RequestValidator.get_id_token` + + :param token: A Bearer token dict + :param token_handler: the token handler (BearerToken class) + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :return: The JWT Bearer token or OpenID Connect ID token (a JWS signed JWT) + + Method is used by JWT Bearer and OpenID Connect tokens: + - JWTToken.create_token + """ + raise NotImplementedError('Subclasses must implement this method.') + + def get_id_token(self, token, token_handler, request): + """Get OpenID Connect ID token + + In the OpenID Connect workflows when an ID Token is requested this method is called. + Subclasses should implement the construction, signing and optional encryption of the + ID Token as described in the OpenID Connect spec. + + In addition to the standard OAuth2 request properties, the request may also contain + these OIDC specific properties which are useful to this method: + + - nonce, if workflow is implicit or hybrid and it was provided + - claims, if provided to the original Authorization Code request + + The token parameter is a dict which may contain an ``access_token`` entry, in which + case the resulting ID Token *should* include a calculated ``at_hash`` claim. + + Similarly, when the request parameter has a ``code`` property defined, the ID Token + *should* include a calculated ``c_hash`` claim. + + http://openid.net/specs/openid-connect-core-1_0.html (sections `3.1.3.6`_, `3.2.2.10`_, `3.3.2.11`_) + + .. _`3.1.3.6`: http://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken + .. _`3.2.2.10`: http://openid.net/specs/openid-connect-core-1_0.html#ImplicitIDToken + .. _`3.3.2.11`: http://openid.net/specs/openid-connect-core-1_0.html#HybridIDToken + + :param token: A Bearer token dict + :param token_handler: the token handler (BearerToken class) + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :return: The ID Token (a JWS signed JWT) + """ + # the request.scope should be used by the get_id_token() method to determine which claims to include in the resulting id_token + raise NotImplementedError('Subclasses must implement this method.') + + def validate_jwt_bearer_token(self, token, scopes, request): + """Ensure the JWT Bearer token or OpenID Connect ID token are valids and authorized access to scopes. + + If using OpenID Connect this SHOULD call `oauthlib.oauth2.RequestValidator.get_id_token` + + If not using OpenID Connect this can `return None` to avoid 5xx rather 401/3 response. + + OpenID connect core 1.0 describe how to validate an id_token: + - http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation + - http://openid.net/specs/openid-connect-core-1_0.html#ImplicitIDTValidation + - http://openid.net/specs/openid-connect-core-1_0.html#HybridIDTValidation + - http://openid.net/specs/openid-connect-core-1_0.html#HybridIDTValidation2 + + :param token: Unicode Bearer token + :param scopes: List of scopes (defined by you) + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :rtype: True or False + + Method is indirectly used by all core OpenID connect JWT token issuing grant types: + - Authorization Code Grant + - Implicit Grant + - Hybrid Grant + """ + raise NotImplementedError('Subclasses must implement this method.') + + def validate_id_token(self, token, scopes, request): + """Ensure the id token is valid and authorized access to scopes. + + OpenID connect core 1.0 describe how to validate an id_token: + - http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation + - http://openid.net/specs/openid-connect-core-1_0.html#ImplicitIDTValidation + - http://openid.net/specs/openid-connect-core-1_0.html#HybridIDTValidation + - http://openid.net/specs/openid-connect-core-1_0.html#HybridIDTValidation2 + + :param token: Unicode Bearer token + :param scopes: List of scopes (defined by you) + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :rtype: True or False + + Method is indirectly used by all core OpenID connect JWT token issuing grant types: + - Authorization Code Grant + - Implicit Grant + - Hybrid Grant + """ + raise NotImplementedError('Subclasses must implement this method.') + + def validate_silent_authorization(self, request): + """Ensure the logged in user has authorized silent OpenID authorization. + + Silent OpenID authorization allows access tokens and id tokens to be + granted to clients without any user prompt or interaction. + + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :rtype: True or False + + Method is used by: + - OpenIDConnectAuthCode + - OpenIDConnectImplicit + - OpenIDConnectHybrid + """ + raise NotImplementedError('Subclasses must implement this method.') + + def validate_silent_login(self, request): + """Ensure session user has authorized silent OpenID login. + + If no user is logged in or has not authorized silent login, this + method should return False. + + If the user is logged in but associated with multiple accounts and + not selected which one to link to the token then this method should + raise an oauthlib.oauth2.AccountSelectionRequired error. + + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :rtype: True or False + + Method is used by: + - OpenIDConnectAuthCode + - OpenIDConnectImplicit + - OpenIDConnectHybrid + """ + raise NotImplementedError('Subclasses must implement this method.') + + def validate_user_match(self, id_token_hint, scopes, claims, request): + """Ensure client supplied user id hint matches session user. + + If the sub claim or id_token_hint is supplied then the session + user must match the given ID. + + :param id_token_hint: User identifier string. + :param scopes: List of OAuth 2 scopes and OpenID claims (strings). + :param claims: OpenID Connect claims dict. + :param request: OAuthlib request. + :type request: oauthlib.common.Request + :rtype: True or False + + Method is used by: + - OpenIDConnectAuthCode + - OpenIDConnectImplicit + - OpenIDConnectHybrid + """ + raise NotImplementedError('Subclasses must implement this method.') diff --git a/ext/oauthlib/openid/connect/core/tokens.py b/ext/oauthlib/openid/connect/core/tokens.py new file mode 100644 index 0000000000..6b68891aba --- /dev/null +++ b/ext/oauthlib/openid/connect/core/tokens.py @@ -0,0 +1,54 @@ +""" +authlib.openid.connect.core.tokens +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This module contains methods for adding JWT tokens to requests. +""" +from __future__ import absolute_import, unicode_literals + + +from oauthlib.oauth2.rfc6749.tokens import TokenBase, random_token_generator + + +class JWTToken(TokenBase): + __slots__ = ( + 'request_validator', 'token_generator', + 'refresh_token_generator', 'expires_in' + ) + + def __init__(self, request_validator=None, token_generator=None, + expires_in=None, refresh_token_generator=None): + self.request_validator = request_validator + self.token_generator = token_generator or random_token_generator + self.refresh_token_generator = ( + refresh_token_generator or self.token_generator + ) + self.expires_in = expires_in or 3600 + + def create_token(self, request, refresh_token=False, save_token=False): + """Create a JWT Token, using requestvalidator method.""" + + if callable(self.expires_in): + expires_in = self.expires_in(request) + else: + expires_in = self.expires_in + + request.expires_in = expires_in + + return self.request_validator.get_jwt_bearer_token(None, None, request) + + def validate_request(self, request): + token = None + if 'Authorization' in request.headers: + token = request.headers.get('Authorization')[7:] + else: + token = request.access_token + return self.request_validator.validate_jwt_bearer_token( + token, request.scopes, request) + + def estimate_type(self, request): + token = request.headers.get('Authorization', '')[7:] + if token.startswith('ey') and token.count('.') in (2, 4): + return 10 + else: + return 0 diff --git a/ext/oauthlib/signals.py b/ext/oauthlib/signals.py index 2f86650579..22d47a415e 100644 --- a/ext/oauthlib/signals.py +++ b/ext/oauthlib/signals.py @@ -8,7 +8,7 @@ try: from blinker import Namespace signals_available = True -except ImportError: +except ImportError: # noqa class Namespace(object): def signal(self, name, doc=None): return _FakeSignal(name, doc) diff --git a/ext/readme.md b/ext/readme.md index bd948bf75a..e3dd35c425 100644 --- a/ext/readme.md +++ b/ext/readme.md @@ -1,69 +1,72 @@ ## ext Status | Package | Version / Commit | Usage | Folder | Notes :------: | :-------: | :----------------: | :---- | :--: | :---- -:: | `adba` | pymedusa/[fcb4bf4](https://github.com/pymedusa/adba/tree/fcb4bf43f10ca53f3beb915707c877581b1bf2a5) | **`medusa`** | ext | - +:: | `adba` | pymedusa/[6502307](https://github.com/pymedusa/adba/tree/6502307ae34286e44b28234cfbacee6df1eadf07) | **`medusa`** | ext | - :: | appdirs.py | [1.4.3](https://pypi.org/project/appdirs/1.4.3/) | `subliminal` (cli only), `simpleanidb` | ext | - :: | `attrs` | [18.2.0](https://pypi.org/project/attrs/18.2.0/) | `imdbpie` | ext | Module: `attr` :: | `babelfish` | [f403000](https://github.com/Diaoul/babelfish/tree/f403000dd63092cfaaae80be9f309fd85c7f20c9) | **`medusa`**, `guessit`, `knowit`, `subliminal` | ext | - +:: | `backports.functools_lru_cache` | [1.5](https://pypi.org/project/backports.functools_lru_cache/1.5/) | `soupsieve` | **ext2** | - :: | backports_abc.py | [0.5](https://pypi.org/project/backports_abc/0.5/) | `tornado` | ext | Markers: `python_version < '3.5'` -:: | `beautifulsoup4` | [4.6.3](https://pypi.org/project/beautifulsoup4/4.6.3/) | **`medusa`**, `subliminal` | **ext2 ext3** | Module: `bs4` +:: | `beautifulsoup4` | [4.7.1](https://pypi.org/project/beautifulsoup4/4.7.1/) | **`medusa`**, `subliminal` | **ext2 ext3** | Module: `bs4` :: | `bencode.py` | [2.0.0](https://pypi.org/project/bencode.py/2.0.0/) | **`medusa`** | ext | Module: `bencode` :: | `boto` | [2.48.0](https://pypi.org/project/boto/2.48.0/) | `imdbpie` | ext | - :: | `CacheControl` | [0.12.5](https://pypi.org/project/CacheControl/0.12.5/) | **`medusa`** | ext | Module: `cachecontrol` -:: | `certifi` | [2018.10.15](https://pypi.org/project/certifi/2018.10.15/) | **`medusa`**, `traktor`, `requests` | ext | - +:: | `certifi` | [2019.3.9](https://pypi.org/project/certifi/2019.3.9/) | **`medusa`**, `traktor`, `requests` | ext | - :: | `chardet` | [3.0.4](https://pypi.org/project/chardet/3.0.4/) | **`medusa`**, `beautifulsoup4`, `feedparser`, `html5lib`, `pysrt`, `requests`, `subliminal` | ext | - :: | `cloudflare-scrape` | pymedusa/[320456e](https://github.com/pymedusa/cloudflare-scrape/tree/320456e8b28cedb807363a7a892b1379db843f66) | **`medusa`** | ext | Module: `cfscrape` :: | configobj.py
`validate.py`
`_version.py` | [5.0.6](https://pypi.org/project/configobj/5.0.6/) | **`medusa`** | ext | - -:: | configparser.py
`configparser.pth`
`backports.configparser` | [3.5.0](https://pypi.org/project/configparser/3.5.0/) | `adba` | ext | `configparser.pth` was renamed from `configparser-3.5.0-py2.7-nspkg.pth` +:: | configparser.py
`backports.configparser` | [3.7.3](https://pypi.org/project/configparser/3.7.3/) | `adba` | **ext2** | - :: | contextlib2.py | [0.5.5](https://pypi.org/project/contextlib2/0.5.5/) | **`medusa`**, `tvdbapiv2` | ext | Markers: `python_version < '3.5'` -:: | decorator.py | [4.3.0](https://pypi.org/project/decorator/4.3.0/) | `validators` | ext | - +:: | decorator.py | [4.3.0](https://pypi.org/project/decorator/4.3.0/) | `dogpile.cache`, `validators` | ext | - +:: | `deluge-client` | [1.7.0](https://pypi.org/project/deluge-client/1.7.0/) | **`medusa`** | ext | - :: | `deprecated` | [1.2.3](https://pypi.org/project/deprecated/1.2.3/) | `PyGithub` | ext | - :: | `dirtyjson` | [1.0.7](https://pypi.org/project/dirtyjson/1.0.7/) | **`medusa`** | ext | - :: | `diskcache` | [2.9.0](https://pypi.org/project/diskcache/2.9.0/) | `imdbpie` | ext | - -:: | `dogpile.cache` | [0.6.7](https://pypi.org/project/dogpile.cache/0.6.7/) | **`medusa`**, `subliminal` | ext | - +:: | `dogpile.cache` | [0.7.1](https://pypi.org/project/dogpile.cache/0.7.1/) | **`medusa`**, `subliminal` | ext | - :: | `enum34` | [1.1.6](https://pypi.org/project/enum34/1.1.6/) | **`medusa`** | **ext2** | Module: `enum`
Backport from Python 3.4 :: | `enzyme` | pymedusa/[665cf69](https://github.com/pymedusa/enzyme/tree/665cf6948aab1c249dcc99bd9624a81d17b3302a) | `knowit`, `subliminal` | ext | - :: | `feedparser` | [2b11c80](https://github.com/kurtmckee/feedparser/tree/2b11c8028321ed43cbaf313f83b0c94820143d66) | **`medusa`** | ext | Requires `sgmllib3k` on Python 3 :: | **`future`**
`_dummy_thread`
`_markupbase`
`_thread`
`builtins`
`copyreg`
`html`
`http`
`libfuturize`
`libpasteurize`
`past`
`queue`
`reprlib`
`socketserver`
`tkinter`
`winreg`
`xmlrpc` | [0.17.1](https://pypi.org/project/future/0.17.1/) | **`medusa`**, `python-twitter`, ????? | **ext2** | - :: | `futures` | [3.2.0](https://pypi.org/project/futures/3.2.0/) | **`medusa`**, `subliminal`, `tornado` | **ext2** | Module: `concurrent.futures`
Markers: `python_version >= '2.6' and python_version < '3'` -:: | `PyGithub` | [1.43.3](https://pypi.org/project/PyGithub/1.43.3/) | **`medusa`** | **ext2 ext3** | Module: `github`
**Removed tests** +:: | `PyGithub` | [1.43.5](https://pypi.org/project/PyGithub/1.43.5/) | **`medusa`** | **ext2 ext3** | Module: `github`
**Removed tests** :: | `gntp` | [1.0.3](https://pypi.org/project/gntp/1.0.3/) | **`medusa`** | ext | - -:: | `guessit` | [3.0.3](https://pypi.org/project/guessit/3.0.3/) | **`medusa`**, `subliminal` | ext | - +:: | `guessit` | [74dbb0c](https://github.com/guessit-io/guessit/tree/74dbb0c7420cee18969926aba9cc06b8959daa0e) | **`medusa`**, `subliminal` | ext | - :: | `html5lib` | [1.0.1](https://pypi.org/project/html5lib/1.0.1/) | **`medusa`** (via `beautifulsoup4`) | ext | - -:: | `idna` | [2.7](https://pypi.org/project/idna/2.7/) | `requests` | ext | - +:: | `idna` | [2.8](https://pypi.org/project/idna/2.8/) | `requests` | ext | - :: | `imdbpie` | [5.6.3](https://pypi.org/project/imdbpie/5.6.3/) | **`medusa`** | ext | - :: | `Js2Py` | [0.59](https://pypi.org/project/Js2Py/0.59/) | `cloudflare-scrape` | ext | Module: `js2py` -:: | `jsonrpclib-pelix` | [0.3.2](https://pypi.org/project/jsonrpclib-pelix/0.3.2/) | **`medusa`** | ext | Module: `jsonrpclib` -:: | `PyJWT` | [1.6.4](https://pypi.org/project/pyjwt/1.6.4/) | **`medusa`**, `PyGithub`, `tvdbapiv2` | ext | Module: `jwt` +:: | `jsonrpclib-pelix` | [0.4.0](https://pypi.org/project/jsonrpclib-pelix/0.4.0/) | **`medusa`** | ext | Module: `jsonrpclib` +:: | `PyJWT` | [1.7.1](https://pypi.org/project/pyjwt/1.7.1/) | **`medusa`**, `PyGithub`, `tvdbapiv2` | ext | Module: `jwt` :: | `knowit` | [0.2.4](https://pypi.org/project/knowit/0.2.4/) | **`medusa`** | ext | - :: | `lockfile` | [0.12.2](https://pypi.org/project/lockfile/0.12.2/) | `CacheControl` | ext | - :: | `Mako` | [1.0.7](https://pypi.org/project/mako/1.0.7/) | **`medusa`** | ext | Module: `mako` -:: | markdown2.py | [2.3.6](https://pypi.org/project/markdown2/2.3.6/) | **`medusa`** | ext | - +:: | markdown2.py | [2.3.7](https://pypi.org/project/markdown2/2.3.7/) | **`medusa`** | ext | - :: | `MarkupSafe` | [1.0](https://pypi.org/project/MarkupSafe/1.0/) | `Mako` | ext | Module: `markupsafe` :: | `msgpack` | [0.5.6](https://pypi.org/project/msgpack/0.5.6/) | `CacheControl` | ext | - -:: | `oauthlib` | [2.1.0](https://pypi.org/project/oauthlib/2.1.0/) | `requests-oauthlib` | ext | - +:: | `oauthlib` | [3.0.0](https://pypi.org/project/oauthlib/3.0.0/) | `requests-oauthlib` | ext | - :: | `Pint` | [0.8.1](https://pypi.org/project/Pint/0.8.1/) | `knowit` | ext | Module: `pint` :: | profilehooks.py | [1.10.0](https://pypi.org/project/profilehooks/1.10.0/) | **`medusa`** | ext | - :: | `pyjsparser` | [2.5.2](https://pypi.org/project/pyjsparser/2.5.2/) | `Js2Py` | ext | - :: | `pysrt` | [1.1.0](https://pypi.org/project/pysrt/1.1.0/) | `subliminal` | ext | - -:: | `python-dateutil` | [2.7.5](https://pypi.org/project/python-dateutil/2.7.5/) | **`medusa`**, `tvdbapiv2`, `guessit`, `imdbpie` | ext | Module: `dateutil` +:: | `python-dateutil` | [2.8.0](https://pypi.org/project/python-dateutil/2.8.0/) | **`medusa`**, `tvdbapiv2`, `guessit`, `imdbpie` | ext | Module: `dateutil` :: | `python-twitter` | [3.5](https://pypi.org/project/python-twitter/3.5/) | **`medusa`** | ext | Module: `twitter` :: | `pytz` | [2018.4](https://pypi.org/project/pytz/2018.4/) | `subliminal`, `tzlocal` | ext | - :: | rarfile.py | [3.0](https://pypi.org/project/rarfile/3.0/) | **`medusa`**, `subliminal` | ext | - :: | `rebulk` | [1.0.0](https://pypi.org/project/rebulk/1.0.0/) | **`medusa`**, `guessit` | ext | - -:: | `requests` | [2.20.1](https://pypi.org/project/requests/2.20.1/) | **`medusa`**, `adba`, `pytvmaze`, `simpleanidb`, `tmdbsimple`, `traktor`, `tvdbapiv2`, `boto`, `rtorrent`, `CacheControl`, `cloudflare-scrape`, `subliminal`, `PyGithub`, `python-twitter` | ext | - -:: | `requests-oauthlib` | [1.0.0](https://pypi.org/project/requests-oauthlib/1.0.0/) | **`medusa`**, `python-twitter` | ext | Module: `requests_oauthlib` +:: | `requests` | [2.21.0](https://pypi.org/project/requests/2.21.0/) | **`medusa`**, `adba`, `pytvmaze`, `simpleanidb`, `tmdbsimple`, `traktor`, `tvdbapiv2`, `boto`, `rtorrent`, `CacheControl`, `cloudflare-scrape`, `subliminal`, `PyGithub`, `python-twitter` | ext | - +:: | `requests-oauthlib` | [1.2.0](https://pypi.org/project/requests-oauthlib/1.2.0/) | **`medusa`**, `python-twitter` | ext | Module: `requests_oauthlib` :: | sgmllib3k | [1.0.0](https://pypi.org/project/sgmllib3k/1.0.0/) | `feedparser` | **ext3** | File: `sgmllib.py` :: | singledispatch.py
`singledispatch_helpers.py` | [3.4.0.3](https://pypi.org/project/singledispatch/3.4.0.3/) | `tornado` | ext | Markers: `python_version < '3.4'` -:: | six.py | [1.11.0](https://pypi.org/project/six/1.11.0/) | **`medusa`**, `tvdbapiv2`, `configobj`, `python-dateutil`, `guessit`, `html5lib`, `imdbpie`, `Js2Py`, `knowit`, `rebulk`, `subliminal`, `validators` | ext | - -:: | `stevedore` | [1.30.0](https://pypi.org/project/stevedore/1.30.0/) | `subliminal` | ext | - -:: | `subliminal` | pymedusa/[78687f4](https://github.com/pymedusa/subliminal/tree/78687f45d23b1bc47fae0a5493be0198dc1fd5b5) | **`medusa`** | ext | - +:: | six.py | [1.12.0](https://pypi.org/project/six/1.12.0/) | **`medusa`**, `tvdbapiv2`, `configobj`, `python-dateutil`, `guessit`, `html5lib`, `imdbpie`, `Js2Py`, `knowit`, `rebulk`, `subliminal`, `validators` | ext | - +:: | `soupsieve` | [1.7](https://pypi.org/project/soupsieve/1.7/) | `beautifulsoup4` | ext | - +:: | `stevedore` | [1.30.1](https://pypi.org/project/stevedore/1.30.1/) | `subliminal` | ext | - +:: | `subliminal` | [6ac2fa23](https://github.com/Diaoul/subliminal/tree/6ac2fa23ee5baa7d8452552edaa7c4a8a00d237a) | **`medusa`** | ext | - :: | `tornado` | [5.1.1](https://pypi.org/project/tornado/5.1.1/) | **`medusa`**, `tornroutes` | ext | - :: | `tornroutes` | [0.5.1](https://pypi.org/project/tornroutes/0.5.1/) | **`medusa`** | ext | - :: | `trans` | [2.1.0](https://pypi.org/project/trans/2.1.0/) | `imdbpie` | ext | - :: | `tzlocal` | [1.5.1](https://pypi.org/project/tzlocal/1.5.1/) | `Js2Py` | ext | - -:: | `urllib3` | [1.23](https://pypi.org/project/urllib3/1.23/) | `requests`, `CacheControl` | ext | - -:: | `validators` | [0.12.3](https://pypi.org/project/validators/0.12.3/) | **`medusa`** | ext | - +:: | `urllib3` | [1.24.1](https://pypi.org/project/urllib3/1.24.1/) | `requests`, `CacheControl` | ext | - +:: | `validators` | [0.12.4](https://pypi.org/project/validators/0.12.4/) | **`medusa`** | ext | - :: | `webencodings` | [0.5.1](https://pypi.org/project/webencodings/0.5.1/) | `html5lib` | ext | - :: | `wrapt` | [1.10.11](https://pypi.org/project/wrapt/1.10.11/) | `deprecated` | ext | - :: | `PyYAML` | [3.13](https://pypi.org/project/PyYAML/3.13/) | `knowit` | **ext2 ext3** | Module: `yaml` diff --git a/ext/requests/__version__.py b/ext/requests/__version__.py index 803773a0fd..f5b5d03671 100644 --- a/ext/requests/__version__.py +++ b/ext/requests/__version__.py @@ -5,8 +5,8 @@ __title__ = 'requests' __description__ = 'Python HTTP for Humans.' __url__ = 'http://python-requests.org' -__version__ = '2.20.1' -__build__ = 0x022001 +__version__ = '2.21.0' +__build__ = 0x022100 __author__ = 'Kenneth Reitz' __author_email__ = 'me@kennethreitz.org' __license__ = 'Apache 2.0' diff --git a/ext/requests/models.py b/ext/requests/models.py index 3dded57eff..62dcd0b7c8 100644 --- a/ext/requests/models.py +++ b/ext/requests/models.py @@ -781,7 +781,7 @@ def generate(): return chunks - def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None, delimiter=None): + def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=False, delimiter=None): """Iterates over the response data, one line at a time. When stream=True is set on the request, this avoids reading the content at once into memory for large responses. diff --git a/ext/requests_oauthlib/__init__.py b/ext/requests_oauthlib/__init__.py index 1bb919eeec..24cd34ade7 100644 --- a/ext/requests_oauthlib/__init__.py +++ b/ext/requests_oauthlib/__init__.py @@ -5,7 +5,7 @@ from .oauth2_auth import OAuth2 from .oauth2_session import OAuth2Session, TokenUpdated -__version__ = '1.0.0' +__version__ = '1.2.0' import requests if requests.__version__ < '2.0.0': diff --git a/ext/requests_oauthlib/oauth1_session.py b/ext/requests_oauthlib/oauth1_session.py index 53b7b6d123..df9b6dbc56 100644 --- a/ext/requests_oauthlib/oauth1_session.py +++ b/ext/requests_oauthlib/oauth1_session.py @@ -24,7 +24,7 @@ def urldecode(body): """Parse query or json to python dictionary""" try: return _urldecode(body) - except: + except Exception: import json return json.loads(body) @@ -255,7 +255,7 @@ def authorization_url(self, url, request_token=None, **kwargs): return add_params_to_uri(url, kwargs.items()) def fetch_request_token(self, url, realm=None, **request_kwargs): - """Fetch a request token. + r"""Fetch a request token. This is the first step in the OAuth 1 workflow. A request token is obtained by making a signed post request to url. The token is then diff --git a/ext/requests_oauthlib/oauth2_session.py b/ext/requests_oauthlib/oauth2_session.py index e5ad72c2df..80778490d3 100644 --- a/ext/requests_oauthlib/oauth2_session.py +++ b/ext/requests_oauthlib/oauth2_session.py @@ -4,6 +4,7 @@ from oauthlib.common import generate_token, urldecode from oauthlib.oauth2 import WebApplicationClient, InsecureTransportError +from oauthlib.oauth2 import LegacyApplicationClient from oauthlib.oauth2 import TokenExpiredError, is_secure_transport import requests @@ -74,6 +75,10 @@ def __init__(self, client_id=None, client=None, auto_refresh_url=None, self.auto_refresh_kwargs = auto_refresh_kwargs or {} self.token_updater = token_updater + # Ensure that requests doesn't do any automatic auth. See #278. + # The default behavior can be re-enabled by setting auth to None. + self.auth = lambda r: r + # Allow customizations for non compliant providers through various # hooks to adjust requests and responses. self.compliance_hook = { @@ -111,7 +116,7 @@ def token(self): @token.setter def token(self, value): self._client.token = value - self._client._populate_attributes(value) + self._client.populate_token_attributes(value) @property def access_token(self): @@ -154,11 +159,14 @@ def authorization_url(self, url, state=None, **kwargs): def fetch_token(self, token_url, code=None, authorization_response=None, body='', auth=None, username=None, password=None, method='POST', - timeout=None, headers=None, verify=True, proxies=None, **kwargs): + timeout=None, headers=None, verify=True, proxies=None, + include_client_id=None, client_secret=None, **kwargs): """Generic method for fetching an access token from the token endpoint. If you are using the MobileApplicationClient you will want to use - token_from_fragment instead of fetch_token. + `token_from_fragment` instead of `fetch_token`. + + The current implementation enforces the RFC guidelines. :param token_url: Token endpoint URL, must use HTTPS. :param code: Authorization code (used by WebApplicationClients). @@ -167,15 +175,28 @@ def fetch_token(self, token_url, code=None, authorization_response=None, WebApplicationClients instead of code. :param body: Optional application/x-www-form-urlencoded body to add the include in the token request. Prefer kwargs over body. - :param auth: An auth tuple or method as accepted by requests. - :param username: Username used by LegacyApplicationClients. - :param password: Password used by LegacyApplicationClients. + :param auth: An auth tuple or method as accepted by `requests`. + :param username: Username required by LegacyApplicationClients to appear + in the request body. + :param password: Password required by LegacyApplicationClients to appear + in the request body. :param method: The HTTP method used to make the request. Defaults to POST, but may also be GET. Other methods should be added as needed. - :param headers: Dict to default request headers with. :param timeout: Timeout of the request in seconds. + :param headers: Dict to default request headers with. :param verify: Verify SSL certificate. + :param proxies: The `proxies` argument is passed onto `requests`. + :param include_client_id: Should the request body include the + `client_id` parameter. Default is `None`, + which will attempt to autodetect. This can be + forced to always include (True) or never + include (False). + :param client_secret: The `client_secret` paired to the `client_id`. + This is generally required unless provided in the + `auth` tuple. If the value is `None`, it will be + omitted from the request, however if the value is + an empty string, an empty string will be sent. :param kwargs: Extra parameters to include in the token request. :return: A token dict """ @@ -192,23 +213,65 @@ def fetch_token(self, token_url, code=None, authorization_response=None, raise ValueError('Please supply either code or ' 'authorization_response parameters.') + # Earlier versions of this library build an HTTPBasicAuth header out of + # `username` and `password`. The RFC states, however these attributes + # must be in the request body and not the header. + # If an upstream server is not spec compliant and requires them to + # appear as an Authorization header, supply an explicit `auth` header + # to this function. + # This check will allow for empty strings, but not `None`. + # + # Refernences + # 4.3.2 - Resource Owner Password Credentials Grant + # https://tools.ietf.org/html/rfc6749#section-4.3.2 + + if isinstance(self._client, LegacyApplicationClient): + if username is None: + raise ValueError('`LegacyApplicationClient` requires both the ' + '`username` and `password` parameters.') + if password is None: + raise ValueError('The required paramter `username` was supplied, ' + 'but `password` was not.') + + # merge username and password into kwargs for `prepare_request_body` + if username is not None: + kwargs['username'] = username + if password is not None: + kwargs['password'] = password + + # is an auth explicitly supplied? + if auth is not None: + # if we're dealing with the default of `include_client_id` (None): + # we will assume the `auth` argument is for an RFC compliant server + # and we should not send the `client_id` in the body. + # This approach allows us to still force the client_id by submitting + # `include_client_id=True` along with an `auth` object. + if include_client_id is None: + include_client_id = False + + # otherwise we may need to create an auth header + else: + # since we don't have an auth header, we MAY need to create one + # it is possible that we want to send the `client_id` in the body + # if so, `include_client_id` should be set to True + # otherwise, we will generate an auth header + if include_client_id is not True: + client_id = self.client_id + if client_id: + log.debug('Encoding `client_id` "%s" with `client_secret` ' + 'as Basic auth credentials.', client_id) + client_secret = client_secret if client_secret is not None else '' + auth = requests.auth.HTTPBasicAuth(client_id, client_secret) + + if include_client_id: + # this was pulled out of the params + # it needs to be passed into prepare_request_body + if client_secret is not None: + kwargs['client_secret'] = client_secret body = self._client.prepare_request_body(code=code, body=body, - redirect_uri=self.redirect_uri, username=username, - password=password, **kwargs) - - client_id = kwargs.get('client_id', '') - if auth is None: - if client_id: - log.debug('Encoding client_id "%s" with client_secret as Basic auth credentials.', client_id) - client_secret = kwargs.get('client_secret', '') - client_secret = client_secret if client_secret is not None else '' - auth = requests.auth.HTTPBasicAuth(client_id, client_secret) - elif username: - if password is None: - raise ValueError('Username was supplied, but not password.') - log.debug('Encoding username, password as Basic auth credentials.') - auth = requests.auth.HTTPBasicAuth(username, password) + redirect_uri=self.redirect_uri, + include_client_id=include_client_id, **kwargs) headers = headers or { 'Accept': 'application/json', @@ -265,9 +328,11 @@ def refresh_token(self, token_url, refresh_token=None, body='', auth=None, :param refresh_token: The refresh_token to use. :param body: Optional application/x-www-form-urlencoded body to add the include in the token request. Prefer kwargs over body. - :param auth: An auth tuple or method as accepted by requests. + :param auth: An auth tuple or method as accepted by `requests`. :param timeout: Timeout of the request in seconds. + :param headers: A dict of headers to be used by `requests`. :param verify: Verify SSL certificate. + :param proxies: The `proxies` argument will be passed to `requests`. :param kwargs: Extra parameters to include in the token request. :return: A token dict """ diff --git a/ext/six.py b/ext/six.py index 6bf4fd3810..89b2188fd6 100644 --- a/ext/six.py +++ b/ext/six.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2017 Benjamin Peterson +# Copyright (c) 2010-2018 Benjamin Peterson # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ import types __author__ = "Benjamin Peterson " -__version__ = "1.11.0" +__version__ = "1.12.0" # Useful for very coarse version differentiation. @@ -844,10 +844,71 @@ def wrapper(cls): orig_vars.pop(slots_var) orig_vars.pop('__dict__', None) orig_vars.pop('__weakref__', None) + if hasattr(cls, '__qualname__'): + orig_vars['__qualname__'] = cls.__qualname__ return metaclass(cls.__name__, cls.__bases__, orig_vars) return wrapper +def ensure_binary(s, encoding='utf-8', errors='strict'): + """Coerce **s** to six.binary_type. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> encoded to `bytes` + - `bytes` -> `bytes` + """ + if isinstance(s, text_type): + return s.encode(encoding, errors) + elif isinstance(s, binary_type): + return s + else: + raise TypeError("not expecting type '%s'" % type(s)) + + +def ensure_str(s, encoding='utf-8', errors='strict'): + """Coerce *s* to `str`. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + if not isinstance(s, (text_type, binary_type)): + raise TypeError("not expecting type '%s'" % type(s)) + if PY2 and isinstance(s, text_type): + s = s.encode(encoding, errors) + elif PY3 and isinstance(s, binary_type): + s = s.decode(encoding, errors) + return s + + +def ensure_text(s, encoding='utf-8', errors='strict'): + """Coerce *s* to six.text_type. + + For Python 2: + - `unicode` -> `unicode` + - `str` -> `unicode` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + if isinstance(s, binary_type): + return s.decode(encoding, errors) + elif isinstance(s, text_type): + return s + else: + raise TypeError("not expecting type '%s'" % type(s)) + + + def python_2_unicode_compatible(klass): """ A decorator that defines __unicode__ and __str__ methods under Python 2. diff --git a/ext/soupsieve/__init__.py b/ext/soupsieve/__init__.py new file mode 100644 index 0000000000..6464671472 --- /dev/null +++ b/ext/soupsieve/__init__.py @@ -0,0 +1,115 @@ +""" +Soup Sieve. + +A CSS selector filter for BeautifulSoup4. + +MIT License + +Copyright (c) 2018 Isaac Muse + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" +from __future__ import unicode_literals +from .__meta__ import __version__, __version_info__ # noqa: F401 +from . import css_parser as cp +from . import css_match as cm +from . import css_types as ct +from .util import DEBUG + +__all__ = ( + 'SoupSieve', 'compile', 'purge', 'DEBUG', + 'comments', 'icomments', 'closest', 'select', 'select_one', + 'iselect', 'match', 'filter' +) + +SoupSieve = cm.SoupSieve + + +def compile(pattern, namespaces=None, flags=0): # noqa: A001 + """Compile CSS pattern.""" + + if namespaces is None: + namespaces = ct.Namespaces() + if not isinstance(namespaces, ct.Namespaces): + namespaces = ct.Namespaces(**(namespaces)) + + if isinstance(pattern, SoupSieve): + if flags != pattern.flags: + raise ValueError("Cannot change flags of a pattern") + elif namespaces != pattern.namespaces: + raise ValueError("Cannot change namespaces of a pattern") + return pattern + + return cp._cached_css_compile(pattern, namespaces, flags) + + +def purge(): + """Purge cached patterns.""" + + cp._purge_cache() + + +def closest(select, tag, namespaces=None, flags=0): + """Match closest ancestor.""" + + return compile(select, namespaces, flags).closest(tag) + + +def match(select, tag, namespaces=None, flags=0): + """Match node.""" + + return compile(select, namespaces, flags).match(tag) + + +def filter(select, iterable, namespaces=None, flags=0): # noqa: A001 + """Filter list of nodes.""" + + return compile(select, namespaces, flags).filter(iterable) + + +def comments(tag, limit=0, flags=0): + """Get comments only.""" + + return list(icomments(tag, limit, flags)) + + +def icomments(tag, limit=0, flags=0): + """Iterate comments only.""" + + for comment in cm.get_comments(tag, limit): + yield comment + + +def select_one(select, tag, namespaces=None, flags=0): + """Select a single tag.""" + + return compile(select, namespaces, flags).select_one(tag) + + +def select(select, tag, namespaces=None, limit=0, flags=0): + """Select the specified tags.""" + + return compile(select, namespaces, flags).select(tag, limit) + + +def iselect(select, tag, namespaces=None, limit=0, flags=0): + """Iterate the specified tags.""" + + for el in compile(select, namespaces, flags).iselect(tag, limit): + yield el diff --git a/ext/soupsieve/__meta__.py b/ext/soupsieve/__meta__.py new file mode 100644 index 0000000000..10adb064a3 --- /dev/null +++ b/ext/soupsieve/__meta__.py @@ -0,0 +1,190 @@ +"""Meta related things.""" +from __future__ import unicode_literals +from collections import namedtuple +import re + +RE_VER = re.compile( + r'''(?x) + (?P\d+)(?:\.(?P\d+))?(?:\.(?P\d+))? + (?:(?Pa|b|rc)(?P
\d+))?
+    (?:\.post(?P\d+))?
+    (?:\.dev(?P\d+))?
+    '''
+)
+
+REL_MAP = {
+    ".dev": "",
+    ".dev-alpha": "a",
+    ".dev-beta": "b",
+    ".dev-candidate": "rc",
+    "alpha": "a",
+    "beta": "b",
+    "candidate": "rc",
+    "final": ""
+}
+
+DEV_STATUS = {
+    ".dev": "2 - Pre-Alpha",
+    ".dev-alpha": "2 - Pre-Alpha",
+    ".dev-beta": "2 - Pre-Alpha",
+    ".dev-candidate": "2 - Pre-Alpha",
+    "alpha": "3 - Alpha",
+    "beta": "4 - Beta",
+    "candidate": "4 - Beta",
+    "final": "5 - Production/Stable"
+}
+
+PRE_REL_MAP = {"a": 'alpha', "b": 'beta', "rc": 'candidate'}
+
+
+class Version(namedtuple("Version", ["major", "minor", "micro", "release", "pre", "post", "dev"])):
+    """
+    Get the version (PEP 440).
+
+    A biased approach to the PEP 440 semantic version.
+
+    Provides a tuple structure which is sorted for comparisons `v1 > v2` etc.
+      (major, minor, micro, release type, pre-release build, post-release build, development release build)
+    Release types are named in is such a way they are comparable with ease.
+    Accessors to check if a development, pre-release, or post-release build. Also provides accessor to get
+    development status for setup files.
+
+    How it works (currently):
+
+    - You must specify a release type as either `final`, `alpha`, `beta`, or `candidate`.
+    - To define a development release, you can use either `.dev`, `.dev-alpha`, `.dev-beta`, or `.dev-candidate`.
+      The dot is used to ensure all development specifiers are sorted before `alpha`.
+      You can specify a `dev` number for development builds, but do not have to as implicit development releases
+      are allowed.
+    - You must specify a `pre` value greater than zero if using a prerelease as this project (not PEP 440) does not
+      allow implicit prereleases.
+    - You can optionally set `post` to a value greater than zero to make the build a post release. While post releases
+      are technically allowed in prereleases, it is strongly discouraged, so we are rejecting them. It should be
+      noted that we do not allow `post0` even though PEP 440 does not restrict this. This project specifically
+      does not allow implicit post releases.
+    - It should be noted that we do not support epochs `1!` or local versions `+some-custom.version-1`.
+
+    Acceptable version releases:
+
+    ```
+    Version(1, 0, 0, "final")                    1.0
+    Version(1, 2, 0, "final")                    1.2
+    Version(1, 2, 3, "final")                    1.2.3
+    Version(1, 2, 0, ".dev-alpha", pre=4)        1.2a4
+    Version(1, 2, 0, ".dev-beta", pre=4)         1.2b4
+    Version(1, 2, 0, ".dev-candidate", pre=4)    1.2rc4
+    Version(1, 2, 0, "final", post=1)            1.2.post1
+    Version(1, 2, 3, ".dev")                     1.2.3.dev0
+    Version(1, 2, 3, ".dev", dev=1)              1.2.3.dev1
+    ```
+
+    """
+
+    def __new__(cls, major, minor, micro, release="final", pre=0, post=0, dev=0):
+        """Validate version info."""
+
+        # Ensure all parts are positive integers.
+        for value in (major, minor, micro, pre, post):
+            if not (isinstance(value, int) and value >= 0):
+                raise ValueError("All version parts except 'release' should be integers.")
+
+        if release not in REL_MAP:
+            raise ValueError("'{}' is not a valid release type.".format(release))
+
+        # Ensure valid pre-release (we do not allow implicit pre-releases).
+        if ".dev-candidate" < release < "final":
+            if pre == 0:
+                raise ValueError("Implicit pre-releases not allowed.")
+            elif dev:
+                raise ValueError("Version is not a development release.")
+            elif post:
+                raise ValueError("Post-releases are not allowed with pre-releases.")
+
+        # Ensure valid development or development/pre release
+        elif release < "alpha":
+            if release > ".dev" and pre == 0:
+                raise ValueError("Implicit pre-release not allowed.")
+            elif post:
+                raise ValueError("Post-releases are not allowed with pre-releases.")
+
+        # Ensure a valid normal release
+        else:
+            if pre:
+                raise ValueError("Version is not a pre-release.")
+            elif dev:
+                raise ValueError("Version is not a development release.")
+
+        return super(Version, cls).__new__(cls, major, minor, micro, release, pre, post, dev)
+
+    def _is_pre(self):
+        """Is prerelease."""
+
+        return self.pre > 0
+
+    def _is_dev(self):
+        """Is development."""
+
+        return bool(self.release < "alpha")
+
+    def _is_post(self):
+        """Is post."""
+
+        return self.post > 0
+
+    def _get_dev_status(self):  # pragma: no cover
+        """Get development status string."""
+
+        return DEV_STATUS[self.release]
+
+    def _get_canonical(self):
+        """Get the canonical output string."""
+
+        # Assemble major, minor, micro version and append `pre`, `post`, or `dev` if needed..
+        if self.micro == 0:
+            ver = "{}.{}".format(self.major, self.minor)
+        else:
+            ver = "{}.{}.{}".format(self.major, self.minor, self.micro)
+        if self._is_pre():
+            ver += '{}{}'.format(REL_MAP[self.release], self.pre)
+        if self._is_post():
+            ver += ".post{}".format(self.post)
+        if self._is_dev():
+            ver += ".dev{}".format(self.dev)
+
+        return ver
+
+
+def parse_version(ver, pre=False):
+    """Parse version into a comparable Version tuple."""
+
+    m = RE_VER.match(ver)
+
+    # Handle major, minor, micro
+    major = int(m.group('major'))
+    minor = int(m.group('minor')) if m.group('minor') else 0
+    micro = int(m.group('micro')) if m.group('micro') else 0
+
+    # Handle pre releases
+    if m.group('type'):
+        release = PRE_REL_MAP[m.group('type')]
+        pre = int(m.group('pre'))
+    else:
+        release = "final"
+        pre = 0
+
+    # Handle development releases
+    dev = m.group('dev') if m.group('dev') else 0
+    if m.group('dev'):
+        dev = int(m.group('dev'))
+        release = '.dev-' + release if pre else '.dev'
+    else:
+        dev = 0
+
+    # Handle post
+    post = int(m.group('post')) if m.group('post') else 0
+
+    return Version(major, minor, micro, release, pre, post, dev)
+
+
+__version_info__ = Version(1, 7, 0, "final")
+__version__ = __version_info__._get_canonical()
diff --git a/ext/soupsieve/css_match.py b/ext/soupsieve/css_match.py
new file mode 100644
index 0000000000..dae2b4032e
--- /dev/null
+++ b/ext/soupsieve/css_match.py
@@ -0,0 +1,1147 @@
+"""CSS matcher."""
+from __future__ import unicode_literals
+from datetime import datetime
+from . import util
+import re
+from .import css_types as ct
+import unicodedata
+
+# Empty tag pattern (whitespace okay)
+RE_NOT_EMPTY = re.compile('[^ \t\r\n\f]')
+
+RE_NOT_WS = re.compile('[^ \t\r\n\f]+')
+
+# Relationships
+REL_PARENT = ' '
+REL_CLOSE_PARENT = '>'
+REL_SIBLING = '~'
+REL_CLOSE_SIBLING = '+'
+
+# Relationships for :has() (forward looking)
+REL_HAS_PARENT = ': '
+REL_HAS_CLOSE_PARENT = ':>'
+REL_HAS_SIBLING = ':~'
+REL_HAS_CLOSE_SIBLING = ':+'
+
+NS_XHTML = 'http://www.w3.org/1999/xhtml'
+
+DIR_FLAGS = ct.SEL_DIR_LTR | ct.SEL_DIR_RTL
+RANGES = ct.SEL_IN_RANGE | ct.SEL_OUT_OF_RANGE
+
+DIR_MAP = {
+    'ltr': ct.SEL_DIR_LTR,
+    'rtl': ct.SEL_DIR_RTL,
+    'auto': 0
+}
+
+RE_NUM = re.compile(r"^(?P-?(?:[0-9]{1,}(\.[0-9]+)?|\.[0-9]+))$")
+RE_TIME = re.compile(r'^(?P[0-9]{2}):(?P[0-9]{2})$')
+RE_MONTH = re.compile(r'^(?P[0-9]{4,})-(?P[0-9]{2})$')
+RE_WEEK = re.compile(r'^(?P[0-9]{4,})-W(?P[0-9]{2})$')
+RE_DATE = re.compile(r'^(?P[0-9]{4,})-(?P[0-9]{2})-(?P[0-9]{2})$')
+RE_DATETIME = re.compile(
+    r'^(?P[0-9]{4,})-(?P[0-9]{2})-(?P[0-9]{2})T(?P[0-9]{2}):(?P[0-9]{2})$'
+)
+
+MONTHS_30 = (4, 6, 9, 11)  # April, June, September, and November
+FEB = 2
+SHORT_MONTH = 30
+LONG_MONTH = 31
+FEB_MONTH = 28
+FEB_LEAP_MONTH = 29
+DAYS_IN_WEEK = 7
+
+
+def assert_valid_input(tag):
+    """Check if valid input tag."""
+
+    # Fail on unexpected types.
+    if not util.is_tag(tag):
+        raise TypeError("Expected a BeautifulSoup 'Tag', but instead recieved type {}".format(type(tag)))
+
+
+def get_comments(el, limit=0):
+    """Get comments."""
+
+    assert_valid_input(el)
+
+    if limit < 1:
+        limit = None
+
+    for child in el.descendants:
+        if util.is_comment(child):
+            yield child
+            if limit is not None:
+                limit -= 1
+                if limit < 1:
+                    break
+
+
+class FakeNthParent(object):
+    """
+    Fake parent for `nth` selector.
+
+    When we have a fragment with no `BeautifulSoup` document object,
+    we can't evaluate `nth` selectors properly.  Create a temporary
+    fake parent so we can traverse the root element as a child.
+    """
+
+    def __init__(self, element):
+        """Initialize."""
+
+        self.contents = [element]
+
+
+class CSSMatch(object):
+    """Perform CSS matching."""
+
+    def __init__(self, selectors, scope, namespaces, flags):
+        """Initialize."""
+
+        assert_valid_input(scope)
+        self.tag = scope
+        self.cached_meta_lang = None
+        self.cached_default_forms = []
+        self.cached_indeterminate_forms = []
+        self.selectors = selectors
+        self.namespaces = namespaces
+        self.flags = flags
+        doc = scope
+        while doc.parent:
+            doc = doc.parent
+        root = None
+        if not util.is_doc(doc):
+            root = doc
+        else:
+            for child in doc.children:
+                if util.is_tag(child):
+                    root = child
+                    break
+        self.root = root
+        self.scope = scope if scope is not doc else root
+        self.html_namespace = self.is_html_ns(root)
+        self.is_xml = doc._is_xml and not self.html_namespace
+
+    def is_html_ns(self, el):
+        """Check if in HTML namespace."""
+
+        ns = getattr(el, 'namespace') if el else None
+        return ns and ns == NS_XHTML
+
+    def get_namespace(self, el):
+        """Get the namespace for the element."""
+
+        namespace = ''
+        ns = el.namespace
+        if ns:
+            namespace = ns
+        return namespace
+
+    def supports_namespaces(self):
+        """Check if namespaces are supported in the HTML type."""
+
+        return self.is_xml or self.html_namespace
+
+    def get_bidi(self, el):
+        """Get directionality from element text."""
+
+        for node in el.children:
+
+            # Analyze child text nodes
+            if util.is_tag(node):
+
+                # Avoid analyzing certain elements specified in the specification.
+                direction = DIR_MAP.get(util.lower(node.attrs.get('dir', '')), None)
+                if (
+                    util.lower(node.name) in ('bdi', 'script', 'style', 'textarea') or
+                    direction is not None
+                ):
+                    continue  # pragma: no cover
+
+                # Check directionality of this node's text
+                value = self.get_bidi(node)
+                if value is not None:
+                    return value
+
+                # Direction could not be determined
+                continue  # pragma: no cover
+
+            # Skip `doctype` comments, etc.
+            if util.is_special_string(node):
+                continue
+
+            # Analyze text nodes for directionality.
+            for c in node:
+                bidi = unicodedata.bidirectional(c)
+                if bidi in ('AL', 'R', 'L'):
+                    return ct.SEL_DIR_LTR if bidi == 'L' else ct.SEL_DIR_RTL
+        return None
+
+    def get_attribute(self, el, attr, prefix):
+        """Get attribute from element if it exists."""
+
+        value = None
+        if self.supports_namespaces():
+            value = None
+            # If we have not defined namespaces, we can't very well find them, so don't bother trying.
+            if prefix:
+                ns = self.namespaces.get(prefix)
+                if ns is None and prefix != '*':
+                    return None
+            else:
+                ns = None
+
+            for k, v in el.attrs.items():
+
+                # Get attribute parts
+                namespace = getattr(k, 'namespace', None)
+                name = getattr(k, 'name', None)
+
+                # Can't match a prefix attribute as we haven't specified one to match
+                # Try to match it normally as a whole `p:a` as selector may be trying `p\:a`.
+                if ns is None:
+                    if (self.is_xml and attr == k) or (not self.is_xml and util.lower(attr) == util.lower(k)):
+                        value = v
+                        break
+                    # Coverage is not finding this even though it is executed.
+                    # Adding a print statement before this (and erasing coverage) causes coverage to find the line.
+                    # Ignore the false positive message.
+                    continue  # pragma: no cover
+
+                # We can't match our desired prefix attribute as the attribute doesn't have a prefix
+                if namespace is None or ns != namespace and prefix != '*':
+                    continue
+
+                if self.is_xml:
+                    # The attribute doesn't match.
+                    if attr != name:
+                        continue
+                else:
+                    # The attribute doesn't match.
+                    if util.lower(attr) != util.lower(name):
+                        continue
+                value = v
+                break
+        else:
+            for k, v in el.attrs.items():
+                if util.lower(attr) != util.lower(k):
+                    continue
+                value = v
+                break
+        return value
+
+    def get_classes(self, el):
+        """Get classes."""
+
+        classes = el.attrs.get('class', [])
+        if isinstance(classes, util.ustr):
+            classes = RE_NOT_WS.findall(classes)
+        return classes
+
+    def get_attribute_by_name(self, el, name, default=None):
+        """Get attribute by name."""
+
+        value = default
+        for k, v in el.attrs.items():
+            if (k if self.is_xml else util.lower(k)) == name:
+                value = v
+                break
+        return value
+
+    def validate_day(self, year, month, day):
+        """Validate day."""
+
+        max_days = LONG_MONTH
+        if month == FEB:
+            max_days = FEB_LEAP_MONTH if ((year % 4 == 0) and (year % 100 != 0)) or (year % 400 == 0) else FEB_MONTH
+        elif month in MONTHS_30:
+            max_days = SHORT_MONTH
+        return 1 <= day <= max_days
+
+    def validate_week(self, year, week):
+        """Validate week."""
+
+        max_week = datetime.strptime("{}-{}-{}".format(12, 31, year), "%m-%d-%Y").isocalendar()[1]
+        if max_week == 1:
+            max_week = 53
+        return 1 <= week <= max_week
+
+    def validate_month(self, month):
+        """Validate month."""
+
+        return 1 <= month <= 12
+
+    def validate_year(self, year):
+        """Validate year."""
+
+        return 1 <= year
+
+    def validate_hour(self, hour):
+        """Validate hour."""
+
+        return 0 <= hour <= 23
+
+    def validate_minutes(self, minutes):
+        """Validate minutes."""
+
+        return 0 <= minutes <= 59
+
+    def parse_input_value(self, itype, value):
+        """Parse the input value."""
+
+        parsed = None
+        if itype == "date":
+            m = RE_DATE.match(value)
+            if m:
+                year = int(m.group('year'), 10)
+                month = int(m.group('month'), 10)
+                day = int(m.group('day'), 10)
+                if self.validate_year(year) and self.validate_month(month) and self.validate_day(year, month, day):
+                    parsed = (year, month, day)
+        elif itype == "month":
+            m = RE_MONTH.match(value)
+            if m:
+                year = int(m.group('year'), 10)
+                month = int(m.group('month'), 10)
+                if self.validate_year(year) and self.validate_month(month):
+                    parsed = (year, month)
+        elif itype == "week":
+            m = RE_WEEK.match(value)
+            if m:
+                year = int(m.group('year'), 10)
+                week = int(m.group('week'), 10)
+                if self.validate_year(year) and self.validate_week(year, week):
+                    parsed = (year, week)
+        elif itype == "time":
+            m = RE_TIME.match(value)
+            if m:
+                hour = int(m.group('hour'), 10)
+                minutes = int(m.group('minutes'), 10)
+                if self.validate_hour(hour) and self.validate_minutes(minutes):
+                    parsed = (hour, minutes)
+        elif itype == "datetime-local":
+            m = RE_DATETIME.match(value)
+            if m:
+                year = int(m.group('year'), 10)
+                month = int(m.group('month'), 10)
+                day = int(m.group('day'), 10)
+                hour = int(m.group('hour'), 10)
+                minutes = int(m.group('minutes'), 10)
+                if (
+                    self.validate_year(year) and self.validate_month(month) and self.validate_day(year, month, day) and
+                    self.validate_hour(hour) and self.validate_minutes(minutes)
+                ):
+                    parsed = (year, month, day, hour, minutes)
+        elif itype in ("number", "range"):
+            m = RE_NUM.match(value)
+            if m:
+                parsed = float(m.group('value'))
+        return parsed
+
+    def match_namespace(self, el, tag):
+        """Match the namespace of the element."""
+
+        match = True
+        namespace = self.get_namespace(el)
+        default_namespace = self.namespaces.get('')
+        tag_ns = '' if tag.prefix is None else self.namespaces.get(tag.prefix, None)
+        # We must match the default namespace if one is not provided
+        if tag.prefix is None and (default_namespace is not None and namespace != default_namespace):
+            match = False
+        # If we specified `|tag`, we must not have a namespace.
+        elif (tag.prefix is not None and tag.prefix == '' and namespace):
+            match = False
+        # Verify prefix matches
+        elif (
+            tag.prefix and
+            tag.prefix != '*' and (tag_ns is None or namespace != tag_ns)
+        ):
+            match = False
+        return match
+
+    def match_attributes(self, el, attributes):
+        """Match attributes."""
+
+        match = True
+        if attributes:
+            for a in attributes:
+                value = self.get_attribute(el, a.attribute, a.prefix)
+                pattern = a.xml_type_pattern if not self.html_namespace and a.xml_type_pattern else a.pattern
+                if isinstance(value, list):
+                    value = ' '.join(value)
+                if value is None:
+                    match = False
+                    break
+                elif pattern is None:
+                    continue
+                elif pattern.match(value) is None:
+                    match = False
+                    break
+        return match
+
+    def match_tagname(self, el, tag):
+        """Match tag name."""
+
+        return not (
+            tag.name and
+            tag.name not in ((util.lower(el.name) if not self.is_xml else el.name), '*')
+        )
+
+    def match_tag(self, el, tag):
+        """Match the tag."""
+
+        has_ns = self.supports_namespaces()
+        match = True
+        if tag is not None:
+            # Verify namespace
+            if has_ns and not self.match_namespace(el, tag):
+                match = False
+            if not self.match_tagname(el, tag):
+                match = False
+        return match
+
+    def match_past_relations(self, el, relation):
+        """Match past relationship."""
+
+        found = False
+        if relation[0].rel_type == REL_PARENT:
+            parent = el.parent
+            while not found and parent:
+                found = self.match_selectors(parent, relation)
+                parent = parent.parent
+        elif relation[0].rel_type == REL_CLOSE_PARENT:
+            parent = el.parent
+            if parent:
+                found = self.match_selectors(parent, relation)
+        elif relation[0].rel_type == REL_SIBLING:
+            sibling = el.previous_sibling
+            while not found and sibling:
+                if not util.is_tag(sibling):
+                    sibling = sibling.previous_sibling
+                    continue
+                found = self.match_selectors(sibling, relation)
+                sibling = sibling.previous_sibling
+        elif relation[0].rel_type == REL_CLOSE_SIBLING:
+            sibling = el.previous_sibling
+            while sibling and not util.is_tag(sibling):
+                sibling = sibling.previous_sibling
+            if sibling and util.is_tag(sibling):
+                found = self.match_selectors(sibling, relation)
+        return found
+
+    def match_future_child(self, parent, relation, recursive=False):
+        """Match future child."""
+
+        match = False
+        for child in (parent.descendants if recursive else parent.children):
+            if not util.is_tag(child):
+                continue
+            match = self.match_selectors(child, relation)
+            if match:
+                break
+        return match
+
+    def match_future_relations(self, el, relation):
+        """Match future relationship."""
+
+        found = False
+        if relation[0].rel_type == REL_HAS_PARENT:
+            found = self.match_future_child(el, relation, True)
+        elif relation[0].rel_type == REL_HAS_CLOSE_PARENT:
+            found = self.match_future_child(el, relation)
+        elif relation[0].rel_type == REL_HAS_SIBLING:
+            sibling = el.next_sibling
+            while not found and sibling:
+                if not util.is_tag(sibling):
+                    sibling = sibling.next_sibling
+                    continue
+                found = self.match_selectors(sibling, relation)
+                sibling = sibling.next_sibling
+        elif relation[0].rel_type == REL_HAS_CLOSE_SIBLING:
+            sibling = el.next_sibling
+            while sibling and not util.is_tag(sibling):
+                sibling = sibling.next_sibling
+            if sibling and util.is_tag(sibling):
+                found = self.match_selectors(sibling, relation)
+        return found
+
+    def match_relations(self, el, relation):
+        """Match relationship to other elements."""
+
+        found = False
+
+        if relation[0].rel_type.startswith(':'):
+            found = self.match_future_relations(el, relation)
+        else:
+            found = self.match_past_relations(el, relation)
+
+        return found
+
+    def match_id(self, el, ids):
+        """Match element's ID."""
+
+        found = True
+        for i in ids:
+            if i != el.attrs.get('id', ''):
+                found = False
+                break
+        return found
+
+    def match_classes(self, el, classes):
+        """Match element's classes."""
+
+        current_classes = self.get_classes(el)
+        found = True
+        for c in classes:
+            if c not in current_classes:
+                found = False
+                break
+        return found
+
+    def match_root(self, el):
+        """Match element as root."""
+
+        return self.root and self.root is el
+
+    def match_scope(self, el):
+        """Match element as scope."""
+
+        return self.scope is el
+
+    def match_nth_tag_type(self, el, child):
+        """Match tag type for `nth` matches."""
+
+        return(
+            (child.name == (util.lower(el.name) if not self.is_xml else el.name)) and
+            (not self.supports_namespaces() or self.get_namespace(child) == self.get_namespace(el))
+        )
+
+    def match_nth(self, el, nth):
+        """Match `nth` elements."""
+
+        matched = True
+
+        for n in nth:
+            matched = False
+            if n.selectors and not self.match_selectors(el, n.selectors):
+                break
+            parent = el.parent
+            if parent is None:
+                parent = FakeNthParent(el)
+            last = n.last
+            last_index = len(parent.contents) - 1
+            relative_index = 0
+            a = n.a
+            b = n.b
+            var = n.n
+            count = 0
+            count_incr = 1
+            factor = -1 if last else 1
+            index = len(parent.contents) - 1 if last else 0
+            idx = last_idx = a * count + b if var else a
+
+            # We can only adjust bounds within a variable index
+            if var:
+                # Abort if our nth index is out of bounds and only getting further out of bounds as we increment.
+                # Otherwise, increment to try to get in bounds.
+                adjust = None
+                while idx < 1 or idx > last_index:
+                    if idx < 0:
+                        diff_low = 0 - idx
+                        if adjust is not None and adjust == 1:
+                            break
+                        adjust = -1
+                        count += count_incr
+                        idx = last_idx = a * count + b if var else a
+                        diff = 0 - idx
+                        if diff >= diff_low:
+                            break
+                    else:
+                        diff_high = idx - last_index
+                        if adjust is not None and adjust == -1:
+                            break
+                        adjust = 1
+                        count += count_incr
+                        idx = last_idx = a * count + b if var else a
+                        diff = idx - last_index
+                        if diff >= diff_high:
+                            break
+                        diff_high = diff
+
+                # If a < 0, our count is working backwards, so floor the index by increasing the count.
+                # Find the count that yields the lowest, in bound value and use that.
+                # Lastly reverse count increment so that we'll increase our index.
+                lowest = count
+                if a < 0:
+                    while idx >= 1:
+                        lowest = count
+                        count += count_incr
+                        idx = last_idx = a * count + b if var else a
+                    count_incr = -1
+                count = lowest
+                idx = last_idx = a * count + b if var else a
+
+            # Evaluate elements while our calculated nth index is still in range
+            while 1 <= idx <= last_index + 1:
+                child = None
+                # Evaluate while our child index is still in range.
+                while 0 <= index <= last_index:
+                    child = parent.contents[index]
+                    index += factor
+                    if not util.is_tag(child):
+                        continue
+                    # Handle `of S` in `nth-child`
+                    if n.selectors and not self.match_selectors(child, n.selectors):
+                        continue
+                    # Handle `of-type`
+                    if n.of_type and not self.match_nth_tag_type(el, child):
+                        continue
+                    relative_index += 1
+                    if relative_index == idx:
+                        if child is el:
+                            matched = True
+                        else:
+                            break
+                    if child is el:
+                        break
+                if child is el:
+                    break
+                last_idx = idx
+                count += count_incr
+                if count < 0:
+                    # Count is counting down and has now ventured into invalid territory.
+                    break
+                idx = a * count + b if var else a
+                if last_idx == idx:
+                    break
+            if not matched:
+                break
+        return matched
+
+    def match_empty(self, el):
+        """Check if element is empty (if requested)."""
+
+        is_empty = True
+        for child in el.children:
+            if util.is_tag(child):
+                is_empty = False
+                break
+            elif (
+                (util.is_navigable_string(child) and not util.is_special_string(child)) and
+                RE_NOT_EMPTY.search(child)
+            ):
+                is_empty = False
+                break
+        return is_empty
+
+    def match_subselectors(self, el, selectors):
+        """Match selectors."""
+
+        match = True
+        for sel in selectors:
+            if not self.match_selectors(el, sel):
+                match = False
+        return match
+
+    def match_contains(self, el, contains):
+        """Match element if it contains text."""
+
+        types = (util.get_navigable_string_type(el),)
+        match = True
+        for c in contains:
+            if c not in el.get_text(types=types):
+                match = False
+                break
+        return match
+
+    def match_default(self, el):
+        """Match default."""
+
+        match = False
+
+        # Find this input's form
+        form = None
+        parent = el.parent
+        while parent and form is None:
+            if util.lower(parent.name) == 'form':
+                form = parent
+            else:
+                parent = parent.parent
+
+        # Look in form cache to see if we've already located its default button
+        found_form = False
+        for f, t in self.cached_default_forms:
+            if f is form:
+                found_form = True
+                if t is el:
+                    match = True
+                break
+
+        # We didn't have the form cached, so look for its default button
+        if not found_form:
+            child_found = False
+            for child in form.descendants:
+                if not util.is_tag(child):
+                    continue
+                name = util.lower(child.name)
+                # Can't do nested forms (haven't figured out why we never hit this)
+                if name == 'form':  # pragma: no cover
+                    break
+                if name in ('input', 'button'):
+                    for k, v in child.attrs.items():
+                        if util.lower(k) == 'type' and util.lower(v) == 'submit':
+                            child_found = True
+                            self.cached_default_forms.append([form, child])
+                            if el is child:
+                                match = True
+                            break
+                if child_found:
+                    break
+        return match
+
+    def match_indeterminate(self, el):
+        """Match default."""
+
+        match = False
+        name = el.attrs.get('name')
+
+        def get_parent_form(el):
+            """Find this input's form."""
+            form = None
+            parent = el.parent
+            while form is None:
+                if util.lower(parent.name) == 'form':
+                    form = parent
+                    break
+                elif parent.parent:
+                    parent = parent.parent
+                else:
+                    form = parent
+                    break
+            return form
+
+        form = get_parent_form(el)
+
+        # Look in form cache to see if we've already evaluated that its fellow radio buttons are indeterminate
+        found_form = False
+        for f, n, i in self.cached_indeterminate_forms:
+            if f is form and n == name:
+                found_form = True
+                if i is True:
+                    match = True
+                break
+
+        # We didn't have the form cached, so validate that the radio button is indeterminate
+        if not found_form:
+            checked = False
+            for child in form.descendants:
+                if not util.is_tag(child) or child is el:
+                    continue
+                tag_name = util.lower(child.name)
+                if tag_name == 'input':
+                    is_radio = False
+                    check = False
+                    has_name = False
+                    for k, v in child.attrs.items():
+                        if util.lower(k) == 'type' and util.lower(v) == 'radio':
+                            is_radio = True
+                        elif util.lower(k) == 'name' and v == name:
+                            has_name = True
+                        elif util.lower(k) == 'checked':
+                            check = True
+                        if is_radio and check and has_name and get_parent_form(child) is form:
+                            checked = True
+                            break
+                if checked:
+                    break
+            if not checked:
+                match = True
+            self.cached_indeterminate_forms.append([form, name, match])
+
+        return match
+
+    def match_lang(self, el, langs):
+        """Match languages."""
+
+        match = False
+        has_ns = self.supports_namespaces()
+
+        # Walk parents looking for `lang` (HTML) or `xml:lang` XML property.
+        parent = el
+        found_lang = None
+        while parent and parent.parent and not found_lang:
+            ns = self.is_html_ns(parent)
+            for k, v in parent.attrs.items():
+                if (
+                    (self.is_xml and k == 'xml:lang') or
+                    (
+                        not self.is_xml and (
+                            ((not has_ns or ns) and util.lower(k) == 'lang') or
+                            (has_ns and not ns and util.lower(k) == 'xml:lang')
+                        )
+                    )
+                ):
+                    found_lang = v
+                    break
+            parent = parent.parent
+
+        # Use cached meta language.
+        if not found_lang and self.cached_meta_lang is not None:
+            found_lang = self.cached_meta_lang
+
+        # If we couldn't find a language, and the document is HTML, look to meta to determine language.
+        if found_lang is None and not self.is_xml:
+            # Find head
+            found = False
+            for tag in ('html', 'head'):
+                found = False
+                for child in parent.children:
+                    if util.is_tag(child) and util.lower(child.name) == tag:
+                        found = True
+                        parent = child
+                        break
+                if not found:  # pragma: no cover
+                    break
+
+            # Search meta tags
+            if found:
+                for child in parent:
+                    if util.is_tag(child) and util.lower(child.name) == 'meta':
+                        c_lang = False
+                        content = None
+                        for k, v in child.attrs.items():
+                            if util.lower(k) == 'http-equiv' and util.lower(v) == 'content-language':
+                                c_lang = True
+                            if util.lower(k) == 'content':
+                                content = v
+                            if c_lang and content:
+                                found_lang = content
+                                self.cached_meta_lang = found_lang
+                                break
+                    if found_lang:
+                        break
+                if not found_lang:
+                    self.cached_meta_lang = False
+
+        # If we determined a language, compare.
+        if found_lang:
+            for patterns in langs:
+                match = False
+                for pattern in patterns:
+                    if pattern.match(found_lang):
+                        match = True
+                if not match:
+                    break
+
+        return match
+
+    def match_dir(self, el, directionality):
+        """Check directionality."""
+
+        # If we have to match both left and right, we can't match either.
+        if directionality & ct.SEL_DIR_LTR and directionality & ct.SEL_DIR_RTL:
+            return False
+
+        # Element has defined direction of left to right or right to left
+        direction = DIR_MAP.get(util.lower(el.attrs.get('dir', '')), None)
+        if direction not in (None, 0):
+            return direction == directionality
+
+        # Element is the document element (the root) and no direction assigned, assume left to right.
+        is_root = self.match_root(el)
+        if is_root and direction is None:
+            return ct.SEL_DIR_LTR == directionality
+
+        # If `input[type=telephone]` and no direction is assigned, assume left to right.
+        is_input = util.lower(el.name) == 'input'
+        is_textarea = util.lower(el.name) == 'textarea'
+        is_bdi = util.lower(el.name) == 'bdi'
+        itype = util.lower(self.get_attribute_by_name(el, 'type', '')) if is_input else ''
+        if is_input and itype == 'tel' and direction is None:
+            return ct.SEL_DIR_LTR == directionality
+
+        # Auto handling for text inputs
+        if ((is_input and itype in ('text', 'search', 'tel', 'url', 'email')) or is_textarea) and direction == 0:
+            if is_textarea:
+                value = []
+                for node in el.contents:
+                    if util.is_navigable_string(node) and not util.is_special_string(node):
+                        value.append(node)
+                value = ''.join(value)
+            else:
+                value = self.get_attribute_by_name(el, 'value', '')
+            if value:
+                for c in value:
+                    bidi = unicodedata.bidirectional(c)
+                    if bidi in ('AL', 'R', 'L'):
+                        direction = ct.SEL_DIR_LTR if bidi == 'L' else ct.SEL_DIR_RTL
+                        return direction == directionality
+                # Assume left to right
+                return ct.SEL_DIR_LTR == directionality
+            elif is_root:
+                return ct.SEL_DIR_LTR == directionality
+            return self.match_dir(el.parent, directionality)
+
+        # Auto handling for `bdi` and other non text inputs.
+        if (is_bdi and direction is None) or direction == 0:
+            direction = self.get_bidi(el)
+            if direction is not None:
+                return direction == directionality
+            elif is_root:
+                return ct.SEL_DIR_LTR == directionality
+            return self.match_dir(el.parent, directionality)
+
+        # Match parents direction
+        return self.match_dir(el.parent, directionality)
+
+    def match_range(self, el, condition):
+        """
+        Match range.
+
+        Behavior is modeled after what we see in browsers. Browsers seem to evaluate
+        if the value is out of range, and if not, it is in range. So a missing value
+        will not evaluate out of range; therefore, value is in range. Personally, I
+        feel like this should evaluate as neither in or out of range.
+        """
+
+        out_of_range = False
+
+        itype = self.get_attribute_by_name(el, 'type').lower()
+        mn = self.get_attribute_by_name(el, 'min', None)
+        if mn is not None:
+            mn = self.parse_input_value(itype, mn)
+        mx = self.get_attribute_by_name(el, 'max', None)
+        if mx is not None:
+            mx = self.parse_input_value(itype, mx)
+
+        # There is no valid min or max, so we cannot evaluate a range
+        if mn is None and mx is None:
+            return False
+
+        value = self.get_attribute_by_name(el, 'value', None)
+        if value is not None:
+            value = self.parse_input_value(itype, value)
+        if value is not None:
+            if itype in ("date", "datetime-local", "month", "week", "number", "range"):
+                if mn is not None and value < mn:
+                    out_of_range = True
+                if not out_of_range and mx is not None and value > mx:
+                    out_of_range = True
+            elif itype == "time":
+                if mn is not None and mx is not None and mn > mx:
+                    # Time is periodic, so this is a reversed/discontinuous range
+                    if value < mn and value > mx:
+                        out_of_range = True
+                else:
+                    if mn is not None and value < mn:
+                        out_of_range = True
+                    if not out_of_range and mx is not None and value > mx:
+                        out_of_range = True
+
+        return not out_of_range if condition & ct.SEL_IN_RANGE else out_of_range
+
+    def match_defined(self, el):
+        """
+        Match defined.
+
+        `:defined` is related to custom elements in a browser.
+
+        - If the document is XML (not XHTML), all tags will match.
+        - Tags that are not custom (don't have a hyphen) are marked defined.
+        - If the tag has a prefix (without or without a namespace), it will not match.
+
+        This is of course requires the parser to provide us with the proper prefix and namespace info,
+        if it doesn't, there is nothing we can do.
+        """
+
+        return (
+            self.is_xml or
+            el.name.find('-') == -1 or
+            el.name.find(':') != -1 or
+            el.prefix is not None
+        )
+
+    def match_selectors(self, el, selectors):
+        """Check if element matches one of the selectors."""
+
+        match = False
+        is_not = selectors.is_not
+        is_html = selectors.is_html
+        if not (is_html and self.is_xml):
+            for selector in selectors:
+                match = is_not
+                # We have a un-matchable situation (like `:focus` as you can focus an element in this environment)
+                if isinstance(selector, ct.NullSelector):
+                    continue
+                # Verify tag matches
+                if not self.match_tag(el, selector.tag):
+                    continue
+                # Verify tag is defined
+                if selector.flags & ct.SEL_DEFINED and not self.match_defined(el):
+                    continue
+                # Verify element is root
+                if selector.flags & ct.SEL_ROOT and not self.match_root(el):
+                    continue
+                # Verify element is scope
+                if selector.flags & ct.SEL_SCOPE and not self.match_scope(el):
+                    continue
+                # Verify `nth` matches
+                if not self.match_nth(el, selector.nth):
+                    continue
+                if selector.flags & ct.SEL_EMPTY and not self.match_empty(el):
+                    continue
+                # Verify id matches
+                if selector.ids and not self.match_id(el, selector.ids):
+                    continue
+                # Verify classes match
+                if selector.classes and not self.match_classes(el, selector.classes):
+                    continue
+                # Verify attribute(s) match
+                if not self.match_attributes(el, selector.attributes):
+                    continue
+                # Verify ranges
+                if selector.flags & RANGES and not self.match_range(el, selector.flags & RANGES):
+                    continue
+                # Verify language patterns
+                if selector.lang and not self.match_lang(el, selector.lang):
+                    continue
+                # Verify pseudo selector patterns
+                if selector.selectors and not self.match_subselectors(el, selector.selectors):
+                    continue
+                # Verify relationship selectors
+                if selector.relation and not self.match_relations(el, selector.relation):
+                    continue
+                # Validate that the current default selector match corresponds to the first submit button in the form
+                if selector.flags & ct.SEL_DEFAULT and not self.match_default(el):
+                    continue
+                # Validate that the unset radio button is among radio buttons with the same name in a form that are
+                # also not set.
+                if selector.flags & ct.SEL_INDETERMINATE and not self.match_indeterminate(el):
+                    continue
+                # Validate element directionality
+                if selector.flags & DIR_FLAGS and not self.match_dir(el, selector.flags & DIR_FLAGS):
+                    continue
+                # Validate that the tag contains the specified text.
+                if not self.match_contains(el, selector.contains):
+                    continue
+                match = not is_not
+                break
+
+        return match
+
+    def select(self, limit=0):
+        """Match all tags under the targeted tag."""
+
+        if limit < 1:
+            limit = None
+
+        for child in self.tag.descendants:
+            if util.is_tag(child) and self.match(child):
+                yield child
+                if limit is not None:
+                    limit -= 1
+                    if limit < 1:
+                        break
+
+    def closest(self):
+        """Match closest ancestor."""
+
+        current = self.tag
+        closest = None
+        while closest is None and current is not None:
+            if self.match(current):
+                closest = current
+            else:
+                current = current.parent
+        return closest
+
+    def filter(self):  # noqa A001
+        """Filter tag's children."""
+
+        return [node for node in self.tag if not util.is_navigable_string(node) and self.match(node)]
+
+    def match(self, el):
+        """Match."""
+
+        return not util.is_doc(el) and util.is_tag(el) and self.match_selectors(el, self.selectors)
+
+
+class SoupSieve(ct.Immutable):
+    """Compiled Soup Sieve selector matching object."""
+
+    __slots__ = ("pattern", "selectors", "namespaces", "flags", "_hash")
+
+    def __init__(self, pattern, selectors, namespaces, flags):
+        """Initialize."""
+
+        super(SoupSieve, self).__init__(
+            pattern=pattern,
+            selectors=selectors,
+            namespaces=namespaces,
+            flags=flags
+        )
+
+    def match(self, tag):
+        """Match."""
+
+        return CSSMatch(self.selectors, tag, self.namespaces, self.flags).match(tag)
+
+    def closest(self, tag):
+        """Match closest ancestor."""
+
+        return CSSMatch(self.selectors, tag, self.namespaces, self.flags).closest()
+
+    def filter(self, iterable):  # noqa A001
+        """
+        Filter.
+
+        `CSSMatch` can cache certain searches for tags of the same document,
+        so if we are given a tag, all tags are from the same document,
+        and we can take advantage of the optimization.
+
+        Any other kind of iterable could have tags from different documents or detached tags,
+        so for those, we use a new `CSSMatch` for each item in the iterable.
+        """
+
+        if util.is_tag(iterable):
+            return CSSMatch(self.selectors, iterable, self.namespaces, self.flags).filter()
+        else:
+            return [node for node in iterable if not util.is_navigable_string(node) and self.match(node)]
+
+    def comments(self, tag, limit=0):
+        """Get comments only."""
+
+        return list(self.icomments(tag, limit))
+
+    def icomments(self, tag, limit=0):
+        """Iterate comments only."""
+
+        for comment in get_comments(tag, limit):
+            yield comment
+
+    def select_one(self, tag):
+        """Select a single tag."""
+
+        tags = self.select(tag, limit=1)
+        return tags[0] if tags else None
+
+    def select(self, tag, limit=0):
+        """Select the specified tags."""
+
+        return list(self.iselect(tag, limit))
+
+    def iselect(self, tag, limit=0):
+        """Iterate the specified tags."""
+
+        for el in CSSMatch(self.selectors, tag, self.namespaces, self.flags).select(limit):
+            yield el
+
+    def __repr__(self):  # pragma: no cover
+        """Representation."""
+
+        return "SoupSieve(pattern={!r}, namespaces={!r}, flags={!r})".format(self.pattern, self.namespaces, self.flags)
+
+    __str__ = __repr__
+
+
+ct.pickle_register(SoupSieve)
diff --git a/ext/soupsieve/css_parser.py b/ext/soupsieve/css_parser.py
new file mode 100644
index 0000000000..ac1a2cdd02
--- /dev/null
+++ b/ext/soupsieve/css_parser.py
@@ -0,0 +1,1013 @@
+"""CSS selector parser."""
+from __future__ import unicode_literals
+import re
+from . import util
+from . import css_match as cm
+from . import css_types as ct
+from collections import OrderedDict
+
+# Simple pseudo classes that take no parameters
+PSEUDO_SIMPLE = {
+    ":any-link",
+    ":empty",
+    ":first-child",
+    ":first-of-type",
+    ":in-range",
+    ":out-of-range",
+    ":last-child",
+    ":last-of-type",
+    ":link",
+    ":only-child",
+    ":only-of-type",
+    ":root",
+    ':checked',
+    ':default',
+    ':disabled',
+    ':enabled',
+    ':indeterminate',
+    ':optional',
+    ':placeholder-shown',
+    ':read-only',
+    ':read-write',
+    ':required',
+    ':scope',
+    ':defined'
+}
+
+# Supported, simple pseudo classes that match nothing in the Soup Sieve environment
+PSEUDO_SIMPLE_NO_MATCH = {
+    ':active',
+    ':current',
+    ':focus',
+    ':focus-visible',
+    ':focus-within',
+    ':future',
+    ':host',
+    ':hover',
+    ':local-link',
+    ':past',
+    ':paused',
+    ':playing',
+    ':target',
+    ':target-within',
+    ':user-invalid',
+    ':visited'
+}
+
+# Complex pseudo classes that take selector lists
+PSEUDO_COMPLEX = {
+    ':contains',
+    ':has',
+    ':is',
+    ':matches',
+    ':not',
+    ':where'
+}
+
+PSEUDO_COMPLEX_NO_MATCH = {
+    ':current',
+    ':host',
+    ':host-context'
+}
+
+# Complex pseudo classes that take very specific parameters and are handled special
+PSEUDO_SPECIAL = {
+    ':dir',
+    ':lang',
+    ':nth-child',
+    ':nth-last-child',
+    ':nth-last-of-type',
+    ':nth-of-type'
+}
+
+PSEUDO_SUPPORTED = PSEUDO_SIMPLE | PSEUDO_SIMPLE_NO_MATCH | PSEUDO_COMPLEX | PSEUDO_COMPLEX_NO_MATCH | PSEUDO_SPECIAL
+
+# Sub-patterns parts
+# Whitespace
+WS = r'[ \t\r\n\f]'
+# Comments
+COMMENTS = r'(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)'
+# Whitespace with comments included
+WSC = r'(?:{ws}|{comments})'.format(ws=WS, comments=COMMENTS)
+# CSS escapes
+CSS_ESCAPES = r'(?:\\[a-f0-9]{{1,6}}{ws}?|\\[^\r\n\f])'.format(ws=WS)
+# CSS Identifier
+IDENTIFIER = r'(?:(?!-?[0-9]|--)(?:[^\x00-\x2c\x2e\x2f\x3A-\x40\x5B-\x5E\x60\x7B-\x9f]|{esc})+)'.format(esc=CSS_ESCAPES)
+# `nth` content
+NTH = r'(?:[-+])?(?:[0-9]+n?|n)(?:(?<=n){ws}*(?:[-+]){ws}*(?:[0-9]+))?'.format(ws=WSC)
+# Value: quoted string or identifier
+VALUE = r'''(?:"(?:\\.|[^\\"]+)*?"|'(?:\\.|[^\\']+)*?'|{ident}+)'''.format(ident=IDENTIFIER)
+# Attribute value comparison. `!=` is handled special as it is non-standard.
+ATTR = r'''
+(?:{ws}*(?P[!~^|*$]?=){ws}*(?P{value})(?:{ws}+(?P[is]))?)?{ws}*\]
+'''.format(ws=WSC, value=VALUE)
+
+# Selector patterns
+# IDs (`#id`)
+PAT_ID = r'\#{ident}'.format(ident=IDENTIFIER)
+# Classes (`.class`)
+PAT_CLASS = r'\.{ident}'.format(ident=IDENTIFIER)
+# Prefix:Tag (`prefix|tag`)
+PAT_TAG = r'(?:(?:{ident}|\*)?\|)?(?:{ident}|\*)'.format(ident=IDENTIFIER)
+# Attributes (`[attr]`, `[attr=value]`, etc.)
+PAT_ATTR = r'\[{ws}*(?P(?:(?:{ident}|\*)?\|)?{ident}){attr}'.format(ws=WSC, ident=IDENTIFIER, attr=ATTR)
+# Pseudo class (`:pseudo-class`, `:pseudo-class(`)
+PAT_PSEUDO_CLASS = r'(?P:{ident})(?P\({ws}*)?'.format(ws=WSC, ident=IDENTIFIER)
+# Closing pseudo group (`)`)
+PAT_PSEUDO_CLOSE = r'{ws}*\)'.format(ws=WSC)
+# Pseudo element (`::pseudo-element`)
+PAT_PSEUDO_ELEMENT = r':{}'.format(PAT_PSEUDO_CLASS)
+# At rule (`@page`, etc.) (not supported)
+PAT_AT_RULE = r'@P{ident}'.format(ident=IDENTIFIER)
+# Pseudo class `nth-child` (`:nth-child(an+b [of S]?)`, `:first-child`, etc.)
+PAT_PSEUDO_NTH_CHILD = r'''
+(?P:nth-(?:last-)?child
+\({ws}*(?P{nth}|even|odd))(?:{wsc}*\)|(?P{comments}*{ws}{wsc}*of{comments}*{ws}{wsc}*))
+'''.format(wsc=WSC, comments=COMMENTS, ws=WS, nth=NTH)
+# Pseudo class `nth-of-type` (`:nth-of-type(an+b)`, `:first-of-type`, etc.)
+PAT_PSEUDO_NTH_TYPE = r'''
+(?P:nth-(?:last-)?of-type
+\({ws}*(?P{nth}|even|odd)){ws}*\)
+'''.format(ws=WSC, nth=NTH)
+# Pseudo class language (`:lang("*-de", en)`)
+PAT_PSEUDO_LANG = r':lang\({ws}*(?P{value}(?:{ws}*,{ws}*{value})*){ws}*\)'.format(ws=WSC, value=VALUE)
+# Pseudo class direction (`:dir(ltr)`)
+PAT_PSEUDO_DIR = r':dir\({ws}*(?Pltr|rtl){ws}*\)'.format(ws=WSC)
+# Combining characters (`>`, `~`, ` `, `+`, `,`)
+PAT_COMBINE = r'{ws}*?(?P[,+>~]|[ \t\r\n\f](?![,+>~])){ws}*'.format(ws=WSC)
+# Extra: Contains (`:contains(text)`)
+PAT_PSEUDO_CONTAINS = r':contains\({ws}*(?P{value}){ws}*\)'.format(ws=WSC, value=VALUE)
+
+# Regular expressions
+# CSS escape pattern
+RE_CSS_ESC = re.compile(r'(?:(\\[a-f0-9]{{1,6}}{ws}?)|(\\[^\r\n\f]))'.format(ws=WSC), re.I)
+# Pattern to break up `nth` specifiers
+RE_NTH = re.compile(
+    r'(?P[-+])?(?P[0-9]+n?|n)(?:(?<=n){ws}*(?P[-+]){ws}*(?P[0-9]+))?'.format(ws=WSC),
+    re.I
+)
+# Pattern to iterate multiple languages.
+RE_LANG = re.compile(r'(?:(?P{value})|(?P{ws}*,{ws}*))'.format(ws=WSC, value=VALUE), re.X)
+# Whitespace checks
+RE_WS = re.compile(WS)
+RE_WS_BEGIN = re.compile('^{}*'.format(WSC))
+RE_WS_END = re.compile('{}*$'.format(WSC))
+
+# Constants
+# List split token
+COMMA_COMBINATOR = ','
+# Relation token for descendant
+WS_COMBINATOR = " "
+
+# Parse flags
+FLG_PSEUDO = 0x01
+FLG_NOT = 0x02
+FLG_RELATIVE = 0x04
+FLG_DEFAULT = 0x08
+FLG_HTML = 0x10
+FLG_INDETERMINATE = 0x20
+FLG_OPEN = 0x40
+FLG_IN_RANGE = 0x80
+FLG_OUT_OF_RANGE = 0x100
+
+# Maximum cached patterns to store
+_MAXCACHE = 500
+
+
+@util.lru_cache(maxsize=_MAXCACHE)
+def _cached_css_compile(pattern, namespaces, flags):
+    """Cached CSS compile."""
+
+    return cm.SoupSieve(
+        pattern,
+        CSSParser(pattern, flags).process_selectors(),
+        namespaces,
+        flags
+    )
+
+
+def _purge_cache():
+    """Purge the cache."""
+
+    _cached_css_compile.cache_clear()
+
+
+def css_unescape(string):
+    """Unescape CSS value."""
+
+    def replace(m):
+        """Replace with the appropriate substitute."""
+
+        return util.uchr(int(m.group(1)[1:], 16)) if m.group(1) else m.group(2)[1:]
+
+    return RE_CSS_ESC.sub(replace, string)
+
+
+class SelectorPattern(object):
+    """Selector pattern."""
+
+    def __init__(self, pattern):
+        """Initialize."""
+
+        self.pattern = re.compile(pattern, re.I | re.X | re.U)
+
+    def enabled(self, flags):
+        """Enabled."""
+
+        return True
+
+
+class _Selector(object):
+    """
+    Intermediate selector class.
+
+    This stores selector data for a compound selector as we are acquiring them.
+    Once we are done collecting the data for a compound selector, we freeze
+    the data in an object that can be pickled and hashed.
+    """
+
+    def __init__(self, **kwargs):
+        """Initialize."""
+
+        self.tag = kwargs.get('tag', None)
+        self.ids = kwargs.get('ids', [])
+        self.classes = kwargs.get('classes', [])
+        self.attributes = kwargs.get('attributes', [])
+        self.nth = kwargs.get('nth', [])
+        self.selectors = kwargs.get('selectors', [])
+        self.relations = kwargs.get('relations', [])
+        self.rel_type = kwargs.get('rel_type', None)
+        self.contains = kwargs.get('contains', [])
+        self.lang = kwargs.get('lang', [])
+        self.flags = kwargs.get('flags', 0)
+        self.no_match = kwargs.get('no_match', False)
+
+    def _freeze_relations(self, relations):
+        """Freeze relation."""
+
+        if relations:
+            sel = relations[0]
+            sel.relations.extend(relations[1:])
+            return ct.SelectorList([sel.freeze()])
+        else:
+            return ct.SelectorList()
+
+    def freeze(self):
+        """Freeze self."""
+
+        if self.no_match:
+            return ct.NullSelector()
+        else:
+            return ct.Selector(
+                self.tag,
+                tuple(self.ids),
+                tuple(self.classes),
+                tuple(self.attributes),
+                tuple(self.nth),
+                tuple(self.selectors),
+                self._freeze_relations(self.relations),
+                self.rel_type,
+                tuple(self.contains),
+                tuple(self.lang),
+                self.flags
+            )
+
+    def __str__(self):  # pragma: no cover
+        """String representation."""
+
+        return (
+            '_Selector(tag={!r}, ids={!r}, classes={!r}, attributes={!r}, nth={!r}, selectors={!r}, '
+            'relations={!r}, rel_type={!r}, contains={!r}, lang={!r}, flags={!r}, no_match={!r})'
+        ).format(
+            self.tag, self.ids, self.classes, self.attributes, self.nth, self.selectors,
+            self.relations, self.rel_type, self.contains, self.lang, self.flags, self.no_match
+        )
+
+    __repr__ = __str__
+
+
+class CSSParser(object):
+    """Parse CSS selectors."""
+
+    css_tokens = OrderedDict(
+        [
+            ("pseudo_close", SelectorPattern(PAT_PSEUDO_CLOSE)),
+            ("pseudo_contains", SelectorPattern(PAT_PSEUDO_CONTAINS)),
+            ("pseudo_nth_child", SelectorPattern(PAT_PSEUDO_NTH_CHILD)),
+            ("pseudo_nth_type", SelectorPattern(PAT_PSEUDO_NTH_TYPE)),
+            ("pseudo_lang", SelectorPattern(PAT_PSEUDO_LANG)),
+            ("pseudo_dir", SelectorPattern(PAT_PSEUDO_DIR)),
+            ("pseudo_class", SelectorPattern(PAT_PSEUDO_CLASS)),
+            ("pseudo_element", SelectorPattern(PAT_PSEUDO_ELEMENT)),
+            ("at_rule", SelectorPattern(PAT_AT_RULE)),
+            ("id", SelectorPattern(PAT_ID)),
+            ("class", SelectorPattern(PAT_CLASS)),
+            ("tag", SelectorPattern(PAT_TAG)),
+            ("attribute", SelectorPattern(PAT_ATTR)),
+            ("combine", SelectorPattern(PAT_COMBINE))
+        ]
+    )
+
+    def __init__(self, selector, flags=0):
+        """Initialize."""
+
+        self.pattern = selector
+        self.flags = flags
+        self.debug = self.flags & util.DEBUG
+
+    def parse_attribute_selector(self, sel, m, has_selector):
+        """Create attribute selector from the returned regex match."""
+
+        op = m.group('cmp')
+        if op and op.startswith('!'):
+            # Equivalent to `:not([attr=value])`
+            attr = m.group('ns_attr')
+            value = m.group('value')
+            case = m.group('case')
+            if not case:
+                case = ''
+            sel.selectors.append(
+                self.parse_selectors(
+                    # Simulate the content of `:not`, but make the attribute as `=` instead of `!=`.
+                    self.selector_iter('[{}={} {}]'.format(attr, value, case)),
+                    m.end(0),
+                    FLG_PSEUDO | FLG_NOT
+                )
+            )
+            has_selector = True
+        else:
+            case = util.lower(m.group('case')) if m.group('case') else None
+            parts = [css_unescape(a) for a in m.group('ns_attr').split('|')]
+            ns = ''
+            is_type = False
+            pattern2 = None
+            if len(parts) > 1:
+                ns = parts[0]
+                attr = parts[1]
+            else:
+                attr = parts[0]
+            if case:
+                flags = re.I if case == 'i' else 0
+            elif util.lower(attr) == 'type':
+                flags = re.I
+                is_type = True
+            else:
+                flags = 0
+
+            if op:
+                value = css_unescape(
+                    m.group('value')[1:-1] if m.group('value').startswith(('"', "'")) else m.group('value')
+                )
+            else:
+                value = None
+            if not op:
+                # Attribute name
+                pattern = None
+            elif op.startswith('^'):
+                # Value start with
+                pattern = re.compile(r'^%s.*' % re.escape(value), flags)
+            elif op.startswith('$'):
+                # Value ends with
+                pattern = re.compile(r'.*?%s$' % re.escape(value), flags)
+            elif op.startswith('*'):
+                # Value contains
+                pattern = re.compile(r'.*?%s.*' % re.escape(value), flags)
+            elif op.startswith('~'):
+                # Value contains word within space separated list
+                # `~=` should match nothing if it is empty or contains whitespace,
+                # so if either of these cases is present, use `[^\s\S]` which cannot be matched.
+                value = r'[^\s\S]' if not value or RE_WS.search(value) else re.escape(value)
+                pattern = re.compile(r'.*?(?:(?<=^)|(?<=[ \t\r\n\f]))%s(?=(?:[ \t\r\n\f]|$)).*' % value, flags)
+            elif op.startswith('|'):
+                # Value starts with word in dash separated list
+                pattern = re.compile(r'^%s(?:-.*)?$' % re.escape(value), flags)
+            else:
+                # Value matches
+                pattern = re.compile(r'^%s$' % re.escape(value), flags)
+            if is_type and pattern:
+                pattern2 = re.compile(pattern.pattern)
+            has_selector = True
+            sel.attributes.append(ct.SelectorAttribute(attr, ns, pattern, pattern2))
+        return has_selector
+
+    def parse_tag_pattern(self, sel, m, has_selector):
+        """Parse tag pattern from regex match."""
+
+        parts = [css_unescape(x) for x in m.group(0).split('|')]
+        if len(parts) > 1:
+            prefix = parts[0]
+            tag = parts[1]
+        else:
+            tag = parts[0]
+            prefix = None
+        sel.tag = ct.SelectorTag(tag, prefix)
+        has_selector = True
+        return has_selector
+
+    def parse_pseudo_class(self, sel, m, has_selector, iselector, is_html):
+        """Parse pseudo class."""
+
+        complex_pseudo = False
+        pseudo = util.lower(m.group('name'))
+        if m.group('open'):
+            complex_pseudo = True
+        if complex_pseudo and pseudo in PSEUDO_COMPLEX:
+            has_selector = self.parse_pseudo_open(sel, pseudo, has_selector, iselector, m.end(0))
+        elif not complex_pseudo and pseudo in PSEUDO_SIMPLE:
+            if pseudo == ':root':
+                sel.flags |= ct.SEL_ROOT
+            elif pseudo == ':defined':
+                sel.flags |= ct.SEL_DEFINED
+                is_html = True
+            elif pseudo == ':scope':
+                sel.flags |= ct.SEL_SCOPE
+            elif pseudo == ':empty':
+                sel.flags |= ct.SEL_EMPTY
+            elif pseudo in (':link', ':any-link'):
+                sel.selectors.append(CSS_LINK)
+            elif pseudo == ':checked':
+                sel.selectors.append(CSS_CHECKED)
+            elif pseudo == ':default':
+                sel.selectors.append(CSS_DEFAULT)
+            elif pseudo == ':indeterminate':
+                sel.selectors.append(CSS_INDETERMINATE)
+            elif pseudo == ":disabled":
+                sel.selectors.append(CSS_DISABLED)
+            elif pseudo == ":enabled":
+                sel.selectors.append(CSS_ENABLED)
+            elif pseudo == ":required":
+                sel.selectors.append(CSS_REQUIRED)
+            elif pseudo == ":optional":
+                sel.selectors.append(CSS_OPTIONAL)
+            elif pseudo == ":read-only":
+                sel.selectors.append(CSS_READ_ONLY)
+            elif pseudo == ":read-write":
+                sel.selectors.append(CSS_READ_WRITE)
+            elif pseudo == ":in-range":
+                sel.selectors.append(CSS_IN_RANGE)
+            elif pseudo == ":out-of-range":
+                sel.selectors.append(CSS_OUT_OF_RANGE)
+            elif pseudo == ":placeholder-shown":
+                sel.selectors.append(CSS_PLACEHOLDER_SHOWN)
+            elif pseudo == ':first-child':
+                sel.nth.append(ct.SelectorNth(1, False, 0, False, False, ct.SelectorList()))
+            elif pseudo == ':last-child':
+                sel.nth.append(ct.SelectorNth(1, False, 0, False, True, ct.SelectorList()))
+            elif pseudo == ':first-of-type':
+                sel.nth.append(ct.SelectorNth(1, False, 0, True, False, ct.SelectorList()))
+            elif pseudo == ':last-of-type':
+                sel.nth.append(ct.SelectorNth(1, False, 0, True, True, ct.SelectorList()))
+            elif pseudo == ':only-child':
+                sel.nth.extend(
+                    [
+                        ct.SelectorNth(1, False, 0, False, False, ct.SelectorList()),
+                        ct.SelectorNth(1, False, 0, False, True, ct.SelectorList())
+                    ]
+                )
+            elif pseudo == ':only-of-type':
+                sel.nth.extend(
+                    [
+                        ct.SelectorNth(1, False, 0, True, False, ct.SelectorList()),
+                        ct.SelectorNth(1, False, 0, True, True, ct.SelectorList())
+                    ]
+                )
+            has_selector = True
+        elif complex_pseudo and pseudo in PSEUDO_COMPLEX_NO_MATCH:
+            self.parse_selectors(iselector, m.end(0), FLG_PSEUDO | FLG_OPEN)
+            sel.no_match = True
+            has_selector = True
+        elif not complex_pseudo and pseudo in PSEUDO_SIMPLE_NO_MATCH:
+            sel.no_match = True
+            has_selector = True
+        elif pseudo in PSEUDO_SUPPORTED:
+            raise SyntaxError("Invalid syntax for pseudo class '{}'".format(pseudo))
+        else:
+            raise NotImplementedError(
+                "'{}' pseudo-class is not implemented at this time".format(pseudo)
+            )
+
+        return has_selector, is_html
+
+    def parse_pseudo_nth(self, sel, m, has_selector, iselector):
+        """Parse `nth` pseudo."""
+
+        mdict = m.groupdict()
+        postfix = '_child' if mdict.get('pseudo_nth_child') else '_type'
+        content = mdict.get('nth' + postfix)
+        if content == 'even':
+            s1 = 2
+            s2 = 2
+            var = True
+        elif content == 'odd':
+            s1 = 2
+            s2 = 1
+            var = True
+        else:
+            nth_parts = RE_NTH.match(content)
+            s1 = '-' if nth_parts.group('s1') and nth_parts.group('s1') == '-' else ''
+            a = nth_parts.group('a')
+            var = a.endswith('n')
+            if a.startswith('n'):
+                s1 += '1'
+            elif var:
+                s1 += a[:-1]
+            else:
+                s1 += a
+            s2 = '-' if nth_parts.group('s2') and nth_parts.group('s2') == '-' else ''
+            if nth_parts.group('b'):
+                s2 += nth_parts.group('b')
+            else:
+                s2 = '0'
+            s1 = int(s1, 10)
+            s2 = int(s2, 10)
+
+        pseudo_sel = util.lower(m.group('pseudo_nth' + postfix))
+        if postfix == '_child':
+            if m.group('of'):
+                # Parse the rest of `of S`.
+                nth_sel = self.parse_selectors(iselector, m.end(0), FLG_PSEUDO | FLG_OPEN)
+            else:
+                # Use default `*|*` for `of S`.
+                nth_sel = CSS_NTH_OF_S_DEFAULT
+            if pseudo_sel.startswith(':nth-child'):
+                sel.nth.append(ct.SelectorNth(s1, var, s2, False, False, nth_sel))
+            elif pseudo_sel.startswith(':nth-last-child'):
+                sel.nth.append(ct.SelectorNth(s1, var, s2, False, True, nth_sel))
+        else:
+            if pseudo_sel.startswith(':nth-of-type'):
+                sel.nth.append(ct.SelectorNth(s1, var, s2, True, False, ct.SelectorList()))
+            elif pseudo_sel.startswith(':nth-last-of-type'):
+                sel.nth.append(ct.SelectorNth(s1, var, s2, True, True, ct.SelectorList()))
+        has_selector = True
+        return has_selector
+
+    def parse_pseudo_open(self, sel, name, has_selector, iselector, index):
+        """Parse pseudo with opening bracket."""
+
+        flags = FLG_PSEUDO | FLG_OPEN
+        if name == ':not':
+            flags |= FLG_NOT
+        if name == ':has':
+            flags |= FLG_RELATIVE
+
+        sel.selectors.append(self.parse_selectors(iselector, index, flags))
+        has_selector = True
+        return has_selector
+
+    def parse_has_combinator(self, sel, m, has_selector, selectors, rel_type, index):
+        """Parse combinator tokens."""
+
+        combinator = m.group('relation').strip()
+        if not combinator:
+            combinator = WS_COMBINATOR
+        if combinator == COMMA_COMBINATOR:
+            if not has_selector:
+                raise SyntaxError(
+                    "The combinator '{}' at postion {}, must have a selector before it".format(combinator, index)
+                )
+            sel.rel_type = rel_type
+            selectors[-1].relations.append(sel)
+            rel_type = ":" + WS_COMBINATOR
+            selectors.append(_Selector())
+        else:
+            if has_selector:
+                sel.rel_type = rel_type
+                selectors[-1].relations.append(sel)
+            rel_type = ':' + combinator
+        sel = _Selector()
+
+        has_selector = False
+        return has_selector, sel, rel_type
+
+    def parse_combinator(self, sel, m, has_selector, selectors, relations, is_pseudo, index):
+        """Parse combinator tokens."""
+
+        combinator = m.group('relation').strip()
+        if not combinator:
+            combinator = WS_COMBINATOR
+        if not has_selector:
+            raise SyntaxError(
+                "The combinator '{}' at postion {}, must have a selector before it".format(combinator, index)
+            )
+        if combinator == COMMA_COMBINATOR:
+            if not sel.tag and not is_pseudo:
+                # Implied `*`
+                sel.tag = ct.SelectorTag('*', None)
+            sel.relations.extend(relations)
+            selectors.append(sel)
+            del relations[:]
+        else:
+            sel.relations.extend(relations)
+            sel.rel_type = combinator
+            del relations[:]
+            relations.append(sel)
+        sel = _Selector()
+
+        has_selector = False
+        return has_selector, sel
+
+    def parse_class_id(self, sel, m, has_selector):
+        """Parse HTML classes and ids."""
+
+        selector = m.group(0)
+        if selector.startswith('.'):
+            sel.classes.append(css_unescape(selector[1:]))
+            has_selector = True
+        else:
+            sel.ids.append(css_unescape(selector[1:]))
+            has_selector = True
+        return has_selector
+
+    def parse_pseudo_contains(self, sel, m, has_selector):
+        """Parse contains."""
+
+        content = m.group('value')
+        if content.startswith(("'", '"')):
+            content = content[1:-1]
+        content = css_unescape(content)
+        sel.contains.append(content)
+        has_selector = True
+        return has_selector
+
+    def parse_pseudo_lang(self, sel, m, has_selector):
+        """Parse pseudo language."""
+
+        lang = m.group('lang')
+        patterns = []
+        for token in RE_LANG.finditer(lang):
+            if token.group('split'):
+                continue
+            value = token.group('value')
+            if value.startswith(('"', "'")):
+                value = value[1:-1]
+            parts = css_unescape(value).split('-')
+
+            new_parts = []
+            first = True
+            for part in parts:
+                if part == '*' and first:
+                    new_parts.append('(?!x\b)[a-z0-9]+?')
+                elif part != '*':
+                    new_parts.append(('' if first else '(-(?!x\b)[a-z0-9]+)*?\\-') + re.escape(part))
+                if first:
+                    first = False
+            patterns.append(re.compile(r'^{}(?:-.*)?$'.format(''.join(new_parts)), re.I))
+        sel.lang.append(ct.SelectorLang(patterns))
+        has_selector = True
+
+        return has_selector
+
+    def parse_pseudo_dir(self, sel, m, has_selector):
+        """Parse pseudo direction."""
+
+        value = ct.SEL_DIR_LTR if util.lower(m.group('dir')) == 'ltr' else ct.SEL_DIR_RTL
+        sel.flags |= value
+        has_selector = True
+        return has_selector
+
+    def parse_selectors(self, iselector, index=0, flags=0):
+        """Parse selectors."""
+
+        sel = _Selector()
+        selectors = []
+        has_selector = False
+        closed = False
+        relations = []
+        rel_type = ":" + WS_COMBINATOR
+        split_last = False
+        is_open = flags & FLG_OPEN
+        is_pseudo = flags & FLG_PSEUDO
+        is_relative = flags & FLG_RELATIVE
+        is_not = flags & FLG_NOT
+        is_html = flags & FLG_HTML
+        is_default = flags & FLG_DEFAULT
+        is_indeterminate = flags & FLG_INDETERMINATE
+        is_in_range = flags & FLG_IN_RANGE
+        is_out_of_range = flags & FLG_OUT_OF_RANGE
+
+        if self.debug:  # pragma: no cover
+            if is_pseudo:
+                print('    is_pseudo: True')
+            if is_open:
+                print('    is_open: True')
+            if is_relative:
+                print('    is_relative: True')
+            if is_not:
+                print('    is_not: True')
+            if is_html:
+                print('    is_html: True')
+            if is_default:
+                print('    is_default: True')
+            if is_indeterminate:
+                print('    is_indeterminate: True')
+            if is_in_range:
+                print('    is_in_range: True')
+            if is_out_of_range:
+                print('    is_out_of_range: True')
+
+        if is_relative:
+            selectors.append(_Selector())
+
+        try:
+            while True:
+                key, m = next(iselector)
+
+                # Handle parts
+                if key == "at_rule":
+                    raise NotImplementedError("At-rules found at position {}".format(m.start(0)))
+                elif key == 'pseudo_class':
+                    has_selector, is_html = self.parse_pseudo_class(sel, m, has_selector, iselector, is_html)
+                elif key == 'pseudo_element':
+                    raise NotImplementedError("Psuedo-element found at position {}".format(m.start(0)))
+                elif key == 'pseudo_contains':
+                    has_selector = self.parse_pseudo_contains(sel, m, has_selector)
+                elif key in ('pseudo_nth_type', 'pseudo_nth_child'):
+                    has_selector = self.parse_pseudo_nth(sel, m, has_selector, iselector)
+                elif key == 'pseudo_lang':
+                    has_selector = self.parse_pseudo_lang(sel, m, has_selector)
+                elif key == 'pseudo_dir':
+                    has_selector = self.parse_pseudo_dir(sel, m, has_selector)
+                    # Currently only supports HTML
+                    is_html = True
+                elif key == 'pseudo_close':
+                    if split_last:
+                        raise SyntaxError("Expected a selector at postion {}".format(m.start(0)))
+                    if is_open:
+                        closed = True
+                        break
+                    else:
+                        raise SyntaxError("Unmatched pseudo-class close at postion {}".format(m.start(0)))
+                elif key == 'combine':
+                    if split_last:
+                        raise SyntaxError("Unexpected combinator at position {}".format(m.start(0)))
+                    if is_relative:
+                        has_selector, sel, rel_type = self.parse_has_combinator(
+                            sel, m, has_selector, selectors, rel_type, index
+                        )
+                    else:
+                        has_selector, sel = self.parse_combinator(
+                            sel, m, has_selector, selectors, relations, is_pseudo, index
+                        )
+                    split_last = True
+                    index = m.end(0)
+                    continue
+                elif key == 'attribute':
+                    has_selector = self.parse_attribute_selector(sel, m, has_selector)
+                elif key == 'tag':
+                    if has_selector:
+                        raise SyntaxError("Tag name found at position {} instead of at the start".format(m.start(0)))
+                    has_selector = self.parse_tag_pattern(sel, m, has_selector)
+                elif key in ('class', 'id'):
+                    has_selector = self.parse_class_id(sel, m, has_selector)
+                split_last = False
+
+                index = m.end(0)
+        except StopIteration:
+            pass
+
+        if is_open and not closed:
+            raise SyntaxError("Unclosed pseudo-class at position {}".format(index))
+
+        if split_last:
+            raise SyntaxError("Expected a selector at position {}".format(index))
+
+        if has_selector:
+            if not sel.tag and not is_pseudo:
+                # Implied `*`
+                sel.tag = ct.SelectorTag('*', None)
+            if is_relative:
+                sel.rel_type = rel_type
+                selectors[-1].relations.append(sel)
+            else:
+                sel.relations.extend(relations)
+                del relations[:]
+                selectors.append(sel)
+        elif is_relative:
+            # We will always need to finish a selector when `:has()` is used as it leads with combining.
+            raise SyntaxError('Expected a selector at position {}'.format(index))
+
+        # Some patterns require additional logic, such as default. We try to make these the
+        # last pattern, and append the appropriate flag to that selector which communicates
+        # to the matcher what additional logic is required.
+        if is_default:
+            selectors[-1].flags = ct.SEL_DEFAULT
+        if is_indeterminate:
+            selectors[-1].flags = ct.SEL_INDETERMINATE
+        if is_in_range:
+            selectors[-1].flags = ct.SEL_IN_RANGE
+        if is_out_of_range:
+            selectors[-1].flags = ct.SEL_OUT_OF_RANGE
+
+        return ct.SelectorList([s.freeze() for s in selectors], is_not, is_html)
+
+    def selector_iter(self, pattern):
+        """Iterate selector tokens."""
+
+        # Ignore whitespace and comments at start and end of pattern
+        m = RE_WS_BEGIN.search(pattern)
+        index = m.end(0) if m else 0
+        m = RE_WS_END.search(pattern)
+        end = (m.start(0) - 1) if m else (len(pattern) - 1)
+
+        if self.debug:  # pragma: no cover
+            print('## PARSING: {!r}'.format(pattern))
+        while index <= end:
+            m = None
+            for k, v in self.css_tokens.items():
+                if not v.enabled(self.flags):  # pragma: no cover
+                    continue
+                m = v.pattern.match(pattern, index)
+                if m:
+                    if self.debug:  # pragma: no cover
+                        print("TOKEN: '{}' --> {!r} at position {}".format(k, m.group(0), m.start(0)))
+                    index = m.end(0)
+                    yield k, m
+                    break
+            if m is None:
+                c = pattern[index]
+                # If the character represents the start of one of the known selector types,
+                # throw an exception mentions that the known selector type in error;
+                # otherwise, report the invalid character.
+                if c == '[':
+                    msg = "Malformed attribute selector at position {}".format(index)
+                elif c == '.':
+                    msg = "Malformed class selector at position {}".format(index)
+                elif c == '#':
+                    msg = "Malformed id selector at position {}".format(index)
+                elif c == ':':
+                    msg = "Malformed pseudo-class selector at position {}".format(index)
+                else:
+                    msg = "Invalid character {!r} position {}".format(c, index)
+                raise SyntaxError(msg)
+        if self.debug:  # pragma: no cover
+            print('## END PARSING')
+
+    def process_selectors(self, index=0, flags=0):
+        """
+        Process selectors.
+
+        We do our own selectors as BeautifulSoup4 has some annoying quirks,
+        and we don't really need to do nth selectors or siblings or
+        descendants etc.
+        """
+
+        return self.parse_selectors(self.selector_iter(self.pattern), index, flags)
+
+
+# Precompile CSS selector lists for pseudo-classes (additional logic may be required beyond the pattern)
+# A few patterns are order dependent as they use patterns previous compiled.
+
+# CSS pattern for `:link` and `:any-link`
+CSS_LINK = CSSParser(
+    ':is(a, area, link)[href]'
+).process_selectors(flags=FLG_PSEUDO | FLG_HTML)
+# CSS pattern for `:checked`
+CSS_CHECKED = CSSParser(
+    '''
+    :is(input[type=checkbox], input[type=radio])[checked],
+    select > option[selected]
+    '''
+).process_selectors(flags=FLG_PSEUDO | FLG_HTML)
+# CSS pattern for `:default` (must compile CSS_CHECKED first)
+CSS_DEFAULT = CSSParser(
+    '''
+    :checked,
+
+    /*
+    This pattern must be at the end.
+    Special logic is applied to the last selector.
+    */
+    form :is(button, input)[type="submit"]
+    '''
+).process_selectors(flags=FLG_PSEUDO | FLG_HTML | FLG_DEFAULT)
+# CSS pattern for `:indeterminate`
+CSS_INDETERMINATE = CSSParser(
+    '''
+    input[type="checkbox"][indeterminate],
+    input[type="radio"]:is(:not([name]), [name=""]):not([checked]),
+    progress:not([value]),
+
+    /*
+    This pattern must be at the end.
+    Special logic is applied to the last selector.
+    */
+    input[type="radio"][name][name!='']:not([checked])
+    '''
+).process_selectors(flags=FLG_PSEUDO | FLG_HTML | FLG_INDETERMINATE)
+# CSS pattern for `:disabled`
+CSS_DISABLED = CSSParser(
+    '''
+    :is(input[type!=hidden], button, select, textarea, fieldset, optgroup, option)[disabled],
+    optgroup[disabled] > option,
+    fieldset[disabled] > :not(legend) :is(input[type!=hidden], button, select, textarea),
+    fieldset[disabled] > :is(input[type!=hidden], button, select, textarea)
+    '''
+).process_selectors(flags=FLG_PSEUDO | FLG_HTML)
+# CSS pattern for `:enabled`
+CSS_ENABLED = CSSParser(
+    '''
+    :is(a, area, link)[href],
+    :is(fieldset, optgroup):not([disabled]),
+    option:not(optgroup[disabled] *):not([disabled]),
+    :is(input[type!=hidden], button, select, textarea):not(
+        fieldset[disabled] > :not(legend) *,
+        fieldset[disabled] > *
+    ):not([disabled])
+    '''
+).process_selectors(flags=FLG_PSEUDO | FLG_HTML)
+# CSS pattern for `:required`
+CSS_REQUIRED = CSSParser(
+    ':is(input, textarea, select)[required]'
+).process_selectors(flags=FLG_PSEUDO | FLG_HTML)
+# CSS pattern for `:optional`
+CSS_OPTIONAL = CSSParser(
+    ':is(input, textarea, select):not([required])'
+).process_selectors(flags=FLG_PSEUDO | FLG_HTML)
+# CSS pattern for `:placeholder-shown`
+CSS_PLACEHOLDER_SHOWN = CSSParser(
+    '''
+    :is(
+        input:is(
+            :not([type]),
+            [type=""],
+            [type=text],
+            [type=search],
+            [type=url],
+            [type=tel],
+            [type=email],
+            [type=password],
+            [type=number]
+        ),
+        textarea
+    )[placeholder][placeholder!='']
+    '''
+).process_selectors(flags=FLG_PSEUDO | FLG_HTML)
+# CSS pattern default for `:nth-child` "of S" feature
+CSS_NTH_OF_S_DEFAULT = CSSParser(
+    '*|*'
+).process_selectors(flags=FLG_PSEUDO)
+# CSS pattern for `:read-write` (CSS_DISABLED must be compiled first)
+CSS_READ_WRITE = CSSParser(
+    '''
+    :is(
+        textarea,
+        input:is(
+            :not([type]),
+            [type=""],
+            [type=text],
+            [type=search],
+            [type=url],
+            [type=tel],
+            [type=email],
+            [type=number],
+            [type=password],
+            [type=date],
+            [type=datetime-local],
+            [type=month],
+            [type=time],
+            [type=week]
+        )
+    ):not([readonly], :disabled),
+    :is([contenteditable=""], [contenteditable="true" i])
+    '''
+).process_selectors(flags=FLG_PSEUDO | FLG_HTML)
+# CSS pattern for `:read-only`
+CSS_READ_ONLY = CSSParser(
+    '''
+    :not(:read-write)
+    '''
+).process_selectors(flags=FLG_PSEUDO | FLG_HTML)
+# CSS pattern for `:in-range`
+CSS_IN_RANGE = CSSParser(
+    '''
+    input:is(
+        [type="date"],
+        [type="month"],
+        [type="week"],
+        [type="time"],
+        [type="datetime-local"],
+        [type="number"],
+        [type="range"]
+    ):is(
+        [min],
+        [max]
+    )
+    '''
+).process_selectors(flags=FLG_PSEUDO | FLG_IN_RANGE | FLG_HTML)
+# CSS pattern for `:out-of-range`
+CSS_OUT_OF_RANGE = CSSParser(
+    '''
+    input:is(
+        [type="date"],
+        [type="month"],
+        [type="week"],
+        [type="time"],
+        [type="datetime-local"],
+        [type="number"],
+        [type="range"]
+    ):is(
+        [min],
+        [max]
+    )
+    '''
+).process_selectors(flags=FLG_PSEUDO | FLG_OUT_OF_RANGE | FLG_HTML)
diff --git a/ext/soupsieve/css_types.py b/ext/soupsieve/css_types.py
new file mode 100644
index 0000000000..457bea5354
--- /dev/null
+++ b/ext/soupsieve/css_types.py
@@ -0,0 +1,309 @@
+"""CSS selector structure items."""
+from __future__ import unicode_literals
+from . import util
+
+__all__ = (
+    'Selector',
+    'NullSelector',
+    'SelectorTag',
+    'SelectorAttribute',
+    'SelectorNth',
+    'SelectorLang',
+    'SelectorList',
+    'Namespaces'
+)
+
+
+SEL_EMPTY = 0x1
+SEL_ROOT = 0x2
+SEL_DEFAULT = 0x4
+SEL_INDETERMINATE = 0x8
+SEL_SCOPE = 0x10
+SEL_DIR_LTR = 0x20
+SEL_DIR_RTL = 0x40
+SEL_IN_RANGE = 0x80
+SEL_OUT_OF_RANGE = 0x100
+SEL_DEFINED = 0x200
+
+
+class Immutable(object):
+    """Immutable."""
+
+    __slots__ = ('_hash',)
+
+    def __init__(self, **kwargs):
+        """Initialize."""
+
+        temp = []
+        for k, v in kwargs.items():
+            temp.append(type(v))
+            temp.append(v)
+            super(Immutable, self).__setattr__(k, v)
+        super(Immutable, self).__setattr__('_hash', hash(tuple(temp)))
+
+    @classmethod
+    def __base__(cls):
+        """Get base class."""
+
+        return cls
+
+    def __eq__(self, other):
+        """Equal."""
+
+        return (
+            isinstance(other, self.__base__()) and
+            all([getattr(other, key) == getattr(self, key) for key in self.__slots__ if key != '_hash'])
+        )
+
+    def __ne__(self, other):
+        """Equal."""
+
+        return (
+            not isinstance(other, self.__base__()) or
+            any([getattr(other, key) != getattr(self, key) for key in self.__slots__ if key != '_hash'])
+        )
+
+    def __hash__(self):
+        """Hash."""
+
+        return self._hash
+
+    def __setattr__(self, name, value):
+        """Prevent mutability."""
+
+        raise AttributeError("'{}' is immutable".format(self.__class__.__name__))
+
+    def __repr__(self):  # pragma: no cover
+        """Representation."""
+
+        return "{}({})".format(
+            self.__base__(), ', '.join(["{}={!r}".format(k, getattr(self, k)) for k in self.__slots__[:-1]])
+        )
+
+    __str__ = __repr__
+
+
+class ImmutableDict(util.Mapping):
+    """Hashable, immutable dictionary."""
+
+    def __init__(self, *args, **kwargs):
+        """Initialize."""
+
+        arg = args[0] if args else kwargs
+        is_dict = isinstance(arg, dict)
+        if (
+            is_dict and not all([isinstance(v, util.Hashable) for v in arg.values()]) or
+            not is_dict and not all([isinstance(k, util.Hashable) and isinstance(v, util.Hashable) for k, v in arg])
+        ):
+            raise TypeError('All values must be hashable')
+
+        self._d = dict(*args, **kwargs)
+        self._hash = hash(tuple([(type(x), x, type(y), y) for x, y in sorted(self._d.items())]))
+
+    def __iter__(self):
+        """Iterator."""
+
+        return iter(self._d)
+
+    def __len__(self):
+        """Length."""
+
+        return len(self._d)
+
+    def __getitem__(self, key):
+        """Get item: `namespace['key']`."""
+        return self._d[key]
+
+    def __hash__(self):
+        """Hash."""
+
+        return self._hash
+
+    def __repr__(self):  # pragma: no cover
+        """Representation."""
+
+        return "{!r}".format(self._d)
+
+    __str__ = __repr__
+
+
+class Namespaces(ImmutableDict):
+    """Namespaces."""
+
+    def __init__(self, *args, **kwargs):
+        """Initialize."""
+
+        # If there are arguments, check the first index.
+        # `super` should fail if the user gave multiple arguments,
+        # so don't bother checking that.
+        arg = args[0] if args else kwargs
+        is_dict = isinstance(arg, dict)
+        if is_dict and not all([isinstance(k, util.string) and isinstance(v, util.string) for k, v in arg.items()]):
+            raise TypeError('Namespace keys and values must be Unicode strings')
+        elif not is_dict and not all([isinstance(k, util.string) and isinstance(v, util.string) for k, v in arg]):
+            raise TypeError('Namespace keys and values must be Unicode strings')
+
+        super(Namespaces, self).__init__(*args, **kwargs)
+
+
+class Selector(Immutable):
+    """Selector."""
+
+    __slots__ = (
+        'tag', 'ids', 'classes', 'attributes', 'nth', 'selectors',
+        'relation', 'rel_type', 'contains', 'lang', 'flags', '_hash'
+    )
+
+    def __init__(
+        self, tag, ids, classes, attributes, nth, selectors,
+        relation, rel_type, contains, lang, flags
+    ):
+        """Initialize."""
+
+        super(Selector, self).__init__(
+            tag=tag,
+            ids=ids,
+            classes=classes,
+            attributes=attributes,
+            nth=nth,
+            selectors=selectors,
+            relation=relation,
+            rel_type=rel_type,
+            contains=contains,
+            lang=lang,
+            flags=flags
+        )
+
+
+class NullSelector(Immutable):
+    """Null Selector."""
+
+    def __init__(self):
+        """Initialize."""
+
+        super(NullSelector, self).__init__()
+
+
+class SelectorTag(Immutable):
+    """Selector tag."""
+
+    __slots__ = ("name", "prefix", "_hash")
+
+    def __init__(self, name, prefix):
+        """Initialize."""
+
+        super(SelectorTag, self).__init__(
+            name=name,
+            prefix=prefix
+        )
+
+
+class SelectorAttribute(Immutable):
+    """Selector attribute rule."""
+
+    __slots__ = ("attribute", "prefix", "pattern", "xml_type_pattern", "_hash")
+
+    def __init__(self, attribute, prefix, pattern, xml_type_pattern):
+        """Initialize."""
+
+        super(SelectorAttribute, self).__init__(
+            attribute=attribute,
+            prefix=prefix,
+            pattern=pattern,
+            xml_type_pattern=xml_type_pattern
+        )
+
+
+class SelectorNth(Immutable):
+    """Selector nth type."""
+
+    __slots__ = ("a", "n", "b", "of_type", "last", "selectors", "_hash")
+
+    def __init__(self, a, n, b, of_type, last, selectors):
+        """Initialize."""
+
+        super(SelectorNth, self).__init__(
+            a=a,
+            n=n,
+            b=b,
+            of_type=of_type,
+            last=last,
+            selectors=selectors
+        )
+
+
+class SelectorLang(Immutable):
+    """Selector language rules."""
+
+    __slots__ = ("languages", "_hash",)
+
+    def __init__(self, languages):
+        """Initialize."""
+
+        super(SelectorLang, self).__init__(
+            languages=tuple(languages)
+        )
+
+    def __iter__(self):
+        """Iterator."""
+
+        return iter(self.languages)
+
+    def __len__(self):  # pragma: no cover
+        """Length."""
+
+        return len(self.languages)
+
+    def __getitem__(self, index):  # pragma: no cover
+        """Get item."""
+
+        return self.languages[index]
+
+
+class SelectorList(Immutable):
+    """Selector list."""
+
+    __slots__ = ("selectors", "is_not", "is_html", "_hash")
+
+    def __init__(self, selectors=tuple(), is_not=False, is_html=False):
+        """Initialize."""
+
+        super(SelectorList, self).__init__(
+            selectors=tuple(selectors),
+            is_not=is_not,
+            is_html=is_html
+        )
+
+    def __iter__(self):
+        """Iterator."""
+
+        return iter(self.selectors)
+
+    def __len__(self):
+        """Length."""
+
+        return len(self.selectors)
+
+    def __getitem__(self, index):
+        """Get item."""
+
+        return self.selectors[index]
+
+
+def _pickle(p):
+    return p.__base__(), tuple([getattr(p, s) for s in p.__slots__[:-1]])
+
+
+def pickle_register(obj):
+    """Allow object to be pickled."""
+
+    util.copyreg.pickle(obj, _pickle)
+
+
+pickle_register(Selector)
+pickle_register(NullSelector)
+pickle_register(SelectorTag)
+pickle_register(SelectorAttribute)
+pickle_register(SelectorNth)
+pickle_register(SelectorLang)
+pickle_register(SelectorList)
diff --git a/ext/soupsieve/util.py b/ext/soupsieve/util.py
new file mode 100644
index 0000000000..260965c07a
--- /dev/null
+++ b/ext/soupsieve/util.py
@@ -0,0 +1,156 @@
+"""Utility."""
+from __future__ import unicode_literals
+from functools import wraps
+import warnings
+import sys
+import struct
+
+PY3 = sys.version_info >= (3, 0)
+
+if PY3:
+    from functools import lru_cache  # noqa F401
+    import copyreg  # noqa F401
+    from collections.abc import Hashable, Mapping  # noqa F401
+
+    ustr = str  # noqa
+    bstr = bytes  # noqa
+    unichar = chr  # noqa
+    string = str  # noqa
+else:
+    from backports.functools_lru_cache import lru_cache  # noqa F401
+    import copy_reg as copyreg  # noqa F401
+    from collections import Hashable, Mapping  # noqa F401
+
+    ustr = unicode  # noqa
+    bstr = str  # noqa
+    unichar = unichr  # noqa
+    string = basestring  # noqa
+
+DEBUG = 0x10000
+
+LC_A = ord('a')
+LC_Z = ord('z')
+UC_A = ord('A')
+UC_Z = ord('Z')
+
+
+def is_doc(obj):
+    """Is `BeautifulSoup` object."""
+
+    import bs4
+    return isinstance(obj, bs4.BeautifulSoup)
+
+
+def is_tag(obj):
+    """Is tag."""
+
+    import bs4
+    return isinstance(obj, bs4.Tag)
+
+
+def is_comment(obj):
+    """Is comment."""
+
+    import bs4
+    return isinstance(obj, bs4.Comment)
+
+
+def is_declaration(obj):  # pragma: no cover
+    """Is declaration."""
+
+    import bs4
+    return isinstance(obj, bs4.Declaration)
+
+
+def is_cdata(obj):  # pragma: no cover
+    """Is CDATA."""
+
+    import bs4
+    return isinstance(obj, bs4.Declaration)
+
+
+def is_processing_instruction(obj):  # pragma: no cover
+    """Is processing instruction."""
+
+    import bs4
+    return isinstance(obj, bs4.ProcessingInstruction)
+
+
+def is_navigable_string(obj):
+    """Is navigable string."""
+
+    import bs4
+    return isinstance(obj, bs4.NavigableString)
+
+
+def is_special_string(obj):
+    """Is special string."""
+
+    import bs4
+    return isinstance(obj, (bs4.Comment, bs4.Declaration, bs4.CData, bs4.ProcessingInstruction))
+
+
+def get_navigable_string_type(obj):
+    """Get navigable string type."""
+
+    import bs4
+    return bs4.NavigableString
+
+
+def lower(string):
+    """Lower."""
+
+    new_string = []
+    for c in string:
+        o = ord(c)
+        new_string.append(chr(o + 32) if UC_A <= o <= UC_Z else c)
+    return ''.join(new_string)
+
+
+def upper(string):  # pragma: no cover
+    """Lower."""
+
+    new_string = []
+    for c in string:
+        o = ord(c)
+        new_string.append(chr(o - 32) if LC_A <= o <= LC_Z else c)
+    return ''.join(new_string)
+
+
+def uchr(i):
+    """Allow getting Unicode character on narrow python builds."""
+
+    try:
+        return unichar(i)
+    except ValueError:  # pragma: no cover
+        return struct.pack('i', i).decode('utf-32')
+
+
+def deprecated(message, stacklevel=2):  # pragma: no cover
+    """
+    Raise a `DeprecationWarning` when wrapped function/method is called.
+
+    Borrowed from https://stackoverflow.com/a/48632082/866026
+    """
+
+    def _decorator(func):
+        @wraps(func)
+        def _func(*args, **kwargs):
+            warnings.warn(
+                "'{}' is deprecated. {}".format(func.__name__, message),
+                category=DeprecationWarning,
+                stacklevel=stacklevel
+            )
+            return func(*args, **kwargs)
+        return _func
+    return _decorator
+
+
+def warn_deprecated(message, stacklevel=2):  # pragma: no cover
+    """Warn deprecated."""
+
+    warnings.warn(
+        message,
+        category=DeprecationWarning,
+        stacklevel=stacklevel
+    )
diff --git a/ext/subliminal/subtitle.py b/ext/subliminal/subtitle.py
index 6578f4ca6f..031ddf6da1 100644
--- a/ext/subliminal/subtitle.py
+++ b/ext/subliminal/subtitle.py
@@ -10,6 +10,7 @@
 from .video import Episode, Movie
 from .utils import sanitize, sanitize_release_group
 
+from six import text_type
 
 logger = logging.getLogger(__name__)
 
@@ -70,10 +71,12 @@ def text(self):
         if not self.content:
             return
 
-        if self.encoding:
-            return self.content.decode(self.encoding, errors='replace')
+        if not isinstance(self.content, text_type):
+            if self.encoding:
+                return self.content.decode(self.encoding, errors='replace')
+            return self.content.decode(self.guess_encoding(), errors='replace')
 
-        return self.content.decode(self.guess_encoding(), errors='replace')
+        return self.content
 
     def is_valid(self):
         """Check if a :attr:`text` is a valid SubRip format.
diff --git a/ext/urllib3/__init__.py b/ext/urllib3/__init__.py
index 4bd533b5b4..148a9c31a7 100644
--- a/ext/urllib3/__init__.py
+++ b/ext/urllib3/__init__.py
@@ -23,16 +23,11 @@
 
 # Set default logging handler to avoid "No handler found" warnings.
 import logging
-try:  # Python 2.7+
-    from logging import NullHandler
-except ImportError:
-    class NullHandler(logging.Handler):
-        def emit(self, record):
-            pass
+from logging import NullHandler
 
 __author__ = 'Andrey Petrov (andrey.petrov@shazow.net)'
 __license__ = 'MIT'
-__version__ = '1.23'
+__version__ = '1.24.1'
 
 __all__ = (
     'HTTPConnectionPool',
diff --git a/ext/urllib3/_collections.py b/ext/urllib3/_collections.py
index 6e36b84e59..34f23811c6 100644
--- a/ext/urllib3/_collections.py
+++ b/ext/urllib3/_collections.py
@@ -14,10 +14,7 @@ def __exit__(self, exc_type, exc_value, traceback):
             pass
 
 
-try:  # Python 2.7+
-    from collections import OrderedDict
-except ImportError:
-    from .packages.ordered_dict import OrderedDict
+from collections import OrderedDict
 from .exceptions import InvalidHeader
 from .packages.six import iterkeys, itervalues, PY3
 
diff --git a/ext/urllib3/connection.py b/ext/urllib3/connection.py
index a03b573f01..02b36654bd 100644
--- a/ext/urllib3/connection.py
+++ b/ext/urllib3/connection.py
@@ -2,7 +2,6 @@
 import datetime
 import logging
 import os
-import sys
 import socket
 from socket import error as SocketError, timeout as SocketTimeout
 import warnings
@@ -78,9 +77,6 @@ class HTTPConnection(_HTTPConnection, object):
 
       - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool`
       - ``source_address``: Set the source address for the current connection.
-
-        .. note:: This is ignored for Python 2.6. It is only applied for 2.7 and 3.x
-
       - ``socket_options``: Set specific options on the underlying socket. If not specified, then
         defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling
         Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy.
@@ -108,21 +104,13 @@ def __init__(self, *args, **kw):
         if six.PY3:  # Python 3
             kw.pop('strict', None)
 
-        # Pre-set source_address in case we have an older Python like 2.6.
+        # Pre-set source_address.
         self.source_address = kw.get('source_address')
 
-        if sys.version_info < (2, 7):  # Python 2.6
-            # _HTTPConnection on Python 2.6 will balk at this keyword arg, but
-            # not newer versions. We can still use it when creating a
-            # connection though, so we pop it *after* we have saved it as
-            # self.source_address.
-            kw.pop('source_address', None)
-
         #: The socket options provided by the user. If no options are
         #: provided, we use the default options.
         self.socket_options = kw.pop('socket_options', self.default_socket_options)
 
-        # Superclass also sets self.source_address in Python 2.7+.
         _HTTPConnection.__init__(self, *args, **kw)
 
     @property
@@ -183,10 +171,7 @@ def _new_conn(self):
 
     def _prepare_conn(self, conn):
         self.sock = conn
-        # the _tunnel_host attribute was added in python 2.6.3 (via
-        # http://hg.python.org/cpython/rev/0f57b30a152f) so pythons 2.6(0-2) do
-        # not have them.
-        if getattr(self, '_tunnel_host', None):
+        if self._tunnel_host:
             # TODO: Fix tunnel so it doesn't depend on self.sock state.
             self._tunnel()
             # Mark this connection as not reusable
@@ -217,13 +202,13 @@ def request_chunked(self, method, url, body=None, headers=None):
         self.endheaders()
 
         if body is not None:
-            stringish_types = six.string_types + (six.binary_type,)
+            stringish_types = six.string_types + (bytes,)
             if isinstance(body, stringish_types):
                 body = (body,)
             for chunk in body:
                 if not chunk:
                     continue
-                if not isinstance(chunk, six.binary_type):
+                if not isinstance(chunk, bytes):
                     chunk = chunk.encode('utf8')
                 len_str = hex(len(chunk))[2:]
                 self.send(len_str.encode('utf-8'))
@@ -242,7 +227,7 @@ class HTTPSConnection(HTTPConnection):
 
     def __init__(self, host, port=None, key_file=None, cert_file=None,
                  strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
-                 ssl_context=None, **kw):
+                 ssl_context=None, server_hostname=None, **kw):
 
         HTTPConnection.__init__(self, host, port, strict=strict,
                                 timeout=timeout, **kw)
@@ -250,6 +235,7 @@ def __init__(self, host, port=None, key_file=None, cert_file=None,
         self.key_file = key_file
         self.cert_file = cert_file
         self.ssl_context = ssl_context
+        self.server_hostname = server_hostname
 
         # Required property for Google AppEngine 1.9.0 which otherwise causes
         # HTTPS requests to go out as HTTP. (See Issue #356)
@@ -270,6 +256,7 @@ def connect(self):
             keyfile=self.key_file,
             certfile=self.cert_file,
             ssl_context=self.ssl_context,
+            server_hostname=self.server_hostname
         )
 
 
@@ -312,12 +299,9 @@ def set_cert(self, key_file=None, cert_file=None,
     def connect(self):
         # Add certificate verification
         conn = self._new_conn()
-
         hostname = self.host
-        if getattr(self, '_tunnel_host', None):
-            # _tunnel_host was added in Python 2.6.3
-            # (See: http://hg.python.org/cpython/rev/0f57b30a152f)
 
+        if self._tunnel_host:
             self.sock = conn
             # Calls self._set_hostport(), so self.host is
             # self._tunnel_host below.
@@ -328,6 +312,10 @@ def connect(self):
             # Override the host with the one we're requesting data from.
             hostname = self._tunnel_host
 
+        server_hostname = hostname
+        if self.server_hostname is not None:
+            server_hostname = self.server_hostname
+
         is_time_off = datetime.date.today() < RECENT_DATE
         if is_time_off:
             warnings.warn((
@@ -352,7 +340,7 @@ def connect(self):
             certfile=self.cert_file,
             ca_certs=self.ca_certs,
             ca_cert_dir=self.ca_cert_dir,
-            server_hostname=hostname,
+            server_hostname=server_hostname,
             ssl_context=context)
 
         if self.assert_fingerprint:
@@ -373,7 +361,7 @@ def connect(self):
                     'for details.)'.format(hostname)),
                     SubjectAltNameWarning
                 )
-            _match_hostname(cert, self.assert_hostname or hostname)
+            _match_hostname(cert, self.assert_hostname or server_hostname)
 
         self.is_verified = (
             context.verify_mode == ssl.CERT_REQUIRED or
diff --git a/ext/urllib3/connectionpool.py b/ext/urllib3/connectionpool.py
index 8fcb0bce79..f7a8f193d1 100644
--- a/ext/urllib3/connectionpool.py
+++ b/ext/urllib3/connectionpool.py
@@ -89,7 +89,7 @@ def close(self):
 
 
 # This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252
-_blocking_errnos = set([errno.EAGAIN, errno.EWOULDBLOCK])
+_blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK}
 
 
 class HTTPConnectionPool(ConnectionPool, RequestMethods):
@@ -313,7 +313,7 @@ def _raise_timeout(self, err, url, timeout_value):
         # Catch possible read timeouts thrown as SSL errors. If not the
         # case, rethrow the original. We need to do this because of:
         # http://bugs.python.org/issue10272
-        if 'timed out' in str(err) or 'did not complete (read)' in str(err):  # Python 2.6
+        if 'timed out' in str(err) or 'did not complete (read)' in str(err):  # Python < 2.7.4
             raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
 
     def _make_request(self, conn, method, url, timeout=_Default, chunked=False,
@@ -375,7 +375,7 @@ def _make_request(self, conn, method, url, timeout=_Default, chunked=False,
         try:
             try:  # Python 2.7, use buffering of HTTP responses
                 httplib_response = conn.getresponse(buffering=True)
-            except TypeError:  # Python 2.6 and older, Python 3
+            except TypeError:  # Python 3
                 try:
                     httplib_response = conn.getresponse()
                 except Exception as e:
@@ -801,17 +801,7 @@ def _prepare_proxy(self, conn):
         Establish tunnel connection early, because otherwise httplib
         would improperly set Host: header to proxy's IP:port.
         """
-        # Python 2.7+
-        try:
-            set_tunnel = conn.set_tunnel
-        except AttributeError:  # Platform-specific: Python 2.6
-            set_tunnel = conn._set_tunnel
-
-        if sys.version_info <= (2, 6, 4) and not self.proxy_headers:  # Python 2.6.4 and older
-            set_tunnel(self._proxy_host, self.port)
-        else:
-            set_tunnel(self._proxy_host, self.port, self.proxy_headers)
-
+        conn.set_tunnel(self._proxy_host, self.port, self.proxy_headers)
         conn.connect()
 
     def _new_conn(self):
diff --git a/ext/urllib3/contrib/__init__.py b/ext/urllib3/contrib/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/ext/urllib3/contrib/_appengine_environ.py b/ext/urllib3/contrib/_appengine_environ.py
new file mode 100644
index 0000000000..f3e00942cb
--- /dev/null
+++ b/ext/urllib3/contrib/_appengine_environ.py
@@ -0,0 +1,30 @@
+"""
+This module provides means to detect the App Engine environment.
+"""
+
+import os
+
+
+def is_appengine():
+    return (is_local_appengine() or
+            is_prod_appengine() or
+            is_prod_appengine_mvms())
+
+
+def is_appengine_sandbox():
+    return is_appengine() and not is_prod_appengine_mvms()
+
+
+def is_local_appengine():
+    return ('APPENGINE_RUNTIME' in os.environ and
+            'Development/' in os.environ['SERVER_SOFTWARE'])
+
+
+def is_prod_appengine():
+    return ('APPENGINE_RUNTIME' in os.environ and
+            'Google App Engine/' in os.environ['SERVER_SOFTWARE'] and
+            not is_prod_appengine_mvms())
+
+
+def is_prod_appengine_mvms():
+    return os.environ.get('GAE_VM', False) == 'true'
diff --git a/ext/urllib3/contrib/_securetransport/__init__.py b/ext/urllib3/contrib/_securetransport/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/ext/urllib3/contrib/_securetransport/bindings.py b/ext/urllib3/contrib/_securetransport/bindings.py
new file mode 100644
index 0000000000..bcf41c02b2
--- /dev/null
+++ b/ext/urllib3/contrib/_securetransport/bindings.py
@@ -0,0 +1,593 @@
+"""
+This module uses ctypes to bind a whole bunch of functions and constants from
+SecureTransport. The goal here is to provide the low-level API to
+SecureTransport. These are essentially the C-level functions and constants, and
+they're pretty gross to work with.
+
+This code is a bastardised version of the code found in Will Bond's oscrypto
+library. An enormous debt is owed to him for blazing this trail for us. For
+that reason, this code should be considered to be covered both by urllib3's
+license and by oscrypto's:
+
+    Copyright (c) 2015-2016 Will Bond 
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the "Software"),
+    to deal in the Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+    and/or sell copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import absolute_import
+
+import platform
+from ctypes.util import find_library
+from ctypes import (
+    c_void_p, c_int32, c_char_p, c_size_t, c_byte, c_uint32, c_ulong, c_long,
+    c_bool
+)
+from ctypes import CDLL, POINTER, CFUNCTYPE
+
+
+security_path = find_library('Security')
+if not security_path:
+    raise ImportError('The library Security could not be found')
+
+
+core_foundation_path = find_library('CoreFoundation')
+if not core_foundation_path:
+    raise ImportError('The library CoreFoundation could not be found')
+
+
+version = platform.mac_ver()[0]
+version_info = tuple(map(int, version.split('.')))
+if version_info < (10, 8):
+    raise OSError(
+        'Only OS X 10.8 and newer are supported, not %s.%s' % (
+            version_info[0], version_info[1]
+        )
+    )
+
+Security = CDLL(security_path, use_errno=True)
+CoreFoundation = CDLL(core_foundation_path, use_errno=True)
+
+Boolean = c_bool
+CFIndex = c_long
+CFStringEncoding = c_uint32
+CFData = c_void_p
+CFString = c_void_p
+CFArray = c_void_p
+CFMutableArray = c_void_p
+CFDictionary = c_void_p
+CFError = c_void_p
+CFType = c_void_p
+CFTypeID = c_ulong
+
+CFTypeRef = POINTER(CFType)
+CFAllocatorRef = c_void_p
+
+OSStatus = c_int32
+
+CFDataRef = POINTER(CFData)
+CFStringRef = POINTER(CFString)
+CFArrayRef = POINTER(CFArray)
+CFMutableArrayRef = POINTER(CFMutableArray)
+CFDictionaryRef = POINTER(CFDictionary)
+CFArrayCallBacks = c_void_p
+CFDictionaryKeyCallBacks = c_void_p
+CFDictionaryValueCallBacks = c_void_p
+
+SecCertificateRef = POINTER(c_void_p)
+SecExternalFormat = c_uint32
+SecExternalItemType = c_uint32
+SecIdentityRef = POINTER(c_void_p)
+SecItemImportExportFlags = c_uint32
+SecItemImportExportKeyParameters = c_void_p
+SecKeychainRef = POINTER(c_void_p)
+SSLProtocol = c_uint32
+SSLCipherSuite = c_uint32
+SSLContextRef = POINTER(c_void_p)
+SecTrustRef = POINTER(c_void_p)
+SSLConnectionRef = c_uint32
+SecTrustResultType = c_uint32
+SecTrustOptionFlags = c_uint32
+SSLProtocolSide = c_uint32
+SSLConnectionType = c_uint32
+SSLSessionOption = c_uint32
+
+
+try:
+    Security.SecItemImport.argtypes = [
+        CFDataRef,
+        CFStringRef,
+        POINTER(SecExternalFormat),
+        POINTER(SecExternalItemType),
+        SecItemImportExportFlags,
+        POINTER(SecItemImportExportKeyParameters),
+        SecKeychainRef,
+        POINTER(CFArrayRef),
+    ]
+    Security.SecItemImport.restype = OSStatus
+
+    Security.SecCertificateGetTypeID.argtypes = []
+    Security.SecCertificateGetTypeID.restype = CFTypeID
+
+    Security.SecIdentityGetTypeID.argtypes = []
+    Security.SecIdentityGetTypeID.restype = CFTypeID
+
+    Security.SecKeyGetTypeID.argtypes = []
+    Security.SecKeyGetTypeID.restype = CFTypeID
+
+    Security.SecCertificateCreateWithData.argtypes = [
+        CFAllocatorRef,
+        CFDataRef
+    ]
+    Security.SecCertificateCreateWithData.restype = SecCertificateRef
+
+    Security.SecCertificateCopyData.argtypes = [
+        SecCertificateRef
+    ]
+    Security.SecCertificateCopyData.restype = CFDataRef
+
+    Security.SecCopyErrorMessageString.argtypes = [
+        OSStatus,
+        c_void_p
+    ]
+    Security.SecCopyErrorMessageString.restype = CFStringRef
+
+    Security.SecIdentityCreateWithCertificate.argtypes = [
+        CFTypeRef,
+        SecCertificateRef,
+        POINTER(SecIdentityRef)
+    ]
+    Security.SecIdentityCreateWithCertificate.restype = OSStatus
+
+    Security.SecKeychainCreate.argtypes = [
+        c_char_p,
+        c_uint32,
+        c_void_p,
+        Boolean,
+        c_void_p,
+        POINTER(SecKeychainRef)
+    ]
+    Security.SecKeychainCreate.restype = OSStatus
+
+    Security.SecKeychainDelete.argtypes = [
+        SecKeychainRef
+    ]
+    Security.SecKeychainDelete.restype = OSStatus
+
+    Security.SecPKCS12Import.argtypes = [
+        CFDataRef,
+        CFDictionaryRef,
+        POINTER(CFArrayRef)
+    ]
+    Security.SecPKCS12Import.restype = OSStatus
+
+    SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t))
+    SSLWriteFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t))
+
+    Security.SSLSetIOFuncs.argtypes = [
+        SSLContextRef,
+        SSLReadFunc,
+        SSLWriteFunc
+    ]
+    Security.SSLSetIOFuncs.restype = OSStatus
+
+    Security.SSLSetPeerID.argtypes = [
+        SSLContextRef,
+        c_char_p,
+        c_size_t
+    ]
+    Security.SSLSetPeerID.restype = OSStatus
+
+    Security.SSLSetCertificate.argtypes = [
+        SSLContextRef,
+        CFArrayRef
+    ]
+    Security.SSLSetCertificate.restype = OSStatus
+
+    Security.SSLSetCertificateAuthorities.argtypes = [
+        SSLContextRef,
+        CFTypeRef,
+        Boolean
+    ]
+    Security.SSLSetCertificateAuthorities.restype = OSStatus
+
+    Security.SSLSetConnection.argtypes = [
+        SSLContextRef,
+        SSLConnectionRef
+    ]
+    Security.SSLSetConnection.restype = OSStatus
+
+    Security.SSLSetPeerDomainName.argtypes = [
+        SSLContextRef,
+        c_char_p,
+        c_size_t
+    ]
+    Security.SSLSetPeerDomainName.restype = OSStatus
+
+    Security.SSLHandshake.argtypes = [
+        SSLContextRef
+    ]
+    Security.SSLHandshake.restype = OSStatus
+
+    Security.SSLRead.argtypes = [
+        SSLContextRef,
+        c_char_p,
+        c_size_t,
+        POINTER(c_size_t)
+    ]
+    Security.SSLRead.restype = OSStatus
+
+    Security.SSLWrite.argtypes = [
+        SSLContextRef,
+        c_char_p,
+        c_size_t,
+        POINTER(c_size_t)
+    ]
+    Security.SSLWrite.restype = OSStatus
+
+    Security.SSLClose.argtypes = [
+        SSLContextRef
+    ]
+    Security.SSLClose.restype = OSStatus
+
+    Security.SSLGetNumberSupportedCiphers.argtypes = [
+        SSLContextRef,
+        POINTER(c_size_t)
+    ]
+    Security.SSLGetNumberSupportedCiphers.restype = OSStatus
+
+    Security.SSLGetSupportedCiphers.argtypes = [
+        SSLContextRef,
+        POINTER(SSLCipherSuite),
+        POINTER(c_size_t)
+    ]
+    Security.SSLGetSupportedCiphers.restype = OSStatus
+
+    Security.SSLSetEnabledCiphers.argtypes = [
+        SSLContextRef,
+        POINTER(SSLCipherSuite),
+        c_size_t
+    ]
+    Security.SSLSetEnabledCiphers.restype = OSStatus
+
+    Security.SSLGetNumberEnabledCiphers.argtype = [
+        SSLContextRef,
+        POINTER(c_size_t)
+    ]
+    Security.SSLGetNumberEnabledCiphers.restype = OSStatus
+
+    Security.SSLGetEnabledCiphers.argtypes = [
+        SSLContextRef,
+        POINTER(SSLCipherSuite),
+        POINTER(c_size_t)
+    ]
+    Security.SSLGetEnabledCiphers.restype = OSStatus
+
+    Security.SSLGetNegotiatedCipher.argtypes = [
+        SSLContextRef,
+        POINTER(SSLCipherSuite)
+    ]
+    Security.SSLGetNegotiatedCipher.restype = OSStatus
+
+    Security.SSLGetNegotiatedProtocolVersion.argtypes = [
+        SSLContextRef,
+        POINTER(SSLProtocol)
+    ]
+    Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus
+
+    Security.SSLCopyPeerTrust.argtypes = [
+        SSLContextRef,
+        POINTER(SecTrustRef)
+    ]
+    Security.SSLCopyPeerTrust.restype = OSStatus
+
+    Security.SecTrustSetAnchorCertificates.argtypes = [
+        SecTrustRef,
+        CFArrayRef
+    ]
+    Security.SecTrustSetAnchorCertificates.restype = OSStatus
+
+    Security.SecTrustSetAnchorCertificatesOnly.argstypes = [
+        SecTrustRef,
+        Boolean
+    ]
+    Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus
+
+    Security.SecTrustEvaluate.argtypes = [
+        SecTrustRef,
+        POINTER(SecTrustResultType)
+    ]
+    Security.SecTrustEvaluate.restype = OSStatus
+
+    Security.SecTrustGetCertificateCount.argtypes = [
+        SecTrustRef
+    ]
+    Security.SecTrustGetCertificateCount.restype = CFIndex
+
+    Security.SecTrustGetCertificateAtIndex.argtypes = [
+        SecTrustRef,
+        CFIndex
+    ]
+    Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef
+
+    Security.SSLCreateContext.argtypes = [
+        CFAllocatorRef,
+        SSLProtocolSide,
+        SSLConnectionType
+    ]
+    Security.SSLCreateContext.restype = SSLContextRef
+
+    Security.SSLSetSessionOption.argtypes = [
+        SSLContextRef,
+        SSLSessionOption,
+        Boolean
+    ]
+    Security.SSLSetSessionOption.restype = OSStatus
+
+    Security.SSLSetProtocolVersionMin.argtypes = [
+        SSLContextRef,
+        SSLProtocol
+    ]
+    Security.SSLSetProtocolVersionMin.restype = OSStatus
+
+    Security.SSLSetProtocolVersionMax.argtypes = [
+        SSLContextRef,
+        SSLProtocol
+    ]
+    Security.SSLSetProtocolVersionMax.restype = OSStatus
+
+    Security.SecCopyErrorMessageString.argtypes = [
+        OSStatus,
+        c_void_p
+    ]
+    Security.SecCopyErrorMessageString.restype = CFStringRef
+
+    Security.SSLReadFunc = SSLReadFunc
+    Security.SSLWriteFunc = SSLWriteFunc
+    Security.SSLContextRef = SSLContextRef
+    Security.SSLProtocol = SSLProtocol
+    Security.SSLCipherSuite = SSLCipherSuite
+    Security.SecIdentityRef = SecIdentityRef
+    Security.SecKeychainRef = SecKeychainRef
+    Security.SecTrustRef = SecTrustRef
+    Security.SecTrustResultType = SecTrustResultType
+    Security.SecExternalFormat = SecExternalFormat
+    Security.OSStatus = OSStatus
+
+    Security.kSecImportExportPassphrase = CFStringRef.in_dll(
+        Security, 'kSecImportExportPassphrase'
+    )
+    Security.kSecImportItemIdentity = CFStringRef.in_dll(
+        Security, 'kSecImportItemIdentity'
+    )
+
+    # CoreFoundation time!
+    CoreFoundation.CFRetain.argtypes = [
+        CFTypeRef
+    ]
+    CoreFoundation.CFRetain.restype = CFTypeRef
+
+    CoreFoundation.CFRelease.argtypes = [
+        CFTypeRef
+    ]
+    CoreFoundation.CFRelease.restype = None
+
+    CoreFoundation.CFGetTypeID.argtypes = [
+        CFTypeRef
+    ]
+    CoreFoundation.CFGetTypeID.restype = CFTypeID
+
+    CoreFoundation.CFStringCreateWithCString.argtypes = [
+        CFAllocatorRef,
+        c_char_p,
+        CFStringEncoding
+    ]
+    CoreFoundation.CFStringCreateWithCString.restype = CFStringRef
+
+    CoreFoundation.CFStringGetCStringPtr.argtypes = [
+        CFStringRef,
+        CFStringEncoding
+    ]
+    CoreFoundation.CFStringGetCStringPtr.restype = c_char_p
+
+    CoreFoundation.CFStringGetCString.argtypes = [
+        CFStringRef,
+        c_char_p,
+        CFIndex,
+        CFStringEncoding
+    ]
+    CoreFoundation.CFStringGetCString.restype = c_bool
+
+    CoreFoundation.CFDataCreate.argtypes = [
+        CFAllocatorRef,
+        c_char_p,
+        CFIndex
+    ]
+    CoreFoundation.CFDataCreate.restype = CFDataRef
+
+    CoreFoundation.CFDataGetLength.argtypes = [
+        CFDataRef
+    ]
+    CoreFoundation.CFDataGetLength.restype = CFIndex
+
+    CoreFoundation.CFDataGetBytePtr.argtypes = [
+        CFDataRef
+    ]
+    CoreFoundation.CFDataGetBytePtr.restype = c_void_p
+
+    CoreFoundation.CFDictionaryCreate.argtypes = [
+        CFAllocatorRef,
+        POINTER(CFTypeRef),
+        POINTER(CFTypeRef),
+        CFIndex,
+        CFDictionaryKeyCallBacks,
+        CFDictionaryValueCallBacks
+    ]
+    CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef
+
+    CoreFoundation.CFDictionaryGetValue.argtypes = [
+        CFDictionaryRef,
+        CFTypeRef
+    ]
+    CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef
+
+    CoreFoundation.CFArrayCreate.argtypes = [
+        CFAllocatorRef,
+        POINTER(CFTypeRef),
+        CFIndex,
+        CFArrayCallBacks,
+    ]
+    CoreFoundation.CFArrayCreate.restype = CFArrayRef
+
+    CoreFoundation.CFArrayCreateMutable.argtypes = [
+        CFAllocatorRef,
+        CFIndex,
+        CFArrayCallBacks
+    ]
+    CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef
+
+    CoreFoundation.CFArrayAppendValue.argtypes = [
+        CFMutableArrayRef,
+        c_void_p
+    ]
+    CoreFoundation.CFArrayAppendValue.restype = None
+
+    CoreFoundation.CFArrayGetCount.argtypes = [
+        CFArrayRef
+    ]
+    CoreFoundation.CFArrayGetCount.restype = CFIndex
+
+    CoreFoundation.CFArrayGetValueAtIndex.argtypes = [
+        CFArrayRef,
+        CFIndex
+    ]
+    CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p
+
+    CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll(
+        CoreFoundation, 'kCFAllocatorDefault'
+    )
+    CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll(CoreFoundation, 'kCFTypeArrayCallBacks')
+    CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll(
+        CoreFoundation, 'kCFTypeDictionaryKeyCallBacks'
+    )
+    CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll(
+        CoreFoundation, 'kCFTypeDictionaryValueCallBacks'
+    )
+
+    CoreFoundation.CFTypeRef = CFTypeRef
+    CoreFoundation.CFArrayRef = CFArrayRef
+    CoreFoundation.CFStringRef = CFStringRef
+    CoreFoundation.CFDictionaryRef = CFDictionaryRef
+
+except (AttributeError):
+    raise ImportError('Error initializing ctypes')
+
+
+class CFConst(object):
+    """
+    A class object that acts as essentially a namespace for CoreFoundation
+    constants.
+    """
+    kCFStringEncodingUTF8 = CFStringEncoding(0x08000100)
+
+
+class SecurityConst(object):
+    """
+    A class object that acts as essentially a namespace for Security constants.
+    """
+    kSSLSessionOptionBreakOnServerAuth = 0
+
+    kSSLProtocol2 = 1
+    kSSLProtocol3 = 2
+    kTLSProtocol1 = 4
+    kTLSProtocol11 = 7
+    kTLSProtocol12 = 8
+
+    kSSLClientSide = 1
+    kSSLStreamType = 0
+
+    kSecFormatPEMSequence = 10
+
+    kSecTrustResultInvalid = 0
+    kSecTrustResultProceed = 1
+    # This gap is present on purpose: this was kSecTrustResultConfirm, which
+    # is deprecated.
+    kSecTrustResultDeny = 3
+    kSecTrustResultUnspecified = 4
+    kSecTrustResultRecoverableTrustFailure = 5
+    kSecTrustResultFatalTrustFailure = 6
+    kSecTrustResultOtherError = 7
+
+    errSSLProtocol = -9800
+    errSSLWouldBlock = -9803
+    errSSLClosedGraceful = -9805
+    errSSLClosedNoNotify = -9816
+    errSSLClosedAbort = -9806
+
+    errSSLXCertChainInvalid = -9807
+    errSSLCrypto = -9809
+    errSSLInternal = -9810
+    errSSLCertExpired = -9814
+    errSSLCertNotYetValid = -9815
+    errSSLUnknownRootCert = -9812
+    errSSLNoRootCert = -9813
+    errSSLHostNameMismatch = -9843
+    errSSLPeerHandshakeFail = -9824
+    errSSLPeerUserCancelled = -9839
+    errSSLWeakPeerEphemeralDHKey = -9850
+    errSSLServerAuthCompleted = -9841
+    errSSLRecordOverflow = -9847
+
+    errSecVerifyFailed = -67808
+    errSecNoTrustSettings = -25263
+    errSecItemNotFound = -25300
+    errSecInvalidTrustSettings = -25262
+
+    # Cipher suites. We only pick the ones our default cipher string allows.
+    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C
+    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030
+    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B
+    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F
+    TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3
+    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F
+    TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2
+    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E
+    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024
+    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028
+    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A
+    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B
+    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039
+    TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067
+    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033
+    TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032
+    TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D
+    TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C
+    TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D
+    TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C
+    TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035
+    TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F
+    TLS_AES_128_GCM_SHA256 = 0x1301
+    TLS_AES_256_GCM_SHA384 = 0x1302
+    TLS_CHACHA20_POLY1305_SHA256 = 0x1303
diff --git a/ext/urllib3/contrib/_securetransport/low_level.py b/ext/urllib3/contrib/_securetransport/low_level.py
new file mode 100644
index 0000000000..b13cd9e72c
--- /dev/null
+++ b/ext/urllib3/contrib/_securetransport/low_level.py
@@ -0,0 +1,346 @@
+"""
+Low-level helpers for the SecureTransport bindings.
+
+These are Python functions that are not directly related to the high-level APIs
+but are necessary to get them to work. They include a whole bunch of low-level
+CoreFoundation messing about and memory management. The concerns in this module
+are almost entirely about trying to avoid memory leaks and providing
+appropriate and useful assistance to the higher-level code.
+"""
+import base64
+import ctypes
+import itertools
+import re
+import os
+import ssl
+import tempfile
+
+from .bindings import Security, CoreFoundation, CFConst
+
+
+# This regular expression is used to grab PEM data out of a PEM bundle.
+_PEM_CERTS_RE = re.compile(
+    b"-----BEGIN CERTIFICATE-----\n(.*?)\n-----END CERTIFICATE-----", re.DOTALL
+)
+
+
+def _cf_data_from_bytes(bytestring):
+    """
+    Given a bytestring, create a CFData object from it. This CFData object must
+    be CFReleased by the caller.
+    """
+    return CoreFoundation.CFDataCreate(
+        CoreFoundation.kCFAllocatorDefault, bytestring, len(bytestring)
+    )
+
+
+def _cf_dictionary_from_tuples(tuples):
+    """
+    Given a list of Python tuples, create an associated CFDictionary.
+    """
+    dictionary_size = len(tuples)
+
+    # We need to get the dictionary keys and values out in the same order.
+    keys = (t[0] for t in tuples)
+    values = (t[1] for t in tuples)
+    cf_keys = (CoreFoundation.CFTypeRef * dictionary_size)(*keys)
+    cf_values = (CoreFoundation.CFTypeRef * dictionary_size)(*values)
+
+    return CoreFoundation.CFDictionaryCreate(
+        CoreFoundation.kCFAllocatorDefault,
+        cf_keys,
+        cf_values,
+        dictionary_size,
+        CoreFoundation.kCFTypeDictionaryKeyCallBacks,
+        CoreFoundation.kCFTypeDictionaryValueCallBacks,
+    )
+
+
+def _cf_string_to_unicode(value):
+    """
+    Creates a Unicode string from a CFString object. Used entirely for error
+    reporting.
+
+    Yes, it annoys me quite a lot that this function is this complex.
+    """
+    value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p))
+
+    string = CoreFoundation.CFStringGetCStringPtr(
+        value_as_void_p,
+        CFConst.kCFStringEncodingUTF8
+    )
+    if string is None:
+        buffer = ctypes.create_string_buffer(1024)
+        result = CoreFoundation.CFStringGetCString(
+            value_as_void_p,
+            buffer,
+            1024,
+            CFConst.kCFStringEncodingUTF8
+        )
+        if not result:
+            raise OSError('Error copying C string from CFStringRef')
+        string = buffer.value
+    if string is not None:
+        string = string.decode('utf-8')
+    return string
+
+
+def _assert_no_error(error, exception_class=None):
+    """
+    Checks the return code and throws an exception if there is an error to
+    report
+    """
+    if error == 0:
+        return
+
+    cf_error_string = Security.SecCopyErrorMessageString(error, None)
+    output = _cf_string_to_unicode(cf_error_string)
+    CoreFoundation.CFRelease(cf_error_string)
+
+    if output is None or output == u'':
+        output = u'OSStatus %s' % error
+
+    if exception_class is None:
+        exception_class = ssl.SSLError
+
+    raise exception_class(output)
+
+
+def _cert_array_from_pem(pem_bundle):
+    """
+    Given a bundle of certs in PEM format, turns them into a CFArray of certs
+    that can be used to validate a cert chain.
+    """
+    # Normalize the PEM bundle's line endings.
+    pem_bundle = pem_bundle.replace(b"\r\n", b"\n")
+
+    der_certs = [
+        base64.b64decode(match.group(1))
+        for match in _PEM_CERTS_RE.finditer(pem_bundle)
+    ]
+    if not der_certs:
+        raise ssl.SSLError("No root certificates specified")
+
+    cert_array = CoreFoundation.CFArrayCreateMutable(
+        CoreFoundation.kCFAllocatorDefault,
+        0,
+        ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks)
+    )
+    if not cert_array:
+        raise ssl.SSLError("Unable to allocate memory!")
+
+    try:
+        for der_bytes in der_certs:
+            certdata = _cf_data_from_bytes(der_bytes)
+            if not certdata:
+                raise ssl.SSLError("Unable to allocate memory!")
+            cert = Security.SecCertificateCreateWithData(
+                CoreFoundation.kCFAllocatorDefault, certdata
+            )
+            CoreFoundation.CFRelease(certdata)
+            if not cert:
+                raise ssl.SSLError("Unable to build cert object!")
+
+            CoreFoundation.CFArrayAppendValue(cert_array, cert)
+            CoreFoundation.CFRelease(cert)
+    except Exception:
+        # We need to free the array before the exception bubbles further.
+        # We only want to do that if an error occurs: otherwise, the caller
+        # should free.
+        CoreFoundation.CFRelease(cert_array)
+
+    return cert_array
+
+
+def _is_cert(item):
+    """
+    Returns True if a given CFTypeRef is a certificate.
+    """
+    expected = Security.SecCertificateGetTypeID()
+    return CoreFoundation.CFGetTypeID(item) == expected
+
+
+def _is_identity(item):
+    """
+    Returns True if a given CFTypeRef is an identity.
+    """
+    expected = Security.SecIdentityGetTypeID()
+    return CoreFoundation.CFGetTypeID(item) == expected
+
+
+def _temporary_keychain():
+    """
+    This function creates a temporary Mac keychain that we can use to work with
+    credentials. This keychain uses a one-time password and a temporary file to
+    store the data. We expect to have one keychain per socket. The returned
+    SecKeychainRef must be freed by the caller, including calling
+    SecKeychainDelete.
+
+    Returns a tuple of the SecKeychainRef and the path to the temporary
+    directory that contains it.
+    """
+    # Unfortunately, SecKeychainCreate requires a path to a keychain. This
+    # means we cannot use mkstemp to use a generic temporary file. Instead,
+    # we're going to create a temporary directory and a filename to use there.
+    # This filename will be 8 random bytes expanded into base64. We also need
+    # some random bytes to password-protect the keychain we're creating, so we
+    # ask for 40 random bytes.
+    random_bytes = os.urandom(40)
+    filename = base64.b16encode(random_bytes[:8]).decode('utf-8')
+    password = base64.b16encode(random_bytes[8:])  # Must be valid UTF-8
+    tempdirectory = tempfile.mkdtemp()
+
+    keychain_path = os.path.join(tempdirectory, filename).encode('utf-8')
+
+    # We now want to create the keychain itself.
+    keychain = Security.SecKeychainRef()
+    status = Security.SecKeychainCreate(
+        keychain_path,
+        len(password),
+        password,
+        False,
+        None,
+        ctypes.byref(keychain)
+    )
+    _assert_no_error(status)
+
+    # Having created the keychain, we want to pass it off to the caller.
+    return keychain, tempdirectory
+
+
+def _load_items_from_file(keychain, path):
+    """
+    Given a single file, loads all the trust objects from it into arrays and
+    the keychain.
+    Returns a tuple of lists: the first list is a list of identities, the
+    second a list of certs.
+    """
+    certificates = []
+    identities = []
+    result_array = None
+
+    with open(path, 'rb') as f:
+        raw_filedata = f.read()
+
+    try:
+        filedata = CoreFoundation.CFDataCreate(
+            CoreFoundation.kCFAllocatorDefault,
+            raw_filedata,
+            len(raw_filedata)
+        )
+        result_array = CoreFoundation.CFArrayRef()
+        result = Security.SecItemImport(
+            filedata,  # cert data
+            None,  # Filename, leaving it out for now
+            None,  # What the type of the file is, we don't care
+            None,  # what's in the file, we don't care
+            0,  # import flags
+            None,  # key params, can include passphrase in the future
+            keychain,  # The keychain to insert into
+            ctypes.byref(result_array)  # Results
+        )
+        _assert_no_error(result)
+
+        # A CFArray is not very useful to us as an intermediary
+        # representation, so we are going to extract the objects we want
+        # and then free the array. We don't need to keep hold of keys: the
+        # keychain already has them!
+        result_count = CoreFoundation.CFArrayGetCount(result_array)
+        for index in range(result_count):
+            item = CoreFoundation.CFArrayGetValueAtIndex(
+                result_array, index
+            )
+            item = ctypes.cast(item, CoreFoundation.CFTypeRef)
+
+            if _is_cert(item):
+                CoreFoundation.CFRetain(item)
+                certificates.append(item)
+            elif _is_identity(item):
+                CoreFoundation.CFRetain(item)
+                identities.append(item)
+    finally:
+        if result_array:
+            CoreFoundation.CFRelease(result_array)
+
+        CoreFoundation.CFRelease(filedata)
+
+    return (identities, certificates)
+
+
+def _load_client_cert_chain(keychain, *paths):
+    """
+    Load certificates and maybe keys from a number of files. Has the end goal
+    of returning a CFArray containing one SecIdentityRef, and then zero or more
+    SecCertificateRef objects, suitable for use as a client certificate trust
+    chain.
+    """
+    # Ok, the strategy.
+    #
+    # This relies on knowing that macOS will not give you a SecIdentityRef
+    # unless you have imported a key into a keychain. This is a somewhat
+    # artificial limitation of macOS (for example, it doesn't necessarily
+    # affect iOS), but there is nothing inside Security.framework that lets you
+    # get a SecIdentityRef without having a key in a keychain.
+    #
+    # So the policy here is we take all the files and iterate them in order.
+    # Each one will use SecItemImport to have one or more objects loaded from
+    # it. We will also point at a keychain that macOS can use to work with the
+    # private key.
+    #
+    # Once we have all the objects, we'll check what we actually have. If we
+    # already have a SecIdentityRef in hand, fab: we'll use that. Otherwise,
+    # we'll take the first certificate (which we assume to be our leaf) and
+    # ask the keychain to give us a SecIdentityRef with that cert's associated
+    # key.
+    #
+    # We'll then return a CFArray containing the trust chain: one
+    # SecIdentityRef and then zero-or-more SecCertificateRef objects. The
+    # responsibility for freeing this CFArray will be with the caller. This
+    # CFArray must remain alive for the entire connection, so in practice it
+    # will be stored with a single SSLSocket, along with the reference to the
+    # keychain.
+    certificates = []
+    identities = []
+
+    # Filter out bad paths.
+    paths = (path for path in paths if path)
+
+    try:
+        for file_path in paths:
+            new_identities, new_certs = _load_items_from_file(
+                keychain, file_path
+            )
+            identities.extend(new_identities)
+            certificates.extend(new_certs)
+
+        # Ok, we have everything. The question is: do we have an identity? If
+        # not, we want to grab one from the first cert we have.
+        if not identities:
+            new_identity = Security.SecIdentityRef()
+            status = Security.SecIdentityCreateWithCertificate(
+                keychain,
+                certificates[0],
+                ctypes.byref(new_identity)
+            )
+            _assert_no_error(status)
+            identities.append(new_identity)
+
+            # We now want to release the original certificate, as we no longer
+            # need it.
+            CoreFoundation.CFRelease(certificates.pop(0))
+
+        # We now need to build a new CFArray that holds the trust chain.
+        trust_chain = CoreFoundation.CFArrayCreateMutable(
+            CoreFoundation.kCFAllocatorDefault,
+            0,
+            ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks),
+        )
+        for item in itertools.chain(identities, certificates):
+            # ArrayAppendValue does a CFRetain on the item. That's fine,
+            # because the finally block will release our other refs to them.
+            CoreFoundation.CFArrayAppendValue(trust_chain, item)
+
+        return trust_chain
+    finally:
+        for obj in itertools.chain(identities, certificates):
+            CoreFoundation.CFRelease(obj)
diff --git a/ext/urllib3/contrib/appengine.py b/ext/urllib3/contrib/appengine.py
new file mode 100644
index 0000000000..2952f114df
--- /dev/null
+++ b/ext/urllib3/contrib/appengine.py
@@ -0,0 +1,289 @@
+"""
+This module provides a pool manager that uses Google App Engine's
+`URLFetch Service `_.
+
+Example usage::
+
+    from urllib3 import PoolManager
+    from urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox
+
+    if is_appengine_sandbox():
+        # AppEngineManager uses AppEngine's URLFetch API behind the scenes
+        http = AppEngineManager()
+    else:
+        # PoolManager uses a socket-level API behind the scenes
+        http = PoolManager()
+
+    r = http.request('GET', 'https://google.com/')
+
+There are `limitations `_ to the URLFetch service and it may not be
+the best choice for your application. There are three options for using
+urllib3 on Google App Engine:
+
+1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is
+   cost-effective in many circumstances as long as your usage is within the
+   limitations.
+2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets.
+   Sockets also have `limitations and restrictions
+   `_ and have a lower free quota than URLFetch.
+   To use sockets, be sure to specify the following in your ``app.yaml``::
+
+        env_variables:
+            GAE_USE_SOCKETS_HTTPLIB : 'true'
+
+3. If you are using `App Engine Flexible
+`_, you can use the standard
+:class:`PoolManager` without any configuration or special environment variables.
+"""
+
+from __future__ import absolute_import
+import io
+import logging
+import warnings
+from ..packages.six.moves.urllib.parse import urljoin
+
+from ..exceptions import (
+    HTTPError,
+    HTTPWarning,
+    MaxRetryError,
+    ProtocolError,
+    TimeoutError,
+    SSLError
+)
+
+from ..request import RequestMethods
+from ..response import HTTPResponse
+from ..util.timeout import Timeout
+from ..util.retry import Retry
+from . import _appengine_environ
+
+try:
+    from google.appengine.api import urlfetch
+except ImportError:
+    urlfetch = None
+
+
+log = logging.getLogger(__name__)
+
+
+class AppEnginePlatformWarning(HTTPWarning):
+    pass
+
+
+class AppEnginePlatformError(HTTPError):
+    pass
+
+
+class AppEngineManager(RequestMethods):
+    """
+    Connection manager for Google App Engine sandbox applications.
+
+    This manager uses the URLFetch service directly instead of using the
+    emulated httplib, and is subject to URLFetch limitations as described in
+    the App Engine documentation `here
+    `_.
+
+    Notably it will raise an :class:`AppEnginePlatformError` if:
+        * URLFetch is not available.
+        * If you attempt to use this on App Engine Flexible, as full socket
+          support is available.
+        * If a request size is more than 10 megabytes.
+        * If a response size is more than 32 megabtyes.
+        * If you use an unsupported request method such as OPTIONS.
+
+    Beyond those cases, it will raise normal urllib3 errors.
+    """
+
+    def __init__(self, headers=None, retries=None, validate_certificate=True,
+                 urlfetch_retries=True):
+        if not urlfetch:
+            raise AppEnginePlatformError(
+                "URLFetch is not available in this environment.")
+
+        if is_prod_appengine_mvms():
+            raise AppEnginePlatformError(
+                "Use normal urllib3.PoolManager instead of AppEngineManager"
+                "on Managed VMs, as using URLFetch is not necessary in "
+                "this environment.")
+
+        warnings.warn(
+            "urllib3 is using URLFetch on Google App Engine sandbox instead "
+            "of sockets. To use sockets directly instead of URLFetch see "
+            "https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html.",
+            AppEnginePlatformWarning)
+
+        RequestMethods.__init__(self, headers)
+        self.validate_certificate = validate_certificate
+        self.urlfetch_retries = urlfetch_retries
+
+        self.retries = retries or Retry.DEFAULT
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        # Return False to re-raise any potential exceptions
+        return False
+
+    def urlopen(self, method, url, body=None, headers=None,
+                retries=None, redirect=True, timeout=Timeout.DEFAULT_TIMEOUT,
+                **response_kw):
+
+        retries = self._get_retries(retries, redirect)
+
+        try:
+            follow_redirects = (
+                    redirect and
+                    retries.redirect != 0 and
+                    retries.total)
+            response = urlfetch.fetch(
+                url,
+                payload=body,
+                method=method,
+                headers=headers or {},
+                allow_truncated=False,
+                follow_redirects=self.urlfetch_retries and follow_redirects,
+                deadline=self._get_absolute_timeout(timeout),
+                validate_certificate=self.validate_certificate,
+            )
+        except urlfetch.DeadlineExceededError as e:
+            raise TimeoutError(self, e)
+
+        except urlfetch.InvalidURLError as e:
+            if 'too large' in str(e):
+                raise AppEnginePlatformError(
+                    "URLFetch request too large, URLFetch only "
+                    "supports requests up to 10mb in size.", e)
+            raise ProtocolError(e)
+
+        except urlfetch.DownloadError as e:
+            if 'Too many redirects' in str(e):
+                raise MaxRetryError(self, url, reason=e)
+            raise ProtocolError(e)
+
+        except urlfetch.ResponseTooLargeError as e:
+            raise AppEnginePlatformError(
+                "URLFetch response too large, URLFetch only supports"
+                "responses up to 32mb in size.", e)
+
+        except urlfetch.SSLCertificateError as e:
+            raise SSLError(e)
+
+        except urlfetch.InvalidMethodError as e:
+            raise AppEnginePlatformError(
+                "URLFetch does not support method: %s" % method, e)
+
+        http_response = self._urlfetch_response_to_http_response(
+            response, retries=retries, **response_kw)
+
+        # Handle redirect?
+        redirect_location = redirect and http_response.get_redirect_location()
+        if redirect_location:
+            # Check for redirect response
+            if (self.urlfetch_retries and retries.raise_on_redirect):
+                raise MaxRetryError(self, url, "too many redirects")
+            else:
+                if http_response.status == 303:
+                    method = 'GET'
+
+                try:
+                    retries = retries.increment(method, url, response=http_response, _pool=self)
+                except MaxRetryError:
+                    if retries.raise_on_redirect:
+                        raise MaxRetryError(self, url, "too many redirects")
+                    return http_response
+
+                retries.sleep_for_retry(http_response)
+                log.debug("Redirecting %s -> %s", url, redirect_location)
+                redirect_url = urljoin(url, redirect_location)
+                return self.urlopen(
+                    method, redirect_url, body, headers,
+                    retries=retries, redirect=redirect,
+                    timeout=timeout, **response_kw)
+
+        # Check if we should retry the HTTP response.
+        has_retry_after = bool(http_response.getheader('Retry-After'))
+        if retries.is_retry(method, http_response.status, has_retry_after):
+            retries = retries.increment(
+                method, url, response=http_response, _pool=self)
+            log.debug("Retry: %s", url)
+            retries.sleep(http_response)
+            return self.urlopen(
+                method, url,
+                body=body, headers=headers,
+                retries=retries, redirect=redirect,
+                timeout=timeout, **response_kw)
+
+        return http_response
+
+    def _urlfetch_response_to_http_response(self, urlfetch_resp, **response_kw):
+
+        if is_prod_appengine():
+            # Production GAE handles deflate encoding automatically, but does
+            # not remove the encoding header.
+            content_encoding = urlfetch_resp.headers.get('content-encoding')
+
+            if content_encoding == 'deflate':
+                del urlfetch_resp.headers['content-encoding']
+
+        transfer_encoding = urlfetch_resp.headers.get('transfer-encoding')
+        # We have a full response's content,
+        # so let's make sure we don't report ourselves as chunked data.
+        if transfer_encoding == 'chunked':
+            encodings = transfer_encoding.split(",")
+            encodings.remove('chunked')
+            urlfetch_resp.headers['transfer-encoding'] = ','.join(encodings)
+
+        original_response = HTTPResponse(
+            # In order for decoding to work, we must present the content as
+            # a file-like object.
+            body=io.BytesIO(urlfetch_resp.content),
+            msg=urlfetch_resp.header_msg,
+            headers=urlfetch_resp.headers,
+            status=urlfetch_resp.status_code,
+            **response_kw
+        )
+
+        return HTTPResponse(
+            body=io.BytesIO(urlfetch_resp.content),
+            headers=urlfetch_resp.headers,
+            status=urlfetch_resp.status_code,
+            original_response=original_response,
+            **response_kw
+        )
+
+    def _get_absolute_timeout(self, timeout):
+        if timeout is Timeout.DEFAULT_TIMEOUT:
+            return None  # Defer to URLFetch's default.
+        if isinstance(timeout, Timeout):
+            if timeout._read is not None or timeout._connect is not None:
+                warnings.warn(
+                    "URLFetch does not support granular timeout settings, "
+                    "reverting to total or default URLFetch timeout.",
+                    AppEnginePlatformWarning)
+            return timeout.total
+        return timeout
+
+    def _get_retries(self, retries, redirect):
+        if not isinstance(retries, Retry):
+            retries = Retry.from_int(
+                retries, redirect=redirect, default=self.retries)
+
+        if retries.connect or retries.read or retries.redirect:
+            warnings.warn(
+                "URLFetch only supports total retries and does not "
+                "recognize connect, read, or redirect retry parameters.",
+                AppEnginePlatformWarning)
+
+        return retries
+
+
+# Alias methods from _appengine_environ to maintain public API interface.
+
+is_appengine = _appengine_environ.is_appengine
+is_appengine_sandbox = _appengine_environ.is_appengine_sandbox
+is_local_appengine = _appengine_environ.is_local_appengine
+is_prod_appengine = _appengine_environ.is_prod_appengine
+is_prod_appengine_mvms = _appengine_environ.is_prod_appengine_mvms
diff --git a/ext/urllib3/contrib/ntlmpool.py b/ext/urllib3/contrib/ntlmpool.py
new file mode 100644
index 0000000000..8ea127c583
--- /dev/null
+++ b/ext/urllib3/contrib/ntlmpool.py
@@ -0,0 +1,111 @@
+"""
+NTLM authenticating pool, contributed by erikcederstran
+
+Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10
+"""
+from __future__ import absolute_import
+
+from logging import getLogger
+from ntlm import ntlm
+
+from .. import HTTPSConnectionPool
+from ..packages.six.moves.http_client import HTTPSConnection
+
+
+log = getLogger(__name__)
+
+
+class NTLMConnectionPool(HTTPSConnectionPool):
+    """
+    Implements an NTLM authentication version of an urllib3 connection pool
+    """
+
+    scheme = 'https'
+
+    def __init__(self, user, pw, authurl, *args, **kwargs):
+        """
+        authurl is a random URL on the server that is protected by NTLM.
+        user is the Windows user, probably in the DOMAIN\\username format.
+        pw is the password for the user.
+        """
+        super(NTLMConnectionPool, self).__init__(*args, **kwargs)
+        self.authurl = authurl
+        self.rawuser = user
+        user_parts = user.split('\\', 1)
+        self.domain = user_parts[0].upper()
+        self.user = user_parts[1]
+        self.pw = pw
+
+    def _new_conn(self):
+        # Performs the NTLM handshake that secures the connection. The socket
+        # must be kept open while requests are performed.
+        self.num_connections += 1
+        log.debug('Starting NTLM HTTPS connection no. %d: https://%s%s',
+                  self.num_connections, self.host, self.authurl)
+
+        headers = {'Connection': 'Keep-Alive'}
+        req_header = 'Authorization'
+        resp_header = 'www-authenticate'
+
+        conn = HTTPSConnection(host=self.host, port=self.port)
+
+        # Send negotiation message
+        headers[req_header] = (
+            'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(self.rawuser))
+        log.debug('Request headers: %s', headers)
+        conn.request('GET', self.authurl, None, headers)
+        res = conn.getresponse()
+        reshdr = dict(res.getheaders())
+        log.debug('Response status: %s %s', res.status, res.reason)
+        log.debug('Response headers: %s', reshdr)
+        log.debug('Response data: %s [...]', res.read(100))
+
+        # Remove the reference to the socket, so that it can not be closed by
+        # the response object (we want to keep the socket open)
+        res.fp = None
+
+        # Server should respond with a challenge message
+        auth_header_values = reshdr[resp_header].split(', ')
+        auth_header_value = None
+        for s in auth_header_values:
+            if s[:5] == 'NTLM ':
+                auth_header_value = s[5:]
+        if auth_header_value is None:
+            raise Exception('Unexpected %s response header: %s' %
+                            (resp_header, reshdr[resp_header]))
+
+        # Send authentication message
+        ServerChallenge, NegotiateFlags = \
+            ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value)
+        auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge,
+                                                         self.user,
+                                                         self.domain,
+                                                         self.pw,
+                                                         NegotiateFlags)
+        headers[req_header] = 'NTLM %s' % auth_msg
+        log.debug('Request headers: %s', headers)
+        conn.request('GET', self.authurl, None, headers)
+        res = conn.getresponse()
+        log.debug('Response status: %s %s', res.status, res.reason)
+        log.debug('Response headers: %s', dict(res.getheaders()))
+        log.debug('Response data: %s [...]', res.read()[:100])
+        if res.status != 200:
+            if res.status == 401:
+                raise Exception('Server rejected request: wrong '
+                                'username or password')
+            raise Exception('Wrong server response: %s %s' %
+                            (res.status, res.reason))
+
+        res.fp = None
+        log.debug('Connection established')
+        return conn
+
+    def urlopen(self, method, url, body=None, headers=None, retries=3,
+                redirect=True, assert_same_host=True):
+        if headers is None:
+            headers = {}
+        headers['Connection'] = 'Keep-Alive'
+        return super(NTLMConnectionPool, self).urlopen(method, url, body,
+                                                       headers, retries,
+                                                       redirect,
+                                                       assert_same_host)
diff --git a/ext/urllib3/contrib/pyopenssl.py b/ext/urllib3/contrib/pyopenssl.py
new file mode 100644
index 0000000000..7c0e9465d9
--- /dev/null
+++ b/ext/urllib3/contrib/pyopenssl.py
@@ -0,0 +1,466 @@
+"""
+SSL with SNI_-support for Python 2. Follow these instructions if you would
+like to verify SSL certificates in Python 2. Note, the default libraries do
+*not* do certificate checking; you need to do additional work to validate
+certificates yourself.
+
+This needs the following packages installed:
+
+* pyOpenSSL (tested with 16.0.0)
+* cryptography (minimum 1.3.4, from pyopenssl)
+* idna (minimum 2.0, from cryptography)
+
+However, pyopenssl depends on cryptography, which depends on idna, so while we
+use all three directly here we end up having relatively few packages required.
+
+You can install them with the following command:
+
+    pip install pyopenssl cryptography idna
+
+To activate certificate checking, call
+:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code
+before you begin making HTTP requests. This can be done in a ``sitecustomize``
+module, or at any other time before your application begins using ``urllib3``,
+like this::
+
+    try:
+        import urllib3.contrib.pyopenssl
+        urllib3.contrib.pyopenssl.inject_into_urllib3()
+    except ImportError:
+        pass
+
+Now you can use :mod:`urllib3` as you normally would, and it will support SNI
+when the required modules are installed.
+
+Activating this module also has the positive side effect of disabling SSL/TLS
+compression in Python 2 (see `CRIME attack`_).
+
+If you want to configure the default list of supported cipher suites, you can
+set the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable.
+
+.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication
+.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit)
+"""
+from __future__ import absolute_import
+
+import OpenSSL.SSL
+from cryptography import x509
+from cryptography.hazmat.backends.openssl import backend as openssl_backend
+from cryptography.hazmat.backends.openssl.x509 import _Certificate
+try:
+    from cryptography.x509 import UnsupportedExtension
+except ImportError:
+    # UnsupportedExtension is gone in cryptography >= 2.1.0
+    class UnsupportedExtension(Exception):
+        pass
+
+from socket import timeout, error as SocketError
+from io import BytesIO
+
+try:  # Platform-specific: Python 2
+    from socket import _fileobject
+except ImportError:  # Platform-specific: Python 3
+    _fileobject = None
+    from ..packages.backports.makefile import backport_makefile
+
+import logging
+import ssl
+from ..packages import six
+import sys
+
+from .. import util
+
+__all__ = ['inject_into_urllib3', 'extract_from_urllib3']
+
+# SNI always works.
+HAS_SNI = True
+
+# Map from urllib3 to PyOpenSSL compatible parameter-values.
+_openssl_versions = {
+    ssl.PROTOCOL_SSLv23: OpenSSL.SSL.SSLv23_METHOD,
+    ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD,
+}
+
+if hasattr(ssl, 'PROTOCOL_TLSv1_1') and hasattr(OpenSSL.SSL, 'TLSv1_1_METHOD'):
+    _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD
+
+if hasattr(ssl, 'PROTOCOL_TLSv1_2') and hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'):
+    _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD
+
+try:
+    _openssl_versions.update({ssl.PROTOCOL_SSLv3: OpenSSL.SSL.SSLv3_METHOD})
+except AttributeError:
+    pass
+
+_stdlib_to_openssl_verify = {
+    ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE,
+    ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER,
+    ssl.CERT_REQUIRED:
+        OpenSSL.SSL.VERIFY_PEER + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
+}
+_openssl_to_stdlib_verify = dict(
+    (v, k) for k, v in _stdlib_to_openssl_verify.items()
+)
+
+# OpenSSL will only write 16K at a time
+SSL_WRITE_BLOCKSIZE = 16384
+
+orig_util_HAS_SNI = util.HAS_SNI
+orig_util_SSLContext = util.ssl_.SSLContext
+
+
+log = logging.getLogger(__name__)
+
+
+def inject_into_urllib3():
+    'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.'
+
+    _validate_dependencies_met()
+
+    util.ssl_.SSLContext = PyOpenSSLContext
+    util.HAS_SNI = HAS_SNI
+    util.ssl_.HAS_SNI = HAS_SNI
+    util.IS_PYOPENSSL = True
+    util.ssl_.IS_PYOPENSSL = True
+
+
+def extract_from_urllib3():
+    'Undo monkey-patching by :func:`inject_into_urllib3`.'
+
+    util.ssl_.SSLContext = orig_util_SSLContext
+    util.HAS_SNI = orig_util_HAS_SNI
+    util.ssl_.HAS_SNI = orig_util_HAS_SNI
+    util.IS_PYOPENSSL = False
+    util.ssl_.IS_PYOPENSSL = False
+
+
+def _validate_dependencies_met():
+    """
+    Verifies that PyOpenSSL's package-level dependencies have been met.
+    Throws `ImportError` if they are not met.
+    """
+    # Method added in `cryptography==1.1`; not available in older versions
+    from cryptography.x509.extensions import Extensions
+    if getattr(Extensions, "get_extension_for_class", None) is None:
+        raise ImportError("'cryptography' module missing required functionality.  "
+                          "Try upgrading to v1.3.4 or newer.")
+
+    # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509
+    # attribute is only present on those versions.
+    from OpenSSL.crypto import X509
+    x509 = X509()
+    if getattr(x509, "_x509", None) is None:
+        raise ImportError("'pyOpenSSL' module missing required functionality. "
+                          "Try upgrading to v0.14 or newer.")
+
+
+def _dnsname_to_stdlib(name):
+    """
+    Converts a dNSName SubjectAlternativeName field to the form used by the
+    standard library on the given Python version.
+
+    Cryptography produces a dNSName as a unicode string that was idna-decoded
+    from ASCII bytes. We need to idna-encode that string to get it back, and
+    then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib
+    uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8).
+
+    If the name cannot be idna-encoded then we return None signalling that
+    the name given should be skipped.
+    """
+    def idna_encode(name):
+        """
+        Borrowed wholesale from the Python Cryptography Project. It turns out
+        that we can't just safely call `idna.encode`: it can explode for
+        wildcard names. This avoids that problem.
+        """
+        import idna
+
+        try:
+            for prefix in [u'*.', u'.']:
+                if name.startswith(prefix):
+                    name = name[len(prefix):]
+                    return prefix.encode('ascii') + idna.encode(name)
+            return idna.encode(name)
+        except idna.core.IDNAError:
+            return None
+
+    name = idna_encode(name)
+    if name is None:
+        return None
+    elif sys.version_info >= (3, 0):
+        name = name.decode('utf-8')
+    return name
+
+
+def get_subj_alt_name(peer_cert):
+    """
+    Given an PyOpenSSL certificate, provides all the subject alternative names.
+    """
+    # Pass the cert to cryptography, which has much better APIs for this.
+    if hasattr(peer_cert, "to_cryptography"):
+        cert = peer_cert.to_cryptography()
+    else:
+        # This is technically using private APIs, but should work across all
+        # relevant versions before PyOpenSSL got a proper API for this.
+        cert = _Certificate(openssl_backend, peer_cert._x509)
+
+    # We want to find the SAN extension. Ask Cryptography to locate it (it's
+    # faster than looping in Python)
+    try:
+        ext = cert.extensions.get_extension_for_class(
+            x509.SubjectAlternativeName
+        ).value
+    except x509.ExtensionNotFound:
+        # No such extension, return the empty list.
+        return []
+    except (x509.DuplicateExtension, UnsupportedExtension,
+            x509.UnsupportedGeneralNameType, UnicodeError) as e:
+        # A problem has been found with the quality of the certificate. Assume
+        # no SAN field is present.
+        log.warning(
+            "A problem was encountered with the certificate that prevented "
+            "urllib3 from finding the SubjectAlternativeName field. This can "
+            "affect certificate validation. The error was %s",
+            e,
+        )
+        return []
+
+    # We want to return dNSName and iPAddress fields. We need to cast the IPs
+    # back to strings because the match_hostname function wants them as
+    # strings.
+    # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8
+    # decoded. This is pretty frustrating, but that's what the standard library
+    # does with certificates, and so we need to attempt to do the same.
+    # We also want to skip over names which cannot be idna encoded.
+    names = [
+        ('DNS', name) for name in map(_dnsname_to_stdlib, ext.get_values_for_type(x509.DNSName))
+        if name is not None
+    ]
+    names.extend(
+        ('IP Address', str(name))
+        for name in ext.get_values_for_type(x509.IPAddress)
+    )
+
+    return names
+
+
+class WrappedSocket(object):
+    '''API-compatibility wrapper for Python OpenSSL's Connection-class.
+
+    Note: _makefile_refs, _drop() and _reuse() are needed for the garbage
+    collector of pypy.
+    '''
+
+    def __init__(self, connection, socket, suppress_ragged_eofs=True):
+        self.connection = connection
+        self.socket = socket
+        self.suppress_ragged_eofs = suppress_ragged_eofs
+        self._makefile_refs = 0
+        self._closed = False
+
+    def fileno(self):
+        return self.socket.fileno()
+
+    # Copy-pasted from Python 3.5 source code
+    def _decref_socketios(self):
+        if self._makefile_refs > 0:
+            self._makefile_refs -= 1
+        if self._closed:
+            self.close()
+
+    def recv(self, *args, **kwargs):
+        try:
+            data = self.connection.recv(*args, **kwargs)
+        except OpenSSL.SSL.SysCallError as e:
+            if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):
+                return b''
+            else:
+                raise SocketError(str(e))
+        except OpenSSL.SSL.ZeroReturnError as e:
+            if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:
+                return b''
+            else:
+                raise
+        except OpenSSL.SSL.WantReadError:
+            if not util.wait_for_read(self.socket, self.socket.gettimeout()):
+                raise timeout('The read operation timed out')
+            else:
+                return self.recv(*args, **kwargs)
+        else:
+            return data
+
+    def recv_into(self, *args, **kwargs):
+        try:
+            return self.connection.recv_into(*args, **kwargs)
+        except OpenSSL.SSL.SysCallError as e:
+            if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):
+                return 0
+            else:
+                raise SocketError(str(e))
+        except OpenSSL.SSL.ZeroReturnError as e:
+            if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:
+                return 0
+            else:
+                raise
+        except OpenSSL.SSL.WantReadError:
+            if not util.wait_for_read(self.socket, self.socket.gettimeout()):
+                raise timeout('The read operation timed out')
+            else:
+                return self.recv_into(*args, **kwargs)
+
+    def settimeout(self, timeout):
+        return self.socket.settimeout(timeout)
+
+    def _send_until_done(self, data):
+        while True:
+            try:
+                return self.connection.send(data)
+            except OpenSSL.SSL.WantWriteError:
+                if not util.wait_for_write(self.socket, self.socket.gettimeout()):
+                    raise timeout()
+                continue
+            except OpenSSL.SSL.SysCallError as e:
+                raise SocketError(str(e))
+
+    def sendall(self, data):
+        total_sent = 0
+        while total_sent < len(data):
+            sent = self._send_until_done(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE])
+            total_sent += sent
+
+    def shutdown(self):
+        # FIXME rethrow compatible exceptions should we ever use this
+        self.connection.shutdown()
+
+    def close(self):
+        if self._makefile_refs < 1:
+            try:
+                self._closed = True
+                return self.connection.close()
+            except OpenSSL.SSL.Error:
+                return
+        else:
+            self._makefile_refs -= 1
+
+    def getpeercert(self, binary_form=False):
+        x509 = self.connection.get_peer_certificate()
+
+        if not x509:
+            return x509
+
+        if binary_form:
+            return OpenSSL.crypto.dump_certificate(
+                OpenSSL.crypto.FILETYPE_ASN1,
+                x509)
+
+        return {
+            'subject': (
+                (('commonName', x509.get_subject().CN),),
+            ),
+            'subjectAltName': get_subj_alt_name(x509)
+        }
+
+    def _reuse(self):
+        self._makefile_refs += 1
+
+    def _drop(self):
+        if self._makefile_refs < 1:
+            self.close()
+        else:
+            self._makefile_refs -= 1
+
+
+if _fileobject:  # Platform-specific: Python 2
+    def makefile(self, mode, bufsize=-1):
+        self._makefile_refs += 1
+        return _fileobject(self, mode, bufsize, close=True)
+else:  # Platform-specific: Python 3
+    makefile = backport_makefile
+
+WrappedSocket.makefile = makefile
+
+
+class PyOpenSSLContext(object):
+    """
+    I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible
+    for translating the interface of the standard library ``SSLContext`` object
+    to calls into PyOpenSSL.
+    """
+    def __init__(self, protocol):
+        self.protocol = _openssl_versions[protocol]
+        self._ctx = OpenSSL.SSL.Context(self.protocol)
+        self._options = 0
+        self.check_hostname = False
+
+    @property
+    def options(self):
+        return self._options
+
+    @options.setter
+    def options(self, value):
+        self._options = value
+        self._ctx.set_options(value)
+
+    @property
+    def verify_mode(self):
+        return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()]
+
+    @verify_mode.setter
+    def verify_mode(self, value):
+        self._ctx.set_verify(
+            _stdlib_to_openssl_verify[value],
+            _verify_callback
+        )
+
+    def set_default_verify_paths(self):
+        self._ctx.set_default_verify_paths()
+
+    def set_ciphers(self, ciphers):
+        if isinstance(ciphers, six.text_type):
+            ciphers = ciphers.encode('utf-8')
+        self._ctx.set_cipher_list(ciphers)
+
+    def load_verify_locations(self, cafile=None, capath=None, cadata=None):
+        if cafile is not None:
+            cafile = cafile.encode('utf-8')
+        if capath is not None:
+            capath = capath.encode('utf-8')
+        self._ctx.load_verify_locations(cafile, capath)
+        if cadata is not None:
+            self._ctx.load_verify_locations(BytesIO(cadata))
+
+    def load_cert_chain(self, certfile, keyfile=None, password=None):
+        self._ctx.use_certificate_chain_file(certfile)
+        if password is not None:
+            self._ctx.set_passwd_cb(lambda max_length, prompt_twice, userdata: password)
+        self._ctx.use_privatekey_file(keyfile or certfile)
+
+    def wrap_socket(self, sock, server_side=False,
+                    do_handshake_on_connect=True, suppress_ragged_eofs=True,
+                    server_hostname=None):
+        cnx = OpenSSL.SSL.Connection(self._ctx, sock)
+
+        if isinstance(server_hostname, six.text_type):  # Platform-specific: Python 3
+            server_hostname = server_hostname.encode('utf-8')
+
+        if server_hostname is not None:
+            cnx.set_tlsext_host_name(server_hostname)
+
+        cnx.set_connect_state()
+
+        while True:
+            try:
+                cnx.do_handshake()
+            except OpenSSL.SSL.WantReadError:
+                if not util.wait_for_read(sock, sock.gettimeout()):
+                    raise timeout('select timed out')
+                continue
+            except OpenSSL.SSL.Error as e:
+                raise ssl.SSLError('bad handshake: %r' % e)
+            break
+
+        return WrappedSocket(cnx, sock)
+
+
+def _verify_callback(cnx, x509, err_no, err_depth, return_code):
+    return err_no == 0
diff --git a/ext/urllib3/contrib/securetransport.py b/ext/urllib3/contrib/securetransport.py
new file mode 100644
index 0000000000..77cb59ed71
--- /dev/null
+++ b/ext/urllib3/contrib/securetransport.py
@@ -0,0 +1,804 @@
+"""
+SecureTranport support for urllib3 via ctypes.
+
+This makes platform-native TLS available to urllib3 users on macOS without the
+use of a compiler. This is an important feature because the Python Package
+Index is moving to become a TLSv1.2-or-higher server, and the default OpenSSL
+that ships with macOS is not capable of doing TLSv1.2. The only way to resolve
+this is to give macOS users an alternative solution to the problem, and that
+solution is to use SecureTransport.
+
+We use ctypes here because this solution must not require a compiler. That's
+because pip is not allowed to require a compiler either.
+
+This is not intended to be a seriously long-term solution to this problem.
+The hope is that PEP 543 will eventually solve this issue for us, at which
+point we can retire this contrib module. But in the short term, we need to
+solve the impending tire fire that is Python on Mac without this kind of
+contrib module. So...here we are.
+
+To use this module, simply import and inject it::
+
+    import urllib3.contrib.securetransport
+    urllib3.contrib.securetransport.inject_into_urllib3()
+
+Happy TLSing!
+"""
+from __future__ import absolute_import
+
+import contextlib
+import ctypes
+import errno
+import os.path
+import shutil
+import socket
+import ssl
+import threading
+import weakref
+
+from .. import util
+from ._securetransport.bindings import (
+    Security, SecurityConst, CoreFoundation
+)
+from ._securetransport.low_level import (
+    _assert_no_error, _cert_array_from_pem, _temporary_keychain,
+    _load_client_cert_chain
+)
+
+try:  # Platform-specific: Python 2
+    from socket import _fileobject
+except ImportError:  # Platform-specific: Python 3
+    _fileobject = None
+    from ..packages.backports.makefile import backport_makefile
+
+__all__ = ['inject_into_urllib3', 'extract_from_urllib3']
+
+# SNI always works
+HAS_SNI = True
+
+orig_util_HAS_SNI = util.HAS_SNI
+orig_util_SSLContext = util.ssl_.SSLContext
+
+# This dictionary is used by the read callback to obtain a handle to the
+# calling wrapped socket. This is a pretty silly approach, but for now it'll
+# do. I feel like I should be able to smuggle a handle to the wrapped socket
+# directly in the SSLConnectionRef, but for now this approach will work I
+# guess.
+#
+# We need to lock around this structure for inserts, but we don't do it for
+# reads/writes in the callbacks. The reasoning here goes as follows:
+#
+#    1. It is not possible to call into the callbacks before the dictionary is
+#       populated, so once in the callback the id must be in the dictionary.
+#    2. The callbacks don't mutate the dictionary, they only read from it, and
+#       so cannot conflict with any of the insertions.
+#
+# This is good: if we had to lock in the callbacks we'd drastically slow down
+# the performance of this code.
+_connection_refs = weakref.WeakValueDictionary()
+_connection_ref_lock = threading.Lock()
+
+# Limit writes to 16kB. This is OpenSSL's limit, but we'll cargo-cult it over
+# for no better reason than we need *a* limit, and this one is right there.
+SSL_WRITE_BLOCKSIZE = 16384
+
+# This is our equivalent of util.ssl_.DEFAULT_CIPHERS, but expanded out to
+# individual cipher suites. We need to do this because this is how
+# SecureTransport wants them.
+CIPHER_SUITES = [
+    SecurityConst.TLS_AES_256_GCM_SHA384,
+    SecurityConst.TLS_CHACHA20_POLY1305_SHA256,
+    SecurityConst.TLS_AES_128_GCM_SHA256,
+    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+    SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+    SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+    SecurityConst.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,
+    SecurityConst.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+    SecurityConst.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
+    SecurityConst.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+    SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+    SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+    SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+    SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
+    SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+    SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+    SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+    SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+    SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+    SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+    SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
+    SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+    SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+    SecurityConst.TLS_RSA_WITH_AES_256_GCM_SHA384,
+    SecurityConst.TLS_RSA_WITH_AES_128_GCM_SHA256,
+    SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA256,
+    SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA256,
+    SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA,
+    SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA,
+]
+
+# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of
+# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version.
+_protocol_to_min_max = {
+    ssl.PROTOCOL_SSLv23: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12),
+}
+
+if hasattr(ssl, "PROTOCOL_SSLv2"):
+    _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = (
+        SecurityConst.kSSLProtocol2, SecurityConst.kSSLProtocol2
+    )
+if hasattr(ssl, "PROTOCOL_SSLv3"):
+    _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = (
+        SecurityConst.kSSLProtocol3, SecurityConst.kSSLProtocol3
+    )
+if hasattr(ssl, "PROTOCOL_TLSv1"):
+    _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = (
+        SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol1
+    )
+if hasattr(ssl, "PROTOCOL_TLSv1_1"):
+    _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = (
+        SecurityConst.kTLSProtocol11, SecurityConst.kTLSProtocol11
+    )
+if hasattr(ssl, "PROTOCOL_TLSv1_2"):
+    _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = (
+        SecurityConst.kTLSProtocol12, SecurityConst.kTLSProtocol12
+    )
+if hasattr(ssl, "PROTOCOL_TLS"):
+    _protocol_to_min_max[ssl.PROTOCOL_TLS] = _protocol_to_min_max[ssl.PROTOCOL_SSLv23]
+
+
+def inject_into_urllib3():
+    """
+    Monkey-patch urllib3 with SecureTransport-backed SSL-support.
+    """
+    util.ssl_.SSLContext = SecureTransportContext
+    util.HAS_SNI = HAS_SNI
+    util.ssl_.HAS_SNI = HAS_SNI
+    util.IS_SECURETRANSPORT = True
+    util.ssl_.IS_SECURETRANSPORT = True
+
+
+def extract_from_urllib3():
+    """
+    Undo monkey-patching by :func:`inject_into_urllib3`.
+    """
+    util.ssl_.SSLContext = orig_util_SSLContext
+    util.HAS_SNI = orig_util_HAS_SNI
+    util.ssl_.HAS_SNI = orig_util_HAS_SNI
+    util.IS_SECURETRANSPORT = False
+    util.ssl_.IS_SECURETRANSPORT = False
+
+
+def _read_callback(connection_id, data_buffer, data_length_pointer):
+    """
+    SecureTransport read callback. This is called by ST to request that data
+    be returned from the socket.
+    """
+    wrapped_socket = None
+    try:
+        wrapped_socket = _connection_refs.get(connection_id)
+        if wrapped_socket is None:
+            return SecurityConst.errSSLInternal
+        base_socket = wrapped_socket.socket
+
+        requested_length = data_length_pointer[0]
+
+        timeout = wrapped_socket.gettimeout()
+        error = None
+        read_count = 0
+
+        try:
+            while read_count < requested_length:
+                if timeout is None or timeout >= 0:
+                    if not util.wait_for_read(base_socket, timeout):
+                        raise socket.error(errno.EAGAIN, 'timed out')
+
+                remaining = requested_length - read_count
+                buffer = (ctypes.c_char * remaining).from_address(
+                    data_buffer + read_count
+                )
+                chunk_size = base_socket.recv_into(buffer, remaining)
+                read_count += chunk_size
+                if not chunk_size:
+                    if not read_count:
+                        return SecurityConst.errSSLClosedGraceful
+                    break
+        except (socket.error) as e:
+            error = e.errno
+
+            if error is not None and error != errno.EAGAIN:
+                data_length_pointer[0] = read_count
+                if error == errno.ECONNRESET or error == errno.EPIPE:
+                    return SecurityConst.errSSLClosedAbort
+                raise
+
+        data_length_pointer[0] = read_count
+
+        if read_count != requested_length:
+            return SecurityConst.errSSLWouldBlock
+
+        return 0
+    except Exception as e:
+        if wrapped_socket is not None:
+            wrapped_socket._exception = e
+        return SecurityConst.errSSLInternal
+
+
+def _write_callback(connection_id, data_buffer, data_length_pointer):
+    """
+    SecureTransport write callback. This is called by ST to request that data
+    actually be sent on the network.
+    """
+    wrapped_socket = None
+    try:
+        wrapped_socket = _connection_refs.get(connection_id)
+        if wrapped_socket is None:
+            return SecurityConst.errSSLInternal
+        base_socket = wrapped_socket.socket
+
+        bytes_to_write = data_length_pointer[0]
+        data = ctypes.string_at(data_buffer, bytes_to_write)
+
+        timeout = wrapped_socket.gettimeout()
+        error = None
+        sent = 0
+
+        try:
+            while sent < bytes_to_write:
+                if timeout is None or timeout >= 0:
+                    if not util.wait_for_write(base_socket, timeout):
+                        raise socket.error(errno.EAGAIN, 'timed out')
+                chunk_sent = base_socket.send(data)
+                sent += chunk_sent
+
+                # This has some needless copying here, but I'm not sure there's
+                # much value in optimising this data path.
+                data = data[chunk_sent:]
+        except (socket.error) as e:
+            error = e.errno
+
+            if error is not None and error != errno.EAGAIN:
+                data_length_pointer[0] = sent
+                if error == errno.ECONNRESET or error == errno.EPIPE:
+                    return SecurityConst.errSSLClosedAbort
+                raise
+
+        data_length_pointer[0] = sent
+
+        if sent != bytes_to_write:
+            return SecurityConst.errSSLWouldBlock
+
+        return 0
+    except Exception as e:
+        if wrapped_socket is not None:
+            wrapped_socket._exception = e
+        return SecurityConst.errSSLInternal
+
+
+# We need to keep these two objects references alive: if they get GC'd while
+# in use then SecureTransport could attempt to call a function that is in freed
+# memory. That would be...uh...bad. Yeah, that's the word. Bad.
+_read_callback_pointer = Security.SSLReadFunc(_read_callback)
+_write_callback_pointer = Security.SSLWriteFunc(_write_callback)
+
+
+class WrappedSocket(object):
+    """
+    API-compatibility wrapper for Python's OpenSSL wrapped socket object.
+
+    Note: _makefile_refs, _drop(), and _reuse() are needed for the garbage
+    collector of PyPy.
+    """
+    def __init__(self, socket):
+        self.socket = socket
+        self.context = None
+        self._makefile_refs = 0
+        self._closed = False
+        self._exception = None
+        self._keychain = None
+        self._keychain_dir = None
+        self._client_cert_chain = None
+
+        # We save off the previously-configured timeout and then set it to
+        # zero. This is done because we use select and friends to handle the
+        # timeouts, but if we leave the timeout set on the lower socket then
+        # Python will "kindly" call select on that socket again for us. Avoid
+        # that by forcing the timeout to zero.
+        self._timeout = self.socket.gettimeout()
+        self.socket.settimeout(0)
+
+    @contextlib.contextmanager
+    def _raise_on_error(self):
+        """
+        A context manager that can be used to wrap calls that do I/O from
+        SecureTransport. If any of the I/O callbacks hit an exception, this
+        context manager will correctly propagate the exception after the fact.
+        This avoids silently swallowing those exceptions.
+
+        It also correctly forces the socket closed.
+        """
+        self._exception = None
+
+        # We explicitly don't catch around this yield because in the unlikely
+        # event that an exception was hit in the block we don't want to swallow
+        # it.
+        yield
+        if self._exception is not None:
+            exception, self._exception = self._exception, None
+            self.close()
+            raise exception
+
+    def _set_ciphers(self):
+        """
+        Sets up the allowed ciphers. By default this matches the set in
+        util.ssl_.DEFAULT_CIPHERS, at least as supported by macOS. This is done
+        custom and doesn't allow changing at this time, mostly because parsing
+        OpenSSL cipher strings is going to be a freaking nightmare.
+        """
+        ciphers = (Security.SSLCipherSuite * len(CIPHER_SUITES))(*CIPHER_SUITES)
+        result = Security.SSLSetEnabledCiphers(
+            self.context, ciphers, len(CIPHER_SUITES)
+        )
+        _assert_no_error(result)
+
+    def _custom_validate(self, verify, trust_bundle):
+        """
+        Called when we have set custom validation. We do this in two cases:
+        first, when cert validation is entirely disabled; and second, when
+        using a custom trust DB.
+        """
+        # If we disabled cert validation, just say: cool.
+        if not verify:
+            return
+
+        # We want data in memory, so load it up.
+        if os.path.isfile(trust_bundle):
+            with open(trust_bundle, 'rb') as f:
+                trust_bundle = f.read()
+
+        cert_array = None
+        trust = Security.SecTrustRef()
+
+        try:
+            # Get a CFArray that contains the certs we want.
+            cert_array = _cert_array_from_pem(trust_bundle)
+
+            # Ok, now the hard part. We want to get the SecTrustRef that ST has
+            # created for this connection, shove our CAs into it, tell ST to
+            # ignore everything else it knows, and then ask if it can build a
+            # chain. This is a buuuunch of code.
+            result = Security.SSLCopyPeerTrust(
+                self.context, ctypes.byref(trust)
+            )
+            _assert_no_error(result)
+            if not trust:
+                raise ssl.SSLError("Failed to copy trust reference")
+
+            result = Security.SecTrustSetAnchorCertificates(trust, cert_array)
+            _assert_no_error(result)
+
+            result = Security.SecTrustSetAnchorCertificatesOnly(trust, True)
+            _assert_no_error(result)
+
+            trust_result = Security.SecTrustResultType()
+            result = Security.SecTrustEvaluate(
+                trust, ctypes.byref(trust_result)
+            )
+            _assert_no_error(result)
+        finally:
+            if trust:
+                CoreFoundation.CFRelease(trust)
+
+            if cert_array is not None:
+                CoreFoundation.CFRelease(cert_array)
+
+        # Ok, now we can look at what the result was.
+        successes = (
+            SecurityConst.kSecTrustResultUnspecified,
+            SecurityConst.kSecTrustResultProceed
+        )
+        if trust_result.value not in successes:
+            raise ssl.SSLError(
+                "certificate verify failed, error code: %d" %
+                trust_result.value
+            )
+
+    def handshake(self,
+                  server_hostname,
+                  verify,
+                  trust_bundle,
+                  min_version,
+                  max_version,
+                  client_cert,
+                  client_key,
+                  client_key_passphrase):
+        """
+        Actually performs the TLS handshake. This is run automatically by
+        wrapped socket, and shouldn't be needed in user code.
+        """
+        # First, we do the initial bits of connection setup. We need to create
+        # a context, set its I/O funcs, and set the connection reference.
+        self.context = Security.SSLCreateContext(
+            None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType
+        )
+        result = Security.SSLSetIOFuncs(
+            self.context, _read_callback_pointer, _write_callback_pointer
+        )
+        _assert_no_error(result)
+
+        # Here we need to compute the handle to use. We do this by taking the
+        # id of self modulo 2**31 - 1. If this is already in the dictionary, we
+        # just keep incrementing by one until we find a free space.
+        with _connection_ref_lock:
+            handle = id(self) % 2147483647
+            while handle in _connection_refs:
+                handle = (handle + 1) % 2147483647
+            _connection_refs[handle] = self
+
+        result = Security.SSLSetConnection(self.context, handle)
+        _assert_no_error(result)
+
+        # If we have a server hostname, we should set that too.
+        if server_hostname:
+            if not isinstance(server_hostname, bytes):
+                server_hostname = server_hostname.encode('utf-8')
+
+            result = Security.SSLSetPeerDomainName(
+                self.context, server_hostname, len(server_hostname)
+            )
+            _assert_no_error(result)
+
+        # Setup the ciphers.
+        self._set_ciphers()
+
+        # Set the minimum and maximum TLS versions.
+        result = Security.SSLSetProtocolVersionMin(self.context, min_version)
+        _assert_no_error(result)
+        result = Security.SSLSetProtocolVersionMax(self.context, max_version)
+        _assert_no_error(result)
+
+        # If there's a trust DB, we need to use it. We do that by telling
+        # SecureTransport to break on server auth. We also do that if we don't
+        # want to validate the certs at all: we just won't actually do any
+        # authing in that case.
+        if not verify or trust_bundle is not None:
+            result = Security.SSLSetSessionOption(
+                self.context,
+                SecurityConst.kSSLSessionOptionBreakOnServerAuth,
+                True
+            )
+            _assert_no_error(result)
+
+        # If there's a client cert, we need to use it.
+        if client_cert:
+            self._keychain, self._keychain_dir = _temporary_keychain()
+            self._client_cert_chain = _load_client_cert_chain(
+                self._keychain, client_cert, client_key
+            )
+            result = Security.SSLSetCertificate(
+                self.context, self._client_cert_chain
+            )
+            _assert_no_error(result)
+
+        while True:
+            with self._raise_on_error():
+                result = Security.SSLHandshake(self.context)
+
+                if result == SecurityConst.errSSLWouldBlock:
+                    raise socket.timeout("handshake timed out")
+                elif result == SecurityConst.errSSLServerAuthCompleted:
+                    self._custom_validate(verify, trust_bundle)
+                    continue
+                else:
+                    _assert_no_error(result)
+                    break
+
+    def fileno(self):
+        return self.socket.fileno()
+
+    # Copy-pasted from Python 3.5 source code
+    def _decref_socketios(self):
+        if self._makefile_refs > 0:
+            self._makefile_refs -= 1
+        if self._closed:
+            self.close()
+
+    def recv(self, bufsiz):
+        buffer = ctypes.create_string_buffer(bufsiz)
+        bytes_read = self.recv_into(buffer, bufsiz)
+        data = buffer[:bytes_read]
+        return data
+
+    def recv_into(self, buffer, nbytes=None):
+        # Read short on EOF.
+        if self._closed:
+            return 0
+
+        if nbytes is None:
+            nbytes = len(buffer)
+
+        buffer = (ctypes.c_char * nbytes).from_buffer(buffer)
+        processed_bytes = ctypes.c_size_t(0)
+
+        with self._raise_on_error():
+            result = Security.SSLRead(
+                self.context, buffer, nbytes, ctypes.byref(processed_bytes)
+            )
+
+        # There are some result codes that we want to treat as "not always
+        # errors". Specifically, those are errSSLWouldBlock,
+        # errSSLClosedGraceful, and errSSLClosedNoNotify.
+        if (result == SecurityConst.errSSLWouldBlock):
+            # If we didn't process any bytes, then this was just a time out.
+            # However, we can get errSSLWouldBlock in situations when we *did*
+            # read some data, and in those cases we should just read "short"
+            # and return.
+            if processed_bytes.value == 0:
+                # Timed out, no data read.
+                raise socket.timeout("recv timed out")
+        elif result in (SecurityConst.errSSLClosedGraceful, SecurityConst.errSSLClosedNoNotify):
+            # The remote peer has closed this connection. We should do so as
+            # well. Note that we don't actually return here because in
+            # principle this could actually be fired along with return data.
+            # It's unlikely though.
+            self.close()
+        else:
+            _assert_no_error(result)
+
+        # Ok, we read and probably succeeded. We should return whatever data
+        # was actually read.
+        return processed_bytes.value
+
+    def settimeout(self, timeout):
+        self._timeout = timeout
+
+    def gettimeout(self):
+        return self._timeout
+
+    def send(self, data):
+        processed_bytes = ctypes.c_size_t(0)
+
+        with self._raise_on_error():
+            result = Security.SSLWrite(
+                self.context, data, len(data), ctypes.byref(processed_bytes)
+            )
+
+        if result == SecurityConst.errSSLWouldBlock and processed_bytes.value == 0:
+            # Timed out
+            raise socket.timeout("send timed out")
+        else:
+            _assert_no_error(result)
+
+        # We sent, and probably succeeded. Tell them how much we sent.
+        return processed_bytes.value
+
+    def sendall(self, data):
+        total_sent = 0
+        while total_sent < len(data):
+            sent = self.send(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE])
+            total_sent += sent
+
+    def shutdown(self):
+        with self._raise_on_error():
+            Security.SSLClose(self.context)
+
+    def close(self):
+        # TODO: should I do clean shutdown here? Do I have to?
+        if self._makefile_refs < 1:
+            self._closed = True
+            if self.context:
+                CoreFoundation.CFRelease(self.context)
+                self.context = None
+            if self._client_cert_chain:
+                CoreFoundation.CFRelease(self._client_cert_chain)
+                self._client_cert_chain = None
+            if self._keychain:
+                Security.SecKeychainDelete(self._keychain)
+                CoreFoundation.CFRelease(self._keychain)
+                shutil.rmtree(self._keychain_dir)
+                self._keychain = self._keychain_dir = None
+            return self.socket.close()
+        else:
+            self._makefile_refs -= 1
+
+    def getpeercert(self, binary_form=False):
+        # Urgh, annoying.
+        #
+        # Here's how we do this:
+        #
+        # 1. Call SSLCopyPeerTrust to get hold of the trust object for this
+        #    connection.
+        # 2. Call SecTrustGetCertificateAtIndex for index 0 to get the leaf.
+        # 3. To get the CN, call SecCertificateCopyCommonName and process that
+        #    string so that it's of the appropriate type.
+        # 4. To get the SAN, we need to do something a bit more complex:
+        #    a. Call SecCertificateCopyValues to get the data, requesting
+        #       kSecOIDSubjectAltName.
+        #    b. Mess about with this dictionary to try to get the SANs out.
+        #
+        # This is gross. Really gross. It's going to be a few hundred LoC extra
+        # just to repeat something that SecureTransport can *already do*. So my
+        # operating assumption at this time is that what we want to do is
+        # instead to just flag to urllib3 that it shouldn't do its own hostname
+        # validation when using SecureTransport.
+        if not binary_form:
+            raise ValueError(
+                "SecureTransport only supports dumping binary certs"
+            )
+        trust = Security.SecTrustRef()
+        certdata = None
+        der_bytes = None
+
+        try:
+            # Grab the trust store.
+            result = Security.SSLCopyPeerTrust(
+                self.context, ctypes.byref(trust)
+            )
+            _assert_no_error(result)
+            if not trust:
+                # Probably we haven't done the handshake yet. No biggie.
+                return None
+
+            cert_count = Security.SecTrustGetCertificateCount(trust)
+            if not cert_count:
+                # Also a case that might happen if we haven't handshaked.
+                # Handshook? Handshaken?
+                return None
+
+            leaf = Security.SecTrustGetCertificateAtIndex(trust, 0)
+            assert leaf
+
+            # Ok, now we want the DER bytes.
+            certdata = Security.SecCertificateCopyData(leaf)
+            assert certdata
+
+            data_length = CoreFoundation.CFDataGetLength(certdata)
+            data_buffer = CoreFoundation.CFDataGetBytePtr(certdata)
+            der_bytes = ctypes.string_at(data_buffer, data_length)
+        finally:
+            if certdata:
+                CoreFoundation.CFRelease(certdata)
+            if trust:
+                CoreFoundation.CFRelease(trust)
+
+        return der_bytes
+
+    def _reuse(self):
+        self._makefile_refs += 1
+
+    def _drop(self):
+        if self._makefile_refs < 1:
+            self.close()
+        else:
+            self._makefile_refs -= 1
+
+
+if _fileobject:  # Platform-specific: Python 2
+    def makefile(self, mode, bufsize=-1):
+        self._makefile_refs += 1
+        return _fileobject(self, mode, bufsize, close=True)
+else:  # Platform-specific: Python 3
+    def makefile(self, mode="r", buffering=None, *args, **kwargs):
+        # We disable buffering with SecureTransport because it conflicts with
+        # the buffering that ST does internally (see issue #1153 for more).
+        buffering = 0
+        return backport_makefile(self, mode, buffering, *args, **kwargs)
+
+WrappedSocket.makefile = makefile
+
+
+class SecureTransportContext(object):
+    """
+    I am a wrapper class for the SecureTransport library, to translate the
+    interface of the standard library ``SSLContext`` object to calls into
+    SecureTransport.
+    """
+    def __init__(self, protocol):
+        self._min_version, self._max_version = _protocol_to_min_max[protocol]
+        self._options = 0
+        self._verify = False
+        self._trust_bundle = None
+        self._client_cert = None
+        self._client_key = None
+        self._client_key_passphrase = None
+
+    @property
+    def check_hostname(self):
+        """
+        SecureTransport cannot have its hostname checking disabled. For more,
+        see the comment on getpeercert() in this file.
+        """
+        return True
+
+    @check_hostname.setter
+    def check_hostname(self, value):
+        """
+        SecureTransport cannot have its hostname checking disabled. For more,
+        see the comment on getpeercert() in this file.
+        """
+        pass
+
+    @property
+    def options(self):
+        # TODO: Well, crap.
+        #
+        # So this is the bit of the code that is the most likely to cause us
+        # trouble. Essentially we need to enumerate all of the SSL options that
+        # users might want to use and try to see if we can sensibly translate
+        # them, or whether we should just ignore them.
+        return self._options
+
+    @options.setter
+    def options(self, value):
+        # TODO: Update in line with above.
+        self._options = value
+
+    @property
+    def verify_mode(self):
+        return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE
+
+    @verify_mode.setter
+    def verify_mode(self, value):
+        self._verify = True if value == ssl.CERT_REQUIRED else False
+
+    def set_default_verify_paths(self):
+        # So, this has to do something a bit weird. Specifically, what it does
+        # is nothing.
+        #
+        # This means that, if we had previously had load_verify_locations
+        # called, this does not undo that. We need to do that because it turns
+        # out that the rest of the urllib3 code will attempt to load the
+        # default verify paths if it hasn't been told about any paths, even if
+        # the context itself was sometime earlier. We resolve that by just
+        # ignoring it.
+        pass
+
+    def load_default_certs(self):
+        return self.set_default_verify_paths()
+
+    def set_ciphers(self, ciphers):
+        # For now, we just require the default cipher string.
+        if ciphers != util.ssl_.DEFAULT_CIPHERS:
+            raise ValueError(
+                "SecureTransport doesn't support custom cipher strings"
+            )
+
+    def load_verify_locations(self, cafile=None, capath=None, cadata=None):
+        # OK, we only really support cadata and cafile.
+        if capath is not None:
+            raise ValueError(
+                "SecureTransport does not support cert directories"
+            )
+
+        self._trust_bundle = cafile or cadata
+
+    def load_cert_chain(self, certfile, keyfile=None, password=None):
+        self._client_cert = certfile
+        self._client_key = keyfile
+        self._client_cert_passphrase = password
+
+    def wrap_socket(self, sock, server_side=False,
+                    do_handshake_on_connect=True, suppress_ragged_eofs=True,
+                    server_hostname=None):
+        # So, what do we do here? Firstly, we assert some properties. This is a
+        # stripped down shim, so there is some functionality we don't support.
+        # See PEP 543 for the real deal.
+        assert not server_side
+        assert do_handshake_on_connect
+        assert suppress_ragged_eofs
+
+        # Ok, we're good to go. Now we want to create the wrapped socket object
+        # and store it in the appropriate place.
+        wrapped_socket = WrappedSocket(sock)
+
+        # Now we can handshake
+        wrapped_socket.handshake(
+            server_hostname, self._verify, self._trust_bundle,
+            self._min_version, self._max_version, self._client_cert,
+            self._client_key, self._client_key_passphrase
+        )
+        return wrapped_socket
diff --git a/ext/urllib3/contrib/socks.py b/ext/urllib3/contrib/socks.py
new file mode 100644
index 0000000000..811e312ec8
--- /dev/null
+++ b/ext/urllib3/contrib/socks.py
@@ -0,0 +1,192 @@
+# -*- coding: utf-8 -*-
+"""
+This module contains provisional support for SOCKS proxies from within
+urllib3. This module supports SOCKS4 (specifically the SOCKS4A variant) and
+SOCKS5. To enable its functionality, either install PySocks or install this
+module with the ``socks`` extra.
+
+The SOCKS implementation supports the full range of urllib3 features. It also
+supports the following SOCKS features:
+
+- SOCKS4
+- SOCKS4a
+- SOCKS5
+- Usernames and passwords for the SOCKS proxy
+
+Known Limitations:
+
+- Currently PySocks does not support contacting remote websites via literal
+  IPv6 addresses. Any such connection attempt will fail. You must use a domain
+  name.
+- Currently PySocks does not support IPv6 connections to the SOCKS proxy. Any
+  such connection attempt will fail.
+"""
+from __future__ import absolute_import
+
+try:
+    import socks
+except ImportError:
+    import warnings
+    from ..exceptions import DependencyWarning
+
+    warnings.warn((
+        'SOCKS support in urllib3 requires the installation of optional '
+        'dependencies: specifically, PySocks.  For more information, see '
+        'https://urllib3.readthedocs.io/en/latest/contrib.html#socks-proxies'
+        ),
+        DependencyWarning
+    )
+    raise
+
+from socket import error as SocketError, timeout as SocketTimeout
+
+from ..connection import (
+    HTTPConnection, HTTPSConnection
+)
+from ..connectionpool import (
+    HTTPConnectionPool, HTTPSConnectionPool
+)
+from ..exceptions import ConnectTimeoutError, NewConnectionError
+from ..poolmanager import PoolManager
+from ..util.url import parse_url
+
+try:
+    import ssl
+except ImportError:
+    ssl = None
+
+
+class SOCKSConnection(HTTPConnection):
+    """
+    A plain-text HTTP connection that connects via a SOCKS proxy.
+    """
+    def __init__(self, *args, **kwargs):
+        self._socks_options = kwargs.pop('_socks_options')
+        super(SOCKSConnection, self).__init__(*args, **kwargs)
+
+    def _new_conn(self):
+        """
+        Establish a new connection via the SOCKS proxy.
+        """
+        extra_kw = {}
+        if self.source_address:
+            extra_kw['source_address'] = self.source_address
+
+        if self.socket_options:
+            extra_kw['socket_options'] = self.socket_options
+
+        try:
+            conn = socks.create_connection(
+                (self.host, self.port),
+                proxy_type=self._socks_options['socks_version'],
+                proxy_addr=self._socks_options['proxy_host'],
+                proxy_port=self._socks_options['proxy_port'],
+                proxy_username=self._socks_options['username'],
+                proxy_password=self._socks_options['password'],
+                proxy_rdns=self._socks_options['rdns'],
+                timeout=self.timeout,
+                **extra_kw
+            )
+
+        except SocketTimeout as e:
+            raise ConnectTimeoutError(
+                self, "Connection to %s timed out. (connect timeout=%s)" %
+                (self.host, self.timeout))
+
+        except socks.ProxyError as e:
+            # This is fragile as hell, but it seems to be the only way to raise
+            # useful errors here.
+            if e.socket_err:
+                error = e.socket_err
+                if isinstance(error, SocketTimeout):
+                    raise ConnectTimeoutError(
+                        self,
+                        "Connection to %s timed out. (connect timeout=%s)" %
+                        (self.host, self.timeout)
+                    )
+                else:
+                    raise NewConnectionError(
+                        self,
+                        "Failed to establish a new connection: %s" % error
+                    )
+            else:
+                raise NewConnectionError(
+                    self,
+                    "Failed to establish a new connection: %s" % e
+                )
+
+        except SocketError as e:  # Defensive: PySocks should catch all these.
+            raise NewConnectionError(
+                self, "Failed to establish a new connection: %s" % e)
+
+        return conn
+
+
+# We don't need to duplicate the Verified/Unverified distinction from
+# urllib3/connection.py here because the HTTPSConnection will already have been
+# correctly set to either the Verified or Unverified form by that module. This
+# means the SOCKSHTTPSConnection will automatically be the correct type.
+class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection):
+    pass
+
+
+class SOCKSHTTPConnectionPool(HTTPConnectionPool):
+    ConnectionCls = SOCKSConnection
+
+
+class SOCKSHTTPSConnectionPool(HTTPSConnectionPool):
+    ConnectionCls = SOCKSHTTPSConnection
+
+
+class SOCKSProxyManager(PoolManager):
+    """
+    A version of the urllib3 ProxyManager that routes connections via the
+    defined SOCKS proxy.
+    """
+    pool_classes_by_scheme = {
+        'http': SOCKSHTTPConnectionPool,
+        'https': SOCKSHTTPSConnectionPool,
+    }
+
+    def __init__(self, proxy_url, username=None, password=None,
+                 num_pools=10, headers=None, **connection_pool_kw):
+        parsed = parse_url(proxy_url)
+
+        if username is None and password is None and parsed.auth is not None:
+            split = parsed.auth.split(':')
+            if len(split) == 2:
+                username, password = split
+        if parsed.scheme == 'socks5':
+            socks_version = socks.PROXY_TYPE_SOCKS5
+            rdns = False
+        elif parsed.scheme == 'socks5h':
+            socks_version = socks.PROXY_TYPE_SOCKS5
+            rdns = True
+        elif parsed.scheme == 'socks4':
+            socks_version = socks.PROXY_TYPE_SOCKS4
+            rdns = False
+        elif parsed.scheme == 'socks4a':
+            socks_version = socks.PROXY_TYPE_SOCKS4
+            rdns = True
+        else:
+            raise ValueError(
+                "Unable to determine SOCKS version from %s" % proxy_url
+            )
+
+        self.proxy_url = proxy_url
+
+        socks_options = {
+            'socks_version': socks_version,
+            'proxy_host': parsed.host,
+            'proxy_port': parsed.port,
+            'username': username,
+            'password': password,
+            'rdns': rdns
+        }
+        connection_pool_kw['_socks_options'] = socks_options
+
+        super(SOCKSProxyManager, self).__init__(
+            num_pools, headers, **connection_pool_kw
+        )
+
+        self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme
diff --git a/ext/urllib3/packages/backports/makefile.py b/ext/urllib3/packages/backports/makefile.py
index 75b80dcf84..740db377d9 100644
--- a/ext/urllib3/packages/backports/makefile.py
+++ b/ext/urllib3/packages/backports/makefile.py
@@ -16,7 +16,7 @@ def backport_makefile(self, mode="r", buffering=None, encoding=None,
     """
     Backport of ``socket.makefile`` from Python 3.5.
     """
-    if not set(mode) <= set(["r", "w", "b"]):
+    if not set(mode) <= {"r", "w", "b"}:
         raise ValueError(
             "invalid mode %r (only r, w, b allowed)" % (mode,)
         )
diff --git a/ext/urllib3/packages/ordered_dict.py b/ext/urllib3/packages/ordered_dict.py
deleted file mode 100644
index 4479363cc4..0000000000
--- a/ext/urllib3/packages/ordered_dict.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy.
-# Passes Python2.7's test suite and incorporates all the latest updates.
-# Copyright 2009 Raymond Hettinger, released under the MIT License.
-# http://code.activestate.com/recipes/576693/
-try:
-    from thread import get_ident as _get_ident
-except ImportError:
-    from dummy_thread import get_ident as _get_ident
-
-try:
-    from _abcoll import KeysView, ValuesView, ItemsView
-except ImportError:
-    pass
-
-
-class OrderedDict(dict):
-    'Dictionary that remembers insertion order'
-    # An inherited dict maps keys to values.
-    # The inherited dict provides __getitem__, __len__, __contains__, and get.
-    # The remaining methods are order-aware.
-    # Big-O running times for all methods are the same as for regular dictionaries.
-
-    # The internal self.__map dictionary maps keys to links in a doubly linked list.
-    # The circular doubly linked list starts and ends with a sentinel element.
-    # The sentinel element never gets deleted (this simplifies the algorithm).
-    # Each link is stored as a list of length three:  [PREV, NEXT, KEY].
-
-    def __init__(self, *args, **kwds):
-        '''Initialize an ordered dictionary.  Signature is the same as for
-        regular dictionaries, but keyword arguments are not recommended
-        because their insertion order is arbitrary.
-
-        '''
-        if len(args) > 1:
-            raise TypeError('expected at most 1 arguments, got %d' % len(args))
-        try:
-            self.__root
-        except AttributeError:
-            self.__root = root = []                     # sentinel node
-            root[:] = [root, root, None]
-            self.__map = {}
-        self.__update(*args, **kwds)
-
-    def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
-        'od.__setitem__(i, y) <==> od[i]=y'
-        # Setting a new item creates a new link which goes at the end of the linked
-        # list, and the inherited dictionary is updated with the new key/value pair.
-        if key not in self:
-            root = self.__root
-            last = root[0]
-            last[1] = root[0] = self.__map[key] = [last, root, key]
-        dict_setitem(self, key, value)
-
-    def __delitem__(self, key, dict_delitem=dict.__delitem__):
-        'od.__delitem__(y) <==> del od[y]'
-        # Deleting an existing item uses self.__map to find the link which is
-        # then removed by updating the links in the predecessor and successor nodes.
-        dict_delitem(self, key)
-        link_prev, link_next, key = self.__map.pop(key)
-        link_prev[1] = link_next
-        link_next[0] = link_prev
-
-    def __iter__(self):
-        'od.__iter__() <==> iter(od)'
-        root = self.__root
-        curr = root[1]
-        while curr is not root:
-            yield curr[2]
-            curr = curr[1]
-
-    def __reversed__(self):
-        'od.__reversed__() <==> reversed(od)'
-        root = self.__root
-        curr = root[0]
-        while curr is not root:
-            yield curr[2]
-            curr = curr[0]
-
-    def clear(self):
-        'od.clear() -> None.  Remove all items from od.'
-        try:
-            for node in self.__map.itervalues():
-                del node[:]
-            root = self.__root
-            root[:] = [root, root, None]
-            self.__map.clear()
-        except AttributeError:
-            pass
-        dict.clear(self)
-
-    def popitem(self, last=True):
-        '''od.popitem() -> (k, v), return and remove a (key, value) pair.
-        Pairs are returned in LIFO order if last is true or FIFO order if false.
-
-        '''
-        if not self:
-            raise KeyError('dictionary is empty')
-        root = self.__root
-        if last:
-            link = root[0]
-            link_prev = link[0]
-            link_prev[1] = root
-            root[0] = link_prev
-        else:
-            link = root[1]
-            link_next = link[1]
-            root[1] = link_next
-            link_next[0] = root
-        key = link[2]
-        del self.__map[key]
-        value = dict.pop(self, key)
-        return key, value
-
-    # -- the following methods do not depend on the internal structure --
-
-    def keys(self):
-        'od.keys() -> list of keys in od'
-        return list(self)
-
-    def values(self):
-        'od.values() -> list of values in od'
-        return [self[key] for key in self]
-
-    def items(self):
-        'od.items() -> list of (key, value) pairs in od'
-        return [(key, self[key]) for key in self]
-
-    def iterkeys(self):
-        'od.iterkeys() -> an iterator over the keys in od'
-        return iter(self)
-
-    def itervalues(self):
-        'od.itervalues -> an iterator over the values in od'
-        for k in self:
-            yield self[k]
-
-    def iteritems(self):
-        'od.iteritems -> an iterator over the (key, value) items in od'
-        for k in self:
-            yield (k, self[k])
-
-    def update(*args, **kwds):
-        '''od.update(E, **F) -> None.  Update od from dict/iterable E and F.
-
-        If E is a dict instance, does:           for k in E: od[k] = E[k]
-        If E has a .keys() method, does:         for k in E.keys(): od[k] = E[k]
-        Or if E is an iterable of items, does:   for k, v in E: od[k] = v
-        In either case, this is followed by:     for k, v in F.items(): od[k] = v
-
-        '''
-        if len(args) > 2:
-            raise TypeError('update() takes at most 2 positional '
-                            'arguments (%d given)' % (len(args),))
-        elif not args:
-            raise TypeError('update() takes at least 1 argument (0 given)')
-        self = args[0]
-        # Make progressively weaker assumptions about "other"
-        other = ()
-        if len(args) == 2:
-            other = args[1]
-        if isinstance(other, dict):
-            for key in other:
-                self[key] = other[key]
-        elif hasattr(other, 'keys'):
-            for key in other.keys():
-                self[key] = other[key]
-        else:
-            for key, value in other:
-                self[key] = value
-        for key, value in kwds.items():
-            self[key] = value
-
-    __update = update  # let subclasses override update without breaking __init__
-
-    __marker = object()
-
-    def pop(self, key, default=__marker):
-        '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value.
-        If key is not found, d is returned if given, otherwise KeyError is raised.
-
-        '''
-        if key in self:
-            result = self[key]
-            del self[key]
-            return result
-        if default is self.__marker:
-            raise KeyError(key)
-        return default
-
-    def setdefault(self, key, default=None):
-        'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
-        if key in self:
-            return self[key]
-        self[key] = default
-        return default
-
-    def __repr__(self, _repr_running={}):
-        'od.__repr__() <==> repr(od)'
-        call_key = id(self), _get_ident()
-        if call_key in _repr_running:
-            return '...'
-        _repr_running[call_key] = 1
-        try:
-            if not self:
-                return '%s()' % (self.__class__.__name__,)
-            return '%s(%r)' % (self.__class__.__name__, self.items())
-        finally:
-            del _repr_running[call_key]
-
-    def __reduce__(self):
-        'Return state information for pickling'
-        items = [[k, self[k]] for k in self]
-        inst_dict = vars(self).copy()
-        for k in vars(OrderedDict()):
-            inst_dict.pop(k, None)
-        if inst_dict:
-            return (self.__class__, (items,), inst_dict)
-        return self.__class__, (items,)
-
-    def copy(self):
-        'od.copy() -> a shallow copy of od'
-        return self.__class__(self)
-
-    @classmethod
-    def fromkeys(cls, iterable, value=None):
-        '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
-        and values equal to v (which defaults to None).
-
-        '''
-        d = cls()
-        for key in iterable:
-            d[key] = value
-        return d
-
-    def __eq__(self, other):
-        '''od.__eq__(y) <==> od==y.  Comparison to another OD is order-sensitive
-        while comparison to a regular mapping is order-insensitive.
-
-        '''
-        if isinstance(other, OrderedDict):
-            return len(self)==len(other) and self.items() == other.items()
-        return dict.__eq__(self, other)
-
-    def __ne__(self, other):
-        return not self == other
-
-    # -- the following methods are only used in Python 2.7 --
-
-    def viewkeys(self):
-        "od.viewkeys() -> a set-like object providing a view on od's keys"
-        return KeysView(self)
-
-    def viewvalues(self):
-        "od.viewvalues() -> an object providing a view on od's values"
-        return ValuesView(self)
-
-    def viewitems(self):
-        "od.viewitems() -> a set-like object providing a view on od's items"
-        return ItemsView(self)
diff --git a/ext/urllib3/packages/ssl_match_hostname/_implementation.py b/ext/urllib3/packages/ssl_match_hostname/_implementation.py
index 1fd42f38ae..d6e66c0196 100644
--- a/ext/urllib3/packages/ssl_match_hostname/_implementation.py
+++ b/ext/urllib3/packages/ssl_match_hostname/_implementation.py
@@ -9,8 +9,7 @@
 # ipaddress has been backported to 2.6+ in pypi.  If it is installed on the
 # system, use it to handle IPAddress ServerAltnames (this was added in
 # python-3.5) otherwise only do DNS matching.  This allows
-# backports.ssl_match_hostname to continue to be used all the way back to
-# python-2.4.
+# backports.ssl_match_hostname to continue to be used in Python 2.7.
 try:
     import ipaddress
 except ImportError:
diff --git a/ext/urllib3/poolmanager.py b/ext/urllib3/poolmanager.py
index 506a3c9b87..fe5491cfda 100644
--- a/ext/urllib3/poolmanager.py
+++ b/ext/urllib3/poolmanager.py
@@ -47,6 +47,7 @@
     'key__socks_options',  # dict
     'key_assert_hostname',  # bool or string
     'key_assert_fingerprint',  # str
+    'key_server_hostname', #str
 )
 
 #: The namedtuple class used to construct keys for the connection pool.
diff --git a/ext/urllib3/request.py b/ext/urllib3/request.py
index 1be3334113..8f2f44bb21 100644
--- a/ext/urllib3/request.py
+++ b/ext/urllib3/request.py
@@ -36,7 +36,7 @@ class RequestMethods(object):
         explicitly.
     """
 
-    _encode_url_methods = set(['DELETE', 'GET', 'HEAD', 'OPTIONS'])
+    _encode_url_methods = {'DELETE', 'GET', 'HEAD', 'OPTIONS'}
 
     def __init__(self, headers=None):
         self.headers = headers or {}
diff --git a/ext/urllib3/response.py b/ext/urllib3/response.py
index 9873cb9423..c112690b0a 100644
--- a/ext/urllib3/response.py
+++ b/ext/urllib3/response.py
@@ -11,7 +11,7 @@
     BodyNotHttplibCompatible, ProtocolError, DecodeError, ReadTimeoutError,
     ResponseNotChunked, IncompleteRead, InvalidHeader
 )
-from .packages.six import string_types as basestring, binary_type, PY3
+from .packages.six import string_types as basestring, PY3
 from .packages.six.moves import http_client as httplib
 from .connection import HTTPException, BaseSSLError
 from .util.response import is_fp_closed, is_response_to_head
@@ -23,7 +23,7 @@ class DeflateDecoder(object):
 
     def __init__(self):
         self._first_try = True
-        self._data = binary_type()
+        self._data = b''
         self._obj = zlib.decompressobj()
 
     def __getattr__(self, name):
@@ -69,9 +69,9 @@ def __getattr__(self, name):
         return getattr(self._obj, name)
 
     def decompress(self, data):
-        ret = binary_type()
+        ret = bytearray()
         if self._state == GzipDecoderState.SWALLOW_DATA or not data:
-            return ret
+            return bytes(ret)
         while True:
             try:
                 ret += self._obj.decompress(data)
@@ -81,16 +81,40 @@ def decompress(self, data):
                 self._state = GzipDecoderState.SWALLOW_DATA
                 if previous_state == GzipDecoderState.OTHER_MEMBERS:
                     # Allow trailing garbage acceptable in other gzip clients
-                    return ret
+                    return bytes(ret)
                 raise
             data = self._obj.unused_data
             if not data:
-                return ret
+                return bytes(ret)
             self._state = GzipDecoderState.OTHER_MEMBERS
             self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
 
 
+class MultiDecoder(object):
+    """
+    From RFC7231:
+        If one or more encodings have been applied to a representation, the
+        sender that applied the encodings MUST generate a Content-Encoding
+        header field that lists the content codings in the order in which
+        they were applied.
+    """
+
+    def __init__(self, modes):
+        self._decoders = [_get_decoder(m.strip()) for m in modes.split(',')]
+
+    def flush(self):
+        return self._decoders[0].flush()
+
+    def decompress(self, data):
+        for d in reversed(self._decoders):
+            data = d.decompress(data)
+        return data
+
+
 def _get_decoder(mode):
+    if ',' in mode:
+        return MultiDecoder(mode)
+
     if mode == 'gzip':
         return GzipDecoder()
 
@@ -159,7 +183,7 @@ def __init__(self, body='', headers=None, status=0, version=0, reason=None,
         self.msg = msg
         self._request_url = request_url
 
-        if body and isinstance(body, (basestring, binary_type)):
+        if body and isinstance(body, (basestring, bytes)):
             self._body = body
 
         self._pool = pool
@@ -283,8 +307,13 @@ def _init_decoder(self):
         # Note: content-encoding value should be case-insensitive, per RFC 7230
         # Section 3.2
         content_encoding = self.headers.get('content-encoding', '').lower()
-        if self._decoder is None and content_encoding in self.CONTENT_DECODERS:
-            self._decoder = _get_decoder(content_encoding)
+        if self._decoder is None:
+            if content_encoding in self.CONTENT_DECODERS:
+                self._decoder = _get_decoder(content_encoding)
+            elif ',' in content_encoding:
+                encodings = [e.strip() for e in content_encoding.split(',') if e.strip() in self.CONTENT_DECODERS]
+                if len(encodings):
+                    self._decoder = _get_decoder(content_encoding)
 
     def _decode(self, data, decode_content, flush_decoder):
         """
diff --git a/ext/urllib3/util/connection.py b/ext/urllib3/util/connection.py
index 5cf488f4b5..5ad70b2f1c 100644
--- a/ext/urllib3/util/connection.py
+++ b/ext/urllib3/util/connection.py
@@ -1,6 +1,7 @@
 from __future__ import absolute_import
 import socket
 from .wait import NoWayToWaitForSocketError, wait_for_read
+from ..contrib import _appengine_environ
 
 
 def is_connection_dropped(conn):  # Platform-specific
@@ -105,6 +106,13 @@ def _has_ipv6(host):
     sock = None
     has_ipv6 = False
 
+    # App Engine doesn't support IPV6 sockets and actually has a quota on the
+    # number of sockets that can be used, so just early out here instead of
+    # creating a socket needlessly.
+    # See https://github.com/urllib3/urllib3/issues/1446
+    if _appengine_environ.is_appengine_sandbox():
+        return False
+
     if socket.has_ipv6:
         # has_ipv6 returns true if cPython was compiled with IPv6 support.
         # It does not tell us if the system has IPv6 support enabled. To
diff --git a/ext/urllib3/util/response.py b/ext/urllib3/util/response.py
index 67cf730ab0..3d5486485a 100644
--- a/ext/urllib3/util/response.py
+++ b/ext/urllib3/util/response.py
@@ -59,8 +59,14 @@ def assert_header_parsing(headers):
     get_payload = getattr(headers, 'get_payload', None)
 
     unparsed_data = None
-    if get_payload:  # Platform-specific: Python 3.
-        unparsed_data = get_payload()
+    if get_payload:
+        # get_payload is actually email.message.Message.get_payload;
+        # we're only interested in the result if it's not a multipart message
+        if not headers.is_multipart():
+            payload = get_payload()
+
+            if isinstance(payload, (bytes, str)):
+                unparsed_data = payload
 
     if defects or unparsed_data:
         raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data)
diff --git a/ext/urllib3/util/retry.py b/ext/urllib3/util/retry.py
index 7ad3dc6608..e7d0abd610 100644
--- a/ext/urllib3/util/retry.py
+++ b/ext/urllib3/util/retry.py
@@ -115,7 +115,7 @@ class Retry(object):
         (most errors are resolved immediately by a second try without a
         delay). urllib3 will sleep for::
 
-            {backoff factor} * (2 ^ ({number of total retries} - 1))
+            {backoff factor} * (2 ** ({number of total retries} - 1))
 
         seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep
         for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer
diff --git a/ext/urllib3/util/ssl_.py b/ext/urllib3/util/ssl_.py
index 2893752a3d..64ea192a85 100644
--- a/ext/urllib3/util/ssl_.py
+++ b/ext/urllib3/util/ssl_.py
@@ -56,9 +56,8 @@ def _const_compare_digest_backport(a, b):
     OP_NO_COMPRESSION = 0x20000
 
 
-# Python 2.7 and earlier didn't have inet_pton on non-Linux
-# so we fallback on inet_aton in those cases. This means that
-# we can only detect IPv4 addresses in this case.
+# Python 2.7 doesn't have inet_pton on non-Linux so we fallback on inet_aton in
+# those cases. This means that we can only detect IPv4 addresses in this case.
 if hasattr(socket, 'inet_pton'):
     inet_pton = socket.inet_pton
 else:
@@ -67,7 +66,7 @@ def _const_compare_digest_backport(a, b):
         import ipaddress
 
         def inet_pton(_, host):
-            if isinstance(host, six.binary_type):
+            if isinstance(host, bytes):
                 host = host.decode('ascii')
             return ipaddress.ip_address(host)
 
@@ -115,10 +114,7 @@ def inet_pton(_, host):
 except ImportError:
     import sys
 
-    class SSLContext(object):  # Platform-specific: Python 2 & 3.1
-        supports_set_ciphers = ((2, 7) <= sys.version_info < (3,) or
-                                (3, 2) <= sys.version_info)
-
+    class SSLContext(object):  # Platform-specific: Python 2
         def __init__(self, protocol_version):
             self.protocol = protocol_version
             # Use default values from a real SSLContext
@@ -141,12 +137,6 @@ def load_verify_locations(self, cafile=None, capath=None):
                 raise SSLError("CA directories not supported in older Pythons")
 
         def set_ciphers(self, cipher_suite):
-            if not self.supports_set_ciphers:
-                raise TypeError(
-                    'Your version of Python does not support setting '
-                    'a custom cipher suite. Please upgrade to Python '
-                    '2.7, 3.2, or later if you need this functionality.'
-                )
             self.ciphers = cipher_suite
 
         def wrap_socket(self, socket, server_hostname=None, server_side=False):
@@ -167,10 +157,7 @@ def wrap_socket(self, socket, server_hostname=None, server_side=False):
                 'ssl_version': self.protocol,
                 'server_side': server_side,
             }
-            if self.supports_set_ciphers:  # Platform-specific: Python 2.7+
-                return wrap_socket(socket, ciphers=self.ciphers, **kwargs)
-            else:  # Platform-specific: Python 2.6
-                return wrap_socket(socket, **kwargs)
+            return wrap_socket(socket, ciphers=self.ciphers, **kwargs)
 
 
 def assert_fingerprint(cert, fingerprint):
@@ -276,6 +263,8 @@ def create_urllib3_context(ssl_version=None, cert_reqs=None,
     """
     context = SSLContext(ssl_version or ssl.PROTOCOL_SSLv23)
 
+    context.set_ciphers(ciphers or DEFAULT_CIPHERS)
+
     # Setting the default here, as we may have no ssl module on import
     cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs
 
@@ -291,9 +280,6 @@ def create_urllib3_context(ssl_version=None, cert_reqs=None,
 
     context.options |= options
 
-    if getattr(context, 'supports_set_ciphers', True):  # Platform-specific: Python 2.6
-        context.set_ciphers(ciphers or DEFAULT_CIPHERS)
-
     context.verify_mode = cert_reqs
     if getattr(context, 'check_hostname', None) is not None:  # Platform-specific: Python 3.2
         # We do our own verification, including fingerprints and alternative
@@ -316,8 +302,7 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
         A pre-made :class:`SSLContext` object. If none is provided, one will
         be created using :func:`create_urllib3_context`.
     :param ciphers:
-        A string of ciphers we wish the client to support. This is not
-        supported on Python 2.6 as the ssl module does not support it.
+        A string of ciphers we wish the client to support.
     :param ca_cert_dir:
         A directory containing CA certificates in multiple separate files, as
         supported by OpenSSL's -CApath flag or the capath argument to
@@ -334,7 +319,7 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
     if ca_certs or ca_cert_dir:
         try:
             context.load_verify_locations(ca_certs, ca_cert_dir)
-        except IOError as e:  # Platform-specific: Python 2.6, 2.7, 3.2
+        except IOError as e:  # Platform-specific: Python 2.7
             raise SSLError(e)
         # Py33 raises FileNotFoundError which subclasses OSError
         # These are not equivalent unless we check the errno attribute
@@ -378,7 +363,7 @@ def is_ipaddress(hostname):
     :param str hostname: Hostname to examine.
     :return: True if the hostname is an IP address, False otherwise.
     """
-    if six.PY3 and isinstance(hostname, six.binary_type):
+    if six.PY3 and isinstance(hostname, bytes):
         # IDN A-label bytes are ASCII compatible.
         hostname = hostname.decode('ascii')
 
diff --git a/ext/urllib3/util/wait.py b/ext/urllib3/util/wait.py
index fa686eff48..4db71bafd8 100644
--- a/ext/urllib3/util/wait.py
+++ b/ext/urllib3/util/wait.py
@@ -43,9 +43,6 @@ def _retry_on_intr(fn, timeout):
 else:
     # Old and broken Pythons.
     def _retry_on_intr(fn, timeout):
-        if timeout is not None and timeout <= 0:
-            return fn(timeout)
-
         if timeout is None:
             deadline = float("inf")
         else:
@@ -117,7 +114,7 @@ def _have_working_poll():
     # from libraries like eventlet/greenlet.
     try:
         poll_obj = select.poll()
-        poll_obj.poll(0)
+        _retry_on_intr(poll_obj.poll, 0)
     except (AttributeError, OSError):
         return False
     else:
diff --git a/ext/validators/__init__.py b/ext/validators/__init__.py
index e4ccfd5311..458ed98714 100644
--- a/ext/validators/__init__.py
+++ b/ext/validators/__init__.py
@@ -14,4 +14,4 @@
 from .utils import ValidationFailure, validator  # noqa
 from .uuid import uuid  # noqa
 
-__version__ = '0.12.3'
+__version__ = '0.12.4'
diff --git a/ext/validators/utils.py b/ext/validators/utils.py
index 6a892fcb0c..a36184be53 100644
--- a/ext/validators/utils.py
+++ b/ext/validators/utils.py
@@ -37,10 +37,15 @@ def func_args_as_dict(func, args, kwargs):
     Return given function's positional and key value arguments as an ordered
     dictionary.
     """
+    if six.PY2:
+        _getargspec = inspect.getargspec
+    else:
+        _getargspec = inspect.getfullargspec
+
     arg_names = list(
         OrderedDict.fromkeys(
             itertools.chain(
-                inspect.getargspec(func)[0],
+                _getargspec(func)[0],
                 kwargs.keys()
             )
         )
diff --git a/ext2/backports/__init__.py b/ext2/backports/__init__.py
new file mode 100644
index 0000000000..febdb2f820
--- /dev/null
+++ b/ext2/backports/__init__.py
@@ -0,0 +1,5 @@
+# A Python "namespace package" http://www.python.org/dev/peps/pep-0382/
+# This always goes inside of a namespace package's __init__.py
+
+from pkgutil import extend_path
+__path__ = extend_path(__path__, __name__)
diff --git a/ext/backports/configparser/__init__.py b/ext2/backports/configparser/__init__.py
similarity index 97%
rename from ext/backports/configparser/__init__.py
rename to ext2/backports/configparser/__init__.py
index 06d7a0855f..a723399198 100644
--- a/ext/backports/configparser/__init__.py
+++ b/ext2/backports/configparser/__init__.py
@@ -1,5 +1,6 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
+# flake8: noqa
 
 """Configuration file parser.
 
@@ -64,7 +65,7 @@
         Return list of configuration options for the named section.
 
     read(filenames, encoding=None)
-        Read and parse the list of named configuration files, given by
+        Read and parse the iterable of named configuration files, given by
         name.  A single filename is also allowed.  Non-existing files
         are ignored.  Return list of successfully read files.
 
@@ -127,10 +128,10 @@
 from __future__ import print_function
 from __future__ import unicode_literals
 
-from collections import MutableMapping
 import functools
 import io
 import itertools
+import os
 import re
 import sys
 import warnings
@@ -138,6 +139,8 @@
 from backports.configparser.helpers import OrderedDict as _default_dict
 from backports.configparser.helpers import ChainMap as _ChainMap
 from backports.configparser.helpers import from_none, open, str, PY2
+from backports.configparser.helpers import PathLike, fspath
+from backports.configparser.helpers import MutableMapping
 
 __all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError",
            "NoOptionError", "InterpolationError", "InterpolationDepthError",
@@ -606,9 +609,6 @@ def __init__(self, defaults=None, dict_type=_default_dict,
         self._converters = ConverterMapping(self)
         self._proxies = self._dict()
         self._proxies[default_section] = SectionProxy(self, default_section)
-        if defaults:
-            for key, value in defaults.items():
-                self._defaults[self.optionxform(key)] = value
         self._delimiters = tuple(delimiters)
         if delimiters == ('=', ':'):
             self._optcre = self.OPTCRE_NV if allow_no_value else self.OPTCRE
@@ -633,6 +633,8 @@ def __init__(self, defaults=None, dict_type=_default_dict,
             self._interpolation = Interpolation()
         if converters is not _UNSET:
             self._converters.update(converters)
+        if defaults:
+            self._read_defaults(defaults)
 
     def defaults(self):
         return self._defaults
@@ -673,33 +675,23 @@ def options(self, section):
         return list(opts.keys())
 
     def read(self, filenames, encoding=None):
-        """Read and parse a filename or a list of filenames.
+        """Read and parse a filename or an iterable of filenames.
 
         Files that cannot be opened are silently ignored; this is
-        designed so that you can specify a list of potential
+        designed so that you can specify an iterable of potential
         configuration file locations (e.g. current directory, user's
         home directory, systemwide directory), and all existing
-        configuration files in the list will be read.  A single
+        configuration files in the iterable will be read.  A single
         filename may also be given.
 
         Return list of successfully read files.
         """
-        if PY2 and isinstance(filenames, bytes):
-            # we allow for a little unholy magic for Python 2 so that
-            # people not using unicode_literals can still use the library
-            # conveniently
-            warnings.warn(
-                "You passed a bytestring as `filenames`. This will not work"
-                " on Python 3. Use `cp.read_file()` or switch to using Unicode"
-                " strings across the board.",
-                DeprecationWarning,
-                stacklevel=2,
-            )
-            filenames = [filenames]
-        elif isinstance(filenames, str):
+        if isinstance(filenames, (str, bytes, PathLike)):
             filenames = [filenames]
         read_ok = []
         for filename in filenames:
+            if isinstance(filename, PathLike):
+                filename = fspath(filename)
             try:
                 with open(filename, encoding=encoding) as fp:
                     self._read(fp, filename)
@@ -1126,10 +1118,10 @@ def _read(self, fp, fpname):
                         # raised at the end of the file and will contain a
                         # list of all bogus lines
                         e = self._handle_error(e, fpname, lineno, line)
+        self._join_multiline_values()
         # if any parsing errors occurred, raise an exception
         if e:
             raise e
-        self._join_multiline_values()
 
     def _join_multiline_values(self):
         defaults = self.default_section, self._defaults
@@ -1143,6 +1135,12 @@ def _join_multiline_values(self):
                                                                 section,
                                                                 name, val)
 
+    def _read_defaults(self, defaults):
+        """Read the defaults passed in the initializer.
+        Note: values can be non-string."""
+        for key, value in defaults.items():
+            self._defaults[self.optionxform(key)] = value
+
     def _handle_error(self, exc, fpname, lineno, line):
         if not exc:
             exc = ParsingError(fpname)
@@ -1245,6 +1243,19 @@ def add_section(self, section):
         section, _, _ = self._validate_value_types(section=section)
         super(ConfigParser, self).add_section(section)
 
+    def _read_defaults(self, defaults):
+        """Reads the defaults passed in the initializer, implicitly converting
+        values to strings like the rest of the API.
+
+        Does not perform interpolation for backwards compatibility.
+        """
+        try:
+            hold_interpolation = self._interpolation
+            self._interpolation = Interpolation()
+            self.read_dict({self.default_section: defaults})
+        finally:
+            self._interpolation = hold_interpolation
+
 
 class SafeConfigParser(ConfigParser):
     """ConfigParser alias for backwards compatibility purposes."""
diff --git a/ext/backports/configparser/helpers.py b/ext2/backports/configparser/helpers.py
similarity index 58%
rename from ext/backports/configparser/helpers.py
rename to ext2/backports/configparser/helpers.py
index c47662f3c9..2d743fbad6 100644
--- a/ext/backports/configparser/helpers.py
+++ b/ext2/backports/configparser/helpers.py
@@ -6,7 +6,14 @@
 from __future__ import print_function
 from __future__ import unicode_literals
 
-from collections import MutableMapping
+import abc
+import os
+
+try:
+    from collections.abc import MutableMapping
+except ImportError:
+    from collections import MutableMapping
+
 try:
     from collections import UserDict
 except ImportError:
@@ -17,6 +24,11 @@
 except ImportError:
     from ordereddict import OrderedDict
 
+try:
+    import pathlib
+except ImportError:
+    pathlib = None
+
 from io import open
 import sys
 try:
@@ -28,9 +40,13 @@
         from _dummy_thread import get_ident
 
 
+__all__ = ['UserDict', 'OrderedDict', 'open']
+
+
 PY2 = sys.version_info[0] == 2
 PY3 = sys.version_info[0] == 3
 
+native_str = str
 str = type('str')
 
 
@@ -68,6 +84,7 @@ def wrapper(self):
 
     return decorating_function
 
+
 # from collections 3.2.1
 class _ChainMap(MutableMapping):
     ''' A ChainMap groups multiple dicts (or other mappings) together
@@ -95,16 +112,19 @@ def __missing__(self, key):
     def __getitem__(self, key):
         for mapping in self.maps:
             try:
-                return mapping[key]             # can't use 'key in mapping' with defaultdict
+                # can't use 'key in mapping' with defaultdict
+                return mapping[key]
             except KeyError:
                 pass
-        return self.__missing__(key)            # support subclasses that define __missing__
+        # support subclasses that define __missing__
+        return self.__missing__(key)
 
     def get(self, key, default=None):
         return self[key] if key in self else default
 
     def __len__(self):
-        return len(set().union(*self.maps))     # reuses stored hash values if possible
+        # reuses stored hash values if possible
+        return len(set().union(*self.maps))
 
     def __iter__(self):
         return iter(set().union(*self.maps))
@@ -123,7 +143,10 @@ def fromkeys(cls, iterable, *args):
         return cls(dict.fromkeys(iterable, *args))
 
     def copy(self):
-        'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
+        """
+        New ChainMap or subclass with a new copy of
+        maps[0] and refs to maps[1:]
+        """
         return self.__class__(self.maps[0].copy(), *self.maps[1:])
 
     __copy__ = copy
@@ -144,21 +167,30 @@ def __delitem__(self, key):
         try:
             del self.maps[0][key]
         except KeyError:
-            raise KeyError('Key not found in the first mapping: {!r}'.format(key))
+            raise KeyError(
+                'Key not found in the first mapping: {!r}'.format(key))
 
     def popitem(self):
-        'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
+        """
+        Remove and return an item pair from maps[0].
+        Raise KeyError is maps[0] is empty.
+        """
         try:
             return self.maps[0].popitem()
         except KeyError:
             raise KeyError('No keys found in the first mapping.')
 
     def pop(self, key, *args):
-        'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
+        """
+        Remove *key* from maps[0] and return its value.
+        Raise KeyError if *key* not in maps[0].
+        """
+
         try:
             return self.maps[0].pop(key, *args)
         except KeyError:
-            raise KeyError('Key not found in the first mapping: {!r}'.format(key))
+            raise KeyError(
+                'Key not found in the first mapping: {!r}'.format(key))
 
     def clear(self):
         'Clear maps[0], leaving maps[1:] intact.'
@@ -169,3 +201,73 @@ def clear(self):
     from collections import ChainMap
 except ImportError:
     ChainMap = _ChainMap
+
+
+_ABC = getattr(
+    abc, 'ABC',
+    # Python 3.3 compatibility
+    abc.ABCMeta(
+        native_str('__ABC'),
+        (object,),
+        dict(__metaclass__=abc.ABCMeta),
+    ),
+)
+
+
+class _PathLike(_ABC):
+
+    """Abstract base class for implementing the file system path protocol."""
+
+    @abc.abstractmethod
+    def __fspath__(self):
+        """Return the file system path representation of the object."""
+        raise NotImplementedError
+
+    @classmethod
+    def __subclasshook__(cls, subclass):
+        return bool(
+            hasattr(subclass, '__fspath__')
+            # workaround for Python 3.5
+            or pathlib and issubclass(subclass, pathlib.Path)
+        )
+
+
+PathLike = getattr(os, 'PathLike', _PathLike)
+
+
+def _fspath(path):
+    """Return the path representation of a path-like object.
+
+    If str or bytes is passed in, it is returned unchanged. Otherwise the
+    os.PathLike interface is used to get the path representation. If the
+    path representation is not str or bytes, TypeError is raised. If the
+    provided path is not str, bytes, or os.PathLike, TypeError is raised.
+    """
+    if isinstance(path, (str, bytes)):
+        return path
+
+    if not hasattr(path, '__fspath__') and isinstance(path, pathlib.Path):
+        # workaround for Python 3.5
+        return str(path)
+
+    # Work from the object's type to match method resolution of other magic
+    # methods.
+    path_type = type(path)
+    try:
+        path_repr = path_type.__fspath__(path)
+    except AttributeError:
+
+        if hasattr(path_type, '__fspath__'):
+            raise
+        else:
+            raise TypeError("expected str, bytes or os.PathLike object, "
+                            "not " + path_type.__name__)
+    if isinstance(path_repr, (str, bytes)):
+        return path_repr
+    else:
+        raise TypeError("expected {}.__fspath__() to return str or bytes, "
+                        "not {}".format(path_type.__name__,
+                                        type(path_repr).__name__))
+
+
+fspath = getattr(os, 'fspath', _fspath)
diff --git a/ext2/backports/functools_lru_cache.py b/ext2/backports/functools_lru_cache.py
new file mode 100644
index 0000000000..707c6c766d
--- /dev/null
+++ b/ext2/backports/functools_lru_cache.py
@@ -0,0 +1,184 @@
+from __future__ import absolute_import
+
+import functools
+from collections import namedtuple
+from threading import RLock
+
+_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])
+
+
+@functools.wraps(functools.update_wrapper)
+def update_wrapper(wrapper,
+                   wrapped,
+                   assigned = functools.WRAPPER_ASSIGNMENTS,
+                   updated = functools.WRAPPER_UPDATES):
+    """
+    Patch two bugs in functools.update_wrapper.
+    """
+    # workaround for http://bugs.python.org/issue3445
+    assigned = tuple(attr for attr in assigned if hasattr(wrapped, attr))
+    wrapper = functools.update_wrapper(wrapper, wrapped, assigned, updated)
+    # workaround for https://bugs.python.org/issue17482
+    wrapper.__wrapped__ = wrapped
+    return wrapper
+
+
+class _HashedSeq(list):
+    __slots__ = 'hashvalue'
+
+    def __init__(self, tup, hash=hash):
+        self[:] = tup
+        self.hashvalue = hash(tup)
+
+    def __hash__(self):
+        return self.hashvalue
+
+
+def _make_key(args, kwds, typed,
+              kwd_mark=(object(),),
+              fasttypes=set([int, str, frozenset, type(None)]),
+              sorted=sorted, tuple=tuple, type=type, len=len):
+    'Make a cache key from optionally typed positional and keyword arguments'
+    key = args
+    if kwds:
+        sorted_items = sorted(kwds.items())
+        key += kwd_mark
+        for item in sorted_items:
+            key += item
+    if typed:
+        key += tuple(type(v) for v in args)
+        if kwds:
+            key += tuple(type(v) for k, v in sorted_items)
+    elif len(key) == 1 and type(key[0]) in fasttypes:
+        return key[0]
+    return _HashedSeq(key)
+
+
+def lru_cache(maxsize=100, typed=False):
+    """Least-recently-used cache decorator.
+
+    If *maxsize* is set to None, the LRU features are disabled and the cache
+    can grow without bound.
+
+    If *typed* is True, arguments of different types will be cached separately.
+    For example, f(3.0) and f(3) will be treated as distinct calls with
+    distinct results.
+
+    Arguments to the cached function must be hashable.
+
+    View the cache statistics named tuple (hits, misses, maxsize, currsize) with
+    f.cache_info().  Clear the cache and statistics with f.cache_clear().
+    Access the underlying function with f.__wrapped__.
+
+    See:  http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used
+
+    """
+
+    # Users should only access the lru_cache through its public API:
+    #       cache_info, cache_clear, and f.__wrapped__
+    # The internals of the lru_cache are encapsulated for thread safety and
+    # to allow the implementation to change (including a possible C version).
+
+    def decorating_function(user_function):
+
+        cache = dict()
+        stats = [0, 0]                  # make statistics updateable non-locally
+        HITS, MISSES = 0, 1             # names for the stats fields
+        make_key = _make_key
+        cache_get = cache.get           # bound method to lookup key or return None
+        _len = len                      # localize the global len() function
+        lock = RLock()                  # because linkedlist updates aren't threadsafe
+        root = []                       # root of the circular doubly linked list
+        root[:] = [root, root, None, None]      # initialize by pointing to self
+        nonlocal_root = [root]                  # make updateable non-locally
+        PREV, NEXT, KEY, RESULT = 0, 1, 2, 3    # names for the link fields
+
+        if maxsize == 0:
+
+            def wrapper(*args, **kwds):
+                # no caching, just do a statistics update after a successful call
+                result = user_function(*args, **kwds)
+                stats[MISSES] += 1
+                return result
+
+        elif maxsize is None:
+
+            def wrapper(*args, **kwds):
+                # simple caching without ordering or size limit
+                key = make_key(args, kwds, typed)
+                result = cache_get(key, root)   # root used here as a unique not-found sentinel
+                if result is not root:
+                    stats[HITS] += 1
+                    return result
+                result = user_function(*args, **kwds)
+                cache[key] = result
+                stats[MISSES] += 1
+                return result
+
+        else:
+
+            def wrapper(*args, **kwds):
+                # size limited caching that tracks accesses by recency
+                key = make_key(args, kwds, typed) if kwds or typed else args
+                with lock:
+                    link = cache_get(key)
+                    if link is not None:
+                        # record recent use of the key by moving it to the front of the list
+                        root, = nonlocal_root
+                        link_prev, link_next, key, result = link
+                        link_prev[NEXT] = link_next
+                        link_next[PREV] = link_prev
+                        last = root[PREV]
+                        last[NEXT] = root[PREV] = link
+                        link[PREV] = last
+                        link[NEXT] = root
+                        stats[HITS] += 1
+                        return result
+                result = user_function(*args, **kwds)
+                with lock:
+                    root, = nonlocal_root
+                    if key in cache:
+                        # getting here means that this same key was added to the
+                        # cache while the lock was released.  since the link
+                        # update is already done, we need only return the
+                        # computed result and update the count of misses.
+                        pass
+                    elif _len(cache) >= maxsize:
+                        # use the old root to store the new key and result
+                        oldroot = root
+                        oldroot[KEY] = key
+                        oldroot[RESULT] = result
+                        # empty the oldest link and make it the new root
+                        root = nonlocal_root[0] = oldroot[NEXT]
+                        oldkey = root[KEY]
+                        root[KEY] = root[RESULT] = None
+                        # now update the cache dictionary for the new links
+                        del cache[oldkey]
+                        cache[key] = oldroot
+                    else:
+                        # put result in a new link at the front of the list
+                        last = root[PREV]
+                        link = [last, root, key, result]
+                        last[NEXT] = root[PREV] = cache[key] = link
+                    stats[MISSES] += 1
+                return result
+
+        def cache_info():
+            """Report cache statistics"""
+            with lock:
+                return _CacheInfo(stats[HITS], stats[MISSES], maxsize, len(cache))
+
+        def cache_clear():
+            """Clear the cache and cache statistics"""
+            with lock:
+                cache.clear()
+                root = nonlocal_root[0]
+                root[:] = [root, root, None, None]
+                stats[:] = [0, 0]
+
+        wrapper.__wrapped__ = user_function
+        wrapper.cache_info = cache_info
+        wrapper.cache_clear = cache_clear
+        return update_wrapper(wrapper, user_function)
+
+    return decorating_function
diff --git a/ext2/bs4/__init__.py b/ext2/bs4/__init__.py
index 470177fdfd..d3a10869d6 100644
--- a/ext2/bs4/__init__.py
+++ b/ext2/bs4/__init__.py
@@ -17,12 +17,10 @@
 
 """
 
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
 __author__ = "Leonard Richardson (leonardr@segfault.org)"
-__version__ = "4.6.3"
-__copyright__ = "Copyright (c) 2004-2018 Leonard Richardson"
+__version__ = "4.7.1"
+__copyright__ = "Copyright (c) 2004-2019 Leonard Richardson"
+# Use of this source code is governed by the MIT license.
 __license__ = "MIT"
 
 __all__ = ['BeautifulSoup']
@@ -237,10 +235,11 @@ def deprecated_argument(old_name, new_name):
         self.builder = builder
         self.is_xml = builder.is_xml
         self.known_xml = self.is_xml
-        self.builder.soup = self
-
+        self._namespaces = dict()
         self.parse_only = parse_only
 
+        self.builder.initialize_soup(self)
+
         if hasattr(markup, 'read'):        # It's a file-type object.
             markup = markup.read()
         elif len(markup) <= 256 and (
@@ -382,7 +381,7 @@ def popTag(self):
 
     def pushTag(self, tag):
         #print "Push", tag.name
-        if self.currentTag:
+        if self.currentTag is not None:
             self.currentTag.contents.append(tag)
         self.tagStack.append(tag)
         self.currentTag = self.tagStack[-1]
@@ -421,60 +420,71 @@ def endData(self, containerClass=NavigableString):
 
     def object_was_parsed(self, o, parent=None, most_recent_element=None):
         """Add an object to the parse tree."""
-        parent = parent or self.currentTag
-        previous_element = most_recent_element or self._most_recent_element
+        if parent is None:
+            parent = self.currentTag
+        if most_recent_element is not None:
+            previous_element = most_recent_element
+        else:
+            previous_element = self._most_recent_element
 
         next_element = previous_sibling = next_sibling = None
         if isinstance(o, Tag):
             next_element = o.next_element
             next_sibling = o.next_sibling
             previous_sibling = o.previous_sibling
-            if not previous_element:
+            if previous_element is None:
                 previous_element = o.previous_element
 
+        fix = parent.next_element is not None
+
         o.setup(parent, previous_element, next_element, previous_sibling, next_sibling)
 
         self._most_recent_element = o
         parent.contents.append(o)
 
-        if parent.next_sibling:
-            # This node is being inserted into an element that has
-            # already been parsed. Deal with any dangling references.
-            index = len(parent.contents)-1
-            while index >= 0:
-                if parent.contents[index] is o:
-                    break
-                index -= 1
-            else:
-                raise ValueError(
-                    "Error building tree: supposedly %r was inserted "
-                    "into %r after the fact, but I don't see it!" % (
-                        o, parent
-                    )
-                )
-            if index == 0:
-                previous_element = parent
-                previous_sibling = None
-            else:
-                previous_element = previous_sibling = parent.contents[index-1]
-            if index == len(parent.contents)-1:
-                next_element = parent.next_sibling
-                next_sibling = None
-            else:
-                next_element = next_sibling = parent.contents[index+1]
-
-            o.previous_element = previous_element
-            if previous_element:
-                previous_element.next_element = o
-            o.next_element = next_element
-            if next_element:
-                next_element.previous_element = o
-            o.next_sibling = next_sibling
-            if next_sibling:
-                next_sibling.previous_sibling = o
-            o.previous_sibling = previous_sibling
-            if previous_sibling:
-                previous_sibling.next_sibling = o
+        # Check if we are inserting into an already parsed node.
+        if fix:
+            self._linkage_fixer(parent)
+
+    def _linkage_fixer(self, el):
+        """Make sure linkage of this fragment is sound."""
+
+        first = el.contents[0]
+        child = el.contents[-1]
+        descendant = child
+
+        if child is first and el.parent is not None:
+            # Parent should be linked to first child
+            el.next_element = child
+            # We are no longer linked to whatever this element is
+            prev_el = child.previous_element
+            if prev_el is not None and prev_el is not el:
+                prev_el.next_element = None
+            # First child should be linked to the parent, and no previous siblings.
+            child.previous_element = el
+            child.previous_sibling = None
+
+        # We have no sibling as we've been appended as the last.
+        child.next_sibling = None
+
+        # This index is a tag, dig deeper for a "last descendant"
+        if isinstance(child, Tag) and child.contents:
+            descendant = child._last_descendant(False)
+
+        # As the final step, link last descendant. It should be linked
+        # to the parent's next sibling (if found), else walk up the chain
+        # and find a parent with a sibling. It should have no next sibling.
+        descendant.next_element = None
+        descendant.next_sibling = None
+        target = el
+        while True:
+            if target is None:
+                break
+            elif target.next_sibling is not None:
+                descendant.next_element = target.next_sibling
+                target.next_sibling.previous_element = child
+                break
+            target = target.parent
 
     def _popToTag(self, name, nsprefix=None, inclusivePop=True):
         """Pops the tag stack up to and including the most recent
@@ -520,7 +530,7 @@ def handle_starttag(self, name, namespace, nsprefix, attrs):
                   self.currentTag, self._most_recent_element)
         if tag is None:
             return tag
-        if self._most_recent_element:
+        if self._most_recent_element is not None:
             self._most_recent_element.next_element = tag
         self._most_recent_element = tag
         self.pushTag(tag)
diff --git a/ext2/bs4/builder/__init__.py b/ext2/bs4/builder/__init__.py
index c9e3f3d31f..42077503f7 100644
--- a/ext2/bs4/builder/__init__.py
+++ b/ext2/bs4/builder/__init__.py
@@ -1,5 +1,5 @@
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
+# Use of this source code is governed by the MIT license.
+__license__ = "MIT"
 
 from collections import defaultdict
 import itertools
@@ -8,7 +8,7 @@
     CharsetMetaAttributeValue,
     ContentMetaAttributeValue,
     HTMLAwareEntitySubstitution,
-    whitespace_re
+    nonwhitespace_re
     )
 
 __all__ = [
@@ -102,6 +102,12 @@ class TreeBuilder(object):
     def __init__(self):
         self.soup = None
 
+    def initialize_soup(self, soup):
+        """The BeautifulSoup object has been initialized and is now
+        being associated with the TreeBuilder.
+        """
+        self.soup = soup
+        
     def reset(self):
         pass
 
@@ -167,7 +173,7 @@ def _replace_cdata_list_attribute_values(self, tag_name, attrs):
                     # values. Split it into a list.
                     value = attrs[attr]
                     if isinstance(value, basestring):
-                        values = whitespace_re.split(value)
+                        values = nonwhitespace_re.findall(value)
                     else:
                         # html5lib sometimes calls setAttributes twice
                         # for the same tag when rearranging the parse
diff --git a/ext2/bs4/builder/_html5lib.py b/ext2/bs4/builder/_html5lib.py
index 5f54893583..6fa8593118 100644
--- a/ext2/bs4/builder/_html5lib.py
+++ b/ext2/bs4/builder/_html5lib.py
@@ -1,5 +1,5 @@
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
+# Use of this source code is governed by the MIT license.
+__license__ = "MIT"
 
 __all__ = [
     'HTML5TreeBuilder',
@@ -15,7 +15,7 @@
     )
 from bs4.element import (
     NamespacedAttribute,
-    whitespace_re,
+    nonwhitespace_re,
 )
 import html5lib
 from html5lib.constants import (
@@ -206,7 +206,7 @@ def __setitem__(self, name, value):
             # A node that is being cloned may have already undergone
             # this procedure.
             if not isinstance(value, list):
-                value = whitespace_re.split(value)
+                value = nonwhitespace_re.findall(value)
         self.element[name] = value
     def items(self):
         return list(self.attrs.items())
@@ -249,7 +249,7 @@ def appendChild(self, node):
         if not isinstance(child, basestring) and child.parent is not None:
             node.element.extract()
 
-        if (string_child and self.element.contents
+        if (string_child is not None and self.element.contents
             and self.element.contents[-1].__class__ == NavigableString):
             # We are appending a string onto another string.
             # TODO This has O(n^2) performance, for input like
@@ -360,16 +360,16 @@ def reparentChildren(self, new_parent):
             # Set the first child's previous_element and previous_sibling
             # to elements within the new parent
             first_child = to_append[0]
-            if new_parents_last_descendant:
+            if new_parents_last_descendant is not None:
                 first_child.previous_element = new_parents_last_descendant
             else:
                 first_child.previous_element = new_parent_element
             first_child.previous_sibling = new_parents_last_child
-            if new_parents_last_descendant:
+            if new_parents_last_descendant is not None:
                 new_parents_last_descendant.next_element = first_child
             else:
                 new_parent_element.next_element = first_child
-            if new_parents_last_child:
+            if new_parents_last_child is not None:
                 new_parents_last_child.next_sibling = first_child
 
             # Find the very last element being moved. It is now the
@@ -379,7 +379,7 @@ def reparentChildren(self, new_parent):
             last_childs_last_descendant = to_append[-1]._last_descendant(False, True)
 
             last_childs_last_descendant.next_element = new_parents_last_descendant_next_element
-            if new_parents_last_descendant_next_element:
+            if new_parents_last_descendant_next_element is not None:
                 # TODO: This code has no test coverage and I'm not sure
                 # how to get html5lib to go through this path, but it's
                 # just the other side of the previous line.
diff --git a/ext2/bs4/builder/_htmlparser.py b/ext2/bs4/builder/_htmlparser.py
index ee6c685df5..ff09ca3109 100644
--- a/ext2/bs4/builder/_htmlparser.py
+++ b/ext2/bs4/builder/_htmlparser.py
@@ -1,8 +1,8 @@
 # encoding: utf-8
 """Use the HTMLParser library to parse HTML files that aren't too bad."""
 
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
+# Use of this source code is governed by the MIT license.
+__license__ = "MIT"
 
 __all__ = [
     'HTMLParserTreeBuilder',
diff --git a/ext2/bs4/builder/_lxml.py b/ext2/bs4/builder/_lxml.py
index 4a0f7de4b1..b7e172cc9a 100644
--- a/ext2/bs4/builder/_lxml.py
+++ b/ext2/bs4/builder/_lxml.py
@@ -1,5 +1,6 @@
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
+# Use of this source code is governed by the MIT license.
+__license__ = "MIT"
+
 __all__ = [
     'LXMLTreeBuilderForXML',
     'LXMLTreeBuilder',
@@ -32,6 +33,10 @@
 
 LXML = 'lxml'
 
+def _invert(d):
+    "Invert a dictionary."
+    return dict((v,k) for k, v in d.items())
+
 class LXMLTreeBuilderForXML(TreeBuilder):
     DEFAULT_PARSER_CLASS = etree.XMLParser
 
@@ -48,7 +53,29 @@ class LXMLTreeBuilderForXML(TreeBuilder):
 
     # This namespace mapping is specified in the XML Namespace
     # standard.
-    DEFAULT_NSMAPS = {'http://www.w3.org/XML/1998/namespace' : "xml"}
+    DEFAULT_NSMAPS = dict(xml='http://www.w3.org/XML/1998/namespace')
+
+    DEFAULT_NSMAPS_INVERTED = _invert(DEFAULT_NSMAPS)
+
+    def initialize_soup(self, soup):
+        """Let the BeautifulSoup object know about the standard namespace
+        mapping.
+        """
+        super(LXMLTreeBuilderForXML, self).initialize_soup(soup)
+        self._register_namespaces(self.DEFAULT_NSMAPS)
+
+    def _register_namespaces(self, mapping):
+        """Let the BeautifulSoup object know about namespaces encountered
+        while parsing the document.
+
+        This might be useful later on when creating CSS selectors.
+        """
+        for key, value in mapping.items():
+            if key and key not in self.soup._namespaces:
+                # Let the BeautifulSoup object know about a new namespace.
+                # If there are multiple namespaces defined with the same
+                # prefix, the first one in the document takes precedence.
+                self.soup._namespaces[key] = value
 
     def default_parser(self, encoding):
         # This can either return a parser object or a class, which
@@ -75,8 +102,8 @@ def __init__(self, parser=None, empty_element_tags=None):
         if empty_element_tags is not None:
             self.empty_element_tags = set(empty_element_tags)
         self.soup = None
-        self.nsmaps = [self.DEFAULT_NSMAPS]
-
+        self.nsmaps = [self.DEFAULT_NSMAPS_INVERTED]
+        
     def _getNsTag(self, tag):
         # Split the namespace URL out of a fully-qualified lxml tag
         # name. Copied from lxml's src/lxml/sax.py.
@@ -144,7 +171,7 @@ def feed(self, markup):
             raise ParserRejectedMarkup(str(e))
 
     def close(self):
-        self.nsmaps = [self.DEFAULT_NSMAPS]
+        self.nsmaps = [self.DEFAULT_NSMAPS_INVERTED]
 
     def start(self, name, attrs, nsmap={}):
         # Make sure attrs is a mutable dict--lxml may send an immutable dictproxy.
@@ -158,8 +185,14 @@ def start(self, name, attrs, nsmap={}):
                 self.nsmaps.append(None)
         elif len(nsmap) > 0:
             # A new namespace mapping has come into play.
-            inverted_nsmap = dict((value, key) for key, value in nsmap.items())
-            self.nsmaps.append(inverted_nsmap)
+
+            # First, Let the BeautifulSoup object know about it.
+            self._register_namespaces(nsmap)
+
+            # Then, add it to our running list of inverted namespace
+            # mappings.
+            self.nsmaps.append(_invert(nsmap))
+
             # Also treat the namespace mapping as a set of attributes on the
             # tag, so we can recreate it later.
             attrs = attrs.copy()
diff --git a/ext2/bs4/dammit.py b/ext2/bs4/dammit.py
index be46b39427..fb2f8b8ed6 100644
--- a/ext2/bs4/dammit.py
+++ b/ext2/bs4/dammit.py
@@ -6,8 +6,7 @@
 Feed Parser. It works best on XML and HTML, but it does not rewrite the
 XML or HTML to reflect a new encoding; that's the tree builder's job.
 """
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
+# Use of this source code is governed by the MIT license.
 __license__ = "MIT"
 
 import codecs
diff --git a/ext2/bs4/diagnose.py b/ext2/bs4/diagnose.py
index 7a28c09a7e..f9835c3cd1 100644
--- a/ext2/bs4/diagnose.py
+++ b/ext2/bs4/diagnose.py
@@ -1,7 +1,6 @@
 """Diagnostic functions, mainly for use when doing tech support."""
 
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
+# Use of this source code is governed by the MIT license.
 __license__ = "MIT"
 
 import cProfile
diff --git a/ext2/bs4/element.py b/ext2/bs4/element.py
index 886eb91f2a..547b8bae8d 100644
--- a/ext2/bs4/element.py
+++ b/ext2/bs4/element.py
@@ -1,5 +1,4 @@
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
+# Use of this source code is governed by the MIT license.
 __license__ = "MIT"
 
 try:
@@ -7,14 +6,25 @@
 except ImportError , e:
     from collections import Callable
 import re
-import shlex
 import sys
 import warnings
+try:
+    import soupsieve
+except ImportError, e:
+    soupsieve = None
+    warnings.warn(
+        'The soupsieve package is not installed. CSS selectors cannot be used.'
+    )
+
 from bs4.dammit import EntitySubstitution
 
 DEFAULT_OUTPUT_ENCODING = "utf-8"
 PY3K = (sys.version_info[0] > 2)
 
+nonwhitespace_re = re.compile(r"\S+")
+
+# NOTE: This isn't used as of 4.7.0. I'm leaving it for a little bit on
+# the off chance someone imported it for their own use.
 whitespace_re = re.compile(r"\s+")
 
 def _alias(attr):
@@ -207,7 +217,7 @@ def format_string(self, s, formatter='minimal'):
         if formatter is None:
             output = s
         else:
-            if callable(formatter):
+            if isinstance(formatter, Callable):
                 # Backwards compatibility -- you used to pass in a formatting method.
                 output = formatter(s)
             else:
@@ -256,26 +266,26 @@ def setup(self, parent=None, previous_element=None, next_element=None,
             self.previous_element.next_element = self
 
         self.next_element = next_element
-        if self.next_element:
+        if self.next_element is not None:
             self.next_element.previous_element = self
 
         self.next_sibling = next_sibling
-        if self.next_sibling:
+        if self.next_sibling is not None:
             self.next_sibling.previous_sibling = self
 
-        if (not previous_sibling
+        if (previous_sibling is None
             and self.parent is not None and self.parent.contents):
             previous_sibling = self.parent.contents[-1]
 
         self.previous_sibling = previous_sibling
-        if previous_sibling:
+        if previous_sibling is not None:
             self.previous_sibling.next_sibling = self
 
     nextSibling = _alias("next_sibling")  # BS3
     previousSibling = _alias("previous_sibling")  # BS3
 
     def replace_with(self, replace_with):
-        if not self.parent:
+        if self.parent is None:
             raise ValueError(
                 "Cannot replace one element with another when the"
                 "element to be replaced is not part of a tree.")
@@ -292,7 +302,7 @@ def replace_with(self, replace_with):
 
     def unwrap(self):
         my_parent = self.parent
-        if not self.parent:
+        if self.parent is None:
             raise ValueError(
                 "Cannot replace an element with its contents when that"
                 "element is not part of a tree.")
@@ -340,7 +350,7 @@ def extract(self):
 
     def _last_descendant(self, is_initialized=True, accept_self=True):
         "Finds the last element beneath this object to be parsed."
-        if is_initialized and self.next_sibling:
+        if is_initialized and self.next_sibling is not None:
             last_child = self.next_sibling.previous_element
         else:
             last_child = self
@@ -430,43 +440,54 @@ def append(self, tag):
         """Appends the given tag to the contents of this tag."""
         self.insert(len(self.contents), tag)
 
-    def insert_before(self, predecessor):
-        """Makes the given element the immediate predecessor of this one.
+    def extend(self, tags):
+        """Appends the given tags to the contents of this tag."""
+        for tag in tags:
+            self.append(tag)
+
+    def insert_before(self, *args):
+        """Makes the given element(s) the immediate predecessor of this one.
 
-        The two elements will have the same parent, and the given element
+        The elements will have the same parent, and the given elements
         will be immediately before this one.
         """
-        if self is predecessor:
-            raise ValueError("Can't insert an element before itself.")
         parent = self.parent
         if parent is None:
             raise ValueError(
                 "Element has no parent, so 'before' has no meaning.")
-        # Extract first so that the index won't be screwed up if they
-        # are siblings.
-        if isinstance(predecessor, PageElement):
-            predecessor.extract()
-        index = parent.index(self)
-        parent.insert(index, predecessor)
-
-    def insert_after(self, successor):
-        """Makes the given element the immediate successor of this one.
-
-        The two elements will have the same parent, and the given element
+        if any(x is self for x in args):
+                raise ValueError("Can't insert an element before itself.")
+        for predecessor in args:
+            # Extract first so that the index won't be screwed up if they
+            # are siblings.
+            if isinstance(predecessor, PageElement):
+                predecessor.extract()
+            index = parent.index(self)
+            parent.insert(index, predecessor)
+
+    def insert_after(self, *args):
+        """Makes the given element(s) the immediate successor of this one.
+
+        The elements will have the same parent, and the given elements
         will be immediately after this one.
         """
-        if self is successor:
-            raise ValueError("Can't insert an element after itself.")
+        # Do all error checking before modifying the tree.
         parent = self.parent
         if parent is None:
             raise ValueError(
                 "Element has no parent, so 'after' has no meaning.")
-        # Extract first so that the index won't be screwed up if they
-        # are siblings.
-        if isinstance(successor, PageElement):
-            successor.extract()
-        index = parent.index(self)
-        parent.insert(index+1, successor)
+        if any(x is self for x in args):
+            raise ValueError("Can't insert an element after itself.")
+        
+        offset = 0
+        for successor in args:
+            # Extract first so that the index won't be screwed up if they
+            # are siblings.
+            if isinstance(successor, PageElement):
+                successor.extract()
+            index = parent.index(self)
+            parent.insert(index+1+offset, successor)
+            offset += 1
 
     def find_next(self, name=None, attrs={}, text=None, **kwargs):
         """Returns the first item that matches the given criteria and
@@ -657,82 +678,6 @@ def parents(self):
             yield i
             i = i.parent
 
-    # Methods for supporting CSS selectors.
-
-    tag_name_re = re.compile('^[a-zA-Z0-9][-.a-zA-Z0-9:_]*$')
-
-    # /^([a-zA-Z0-9][-.a-zA-Z0-9:_]*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
-    #   \---------------------------/  \---/\-------------/    \-------/
-    #     |                              |         |               |
-    #     |                              |         |           The value
-    #     |                              |    ~,|,^,$,* or =
-    #     |                           Attribute
-    #    Tag
-    attribselect_re = re.compile(
-        r'^(?P[a-zA-Z0-9][-.a-zA-Z0-9:_]*)?\[(?P[\w-]+)(?P[=~\|\^\$\*]?)' +
-        r'=?"?(?P[^\]"]*)"?\]$'
-        )
-
-    def _attr_value_as_string(self, value, default=None):
-        """Force an attribute value into a string representation.
-
-        A multi-valued attribute will be converted into a
-        space-separated stirng.
-        """
-        value = self.get(value, default)
-        if isinstance(value, list) or isinstance(value, tuple):
-            value =" ".join(value)
-        return value
-
-    def _tag_name_matches_and(self, function, tag_name):
-        if not tag_name:
-            return function
-        else:
-            def _match(tag):
-                return tag.name == tag_name and function(tag)
-            return _match
-
-    def _attribute_checker(self, operator, attribute, value=''):
-        """Create a function that performs a CSS selector operation.
-
-        Takes an operator, attribute and optional value. Returns a
-        function that will return True for elements that match that
-        combination.
-        """
-        if operator == '=':
-            # string representation of `attribute` is equal to `value`
-            return lambda el: el._attr_value_as_string(attribute) == value
-        elif operator == '~':
-            # space-separated list representation of `attribute`
-            # contains `value`
-            def _includes_value(element):
-                attribute_value = element.get(attribute, [])
-                if not isinstance(attribute_value, list):
-                    attribute_value = attribute_value.split()
-                return value in attribute_value
-            return _includes_value
-        elif operator == '^':
-            # string representation of `attribute` starts with `value`
-            return lambda el: el._attr_value_as_string(
-                attribute, '').startswith(value)
-        elif operator == '$':
-            # string representation of `attribute` ends with `value`
-            return lambda el: el._attr_value_as_string(
-                attribute, '').endswith(value)
-        elif operator == '*':
-            # string representation of `attribute` contains `value`
-            return lambda el: value in el._attr_value_as_string(attribute, '')
-        elif operator == '|':
-            # string representation of `attribute` is either exactly
-            # `value` or starts with `value` and then a dash.
-            def _is_or_starts_with_dash(element):
-                attribute_value = element._attr_value_as_string(attribute, '')
-                return (attribute_value == value or attribute_value.startswith(
-                        value + '-'))
-            return _is_or_starts_with_dash
-        else:
-            return lambda el: el.has_attr(attribute)
-
     # Old non-property versions of the generators, for backwards
     # compatibility with BS3.
     def nextGenerator(self):
@@ -1193,7 +1138,7 @@ def decode(self, indent_level=None,
 
         # First off, turn a string formatter into a Formatter object. This
         # will stop the lookup from happening over and over again.
-        if not isinstance(formatter, Formatter) and not callable(formatter):
+        if not isinstance(formatter, Formatter) and not isinstance(formatter, Callable):
             formatter = self._formatter_for_name(formatter)
         attrs = []
         if self.attrs:
@@ -1298,7 +1243,7 @@ def decode_contents(self, indent_level=None,
         """
         # First off, turn a string formatter into a Formatter object. This
         # will stop the lookup from happening over and over again.
-        if not isinstance(formatter, Formatter) and not callable(formatter):
+        if not isinstance(formatter, Formatter) and not isinstance(formatter, Callable):
             formatter = self._formatter_for_name(formatter)
 
         pretty_print = (indent_level is not None)
@@ -1394,250 +1339,41 @@ def descendants(self):
             current = current.next_element
 
     # CSS selector code
-
-    _selector_combinators = ['>', '+', '~']
-    _select_debug = False
-    quoted_colon = re.compile('"[^"]*:[^"]*"')
-    def select_one(self, selector):
+    def select_one(self, selector, namespaces=None, **kwargs):
         """Perform a CSS selection operation on the current element."""
-        value = self.select(selector, limit=1)
+        value = self.select(selector, namespaces, 1, **kwargs)
         if value:
             return value[0]
         return None
 
-    def select(self, selector, _candidate_generator=None, limit=None):
-        """Perform a CSS selection operation on the current element."""
+    def select(self, selector, namespaces=None, limit=None, **kwargs):
+        """Perform a CSS selection operation on the current element.
 
-        # Handle grouping selectors if ',' exists, ie: p,a
-        if ',' in selector:
-            context = []
-            selectors = [x.strip() for x in selector.split(",")]
-
-            # If a selector is mentioned multiple times we don't want
-            # to use it more than once.
-            used_selectors = set()
-
-            # We also don't want to select the same element more than once,
-            # if it's matched by multiple selectors.
-            selected_object_ids = set()
-            for partial_selector in selectors:
-                if partial_selector == '':
-                    raise ValueError('Invalid group selection syntax: %s' % selector)
-                if partial_selector in used_selectors:
-                    continue
-                used_selectors.add(partial_selector)
-                candidates = self.select(partial_selector, limit=limit)
-                for candidate in candidates:
-                    # This lets us distinguish between distinct tags that
-                    # represent the same markup.
-                    object_id = id(candidate)
-                    if object_id not in selected_object_ids:
-                        context.append(candidate)
-                        selected_object_ids.add(object_id)
-                if limit and len(context) >= limit:
-                    break
-            return context
-        tokens = shlex.split(selector)
-        current_context = [self]
-
-        if tokens[-1] in self._selector_combinators:
-            raise ValueError(
-                'Final combinator "%s" is missing an argument.' % tokens[-1])
+        This uses the SoupSieve library.
 
-        if self._select_debug:
-            print 'Running CSS selector "%s"' % selector
+        :param selector: A string containing a CSS selector.
 
-        for index, token in enumerate(tokens):
-            new_context = []
-            new_context_ids = set([])
+        :param namespaces: A dictionary mapping namespace prefixes
+        used in the CSS selector to namespace URIs. By default,
+        Beautiful Soup will use the prefixes it encountered while
+        parsing the document.
 
-            if tokens[index-1] in self._selector_combinators:
-                # This token was consumed by the previous combinator. Skip it.
-                if self._select_debug:
-                    print '  Token was consumed by the previous combinator.'
-                continue
+        :param limit: After finding this number of results, stop looking.
 
-            if self._select_debug:
-                print ' Considering token "%s"' % token
-            recursive_candidate_generator = None
-            tag_name = None
-
-            # Each operation corresponds to a checker function, a rule
-            # for determining whether a candidate matches the
-            # selector. Candidates are generated by the active
-            # iterator.
-            checker = None
-
-            m = self.attribselect_re.match(token)
-            if m is not None:
-                # Attribute selector
-                tag_name, attribute, operator, value = m.groups()
-                checker = self._attribute_checker(operator, attribute, value)
-
-            elif '#' in token:
-                # ID selector
-                tag_name, tag_id = token.split('#', 1)
-                def id_matches(tag):
-                    return tag.get('id', None) == tag_id
-                checker = id_matches
-
-            elif '.' in token:
-                # Class selector
-                tag_name, klass = token.split('.', 1)
-                classes = set(klass.split('.'))
-                def classes_match(candidate):
-                    return classes.issubset(candidate.get('class', []))
-                checker = classes_match
-
-            elif ':' in token and not self.quoted_colon.search(token):
-                # Pseudo-class
-                tag_name, pseudo = token.split(':', 1)
-                if tag_name == '':
-                    raise ValueError(
-                        "A pseudo-class must be prefixed with a tag name.")
-                pseudo_attributes = re.match(r'([a-zA-Z\d-]+)\(([a-zA-Z\d]+)\)', pseudo)
-                found = []
-                if pseudo_attributes is None:
-                    pseudo_type = pseudo
-                    pseudo_value = None
-                else:
-                    pseudo_type, pseudo_value = pseudo_attributes.groups()
-                if pseudo_type == 'nth-of-type':
-                    try:
-                        pseudo_value = int(pseudo_value)
-                    except:
-                        raise NotImplementedError(
-                            'Only numeric values are currently supported for the nth-of-type pseudo-class.')
-                    if pseudo_value < 1:
-                        raise ValueError(
-                            'nth-of-type pseudo-class value must be at least 1.')
-                    class Counter(object):
-                        def __init__(self, destination):
-                            self.count = 0
-                            self.destination = destination
-
-                        def nth_child_of_type(self, tag):
-                            self.count += 1
-                            if self.count == self.destination:
-                                return True
-                            else:
-                                return False
-                    checker = Counter(pseudo_value).nth_child_of_type
-                else:
-                    raise NotImplementedError(
-                        'Only the following pseudo-classes are implemented: nth-of-type.')
-
-            elif token == '*':
-                # Star selector -- matches everything
-                pass
-            elif token == '>':
-                # Run the next token as a CSS selector against the
-                # direct children of each tag in the current context.
-                recursive_candidate_generator = lambda tag: tag.children
-            elif token == '~':
-                # Run the next token as a CSS selector against the
-                # siblings of each tag in the current context.
-                recursive_candidate_generator = lambda tag: tag.next_siblings
-            elif token == '+':
-                # For each tag in the current context, run the next
-                # token as a CSS selector against the tag's next
-                # sibling that's a tag.
-                def next_tag_sibling(tag):
-                    yield tag.find_next_sibling(True)
-                recursive_candidate_generator = next_tag_sibling
-
-            elif self.tag_name_re.match(token):
-                # Just a tag name.
-                tag_name = token
-            else:
-                raise ValueError(
-                    'Unsupported or invalid CSS selector: "%s"' % token)
-            if recursive_candidate_generator:
-                # This happens when the selector looks like  "> foo".
-                #
-                # The generator calls select() recursively on every
-                # member of the current context, passing in a different
-                # candidate generator and a different selector.
-                #
-                # In the case of "> foo", the candidate generator is
-                # one that yields a tag's direct children (">"), and
-                # the selector is "foo".
-                next_token = tokens[index+1]
-                def recursive_select(tag):
-                    if self._select_debug:
-                        print '    Calling select("%s") recursively on %s %s' % (next_token, tag.name, tag.attrs)
-                        print '-' * 40
-                    for i in tag.select(next_token, recursive_candidate_generator):
-                        if self._select_debug:
-                            print '(Recursive select picked up candidate %s %s)' % (i.name, i.attrs)
-                        yield i
-                    if self._select_debug:
-                        print '-' * 40
-                _use_candidate_generator = recursive_select
-            elif _candidate_generator is None:
-                # By default, a tag's candidates are all of its
-                # children. If tag_name is defined, only yield tags
-                # with that name.
-                if self._select_debug:
-                    if tag_name:
-                        check = "[any]"
-                    else:
-                        check = tag_name
-                    print '   Default candidate generator, tag name="%s"' % check
-                if self._select_debug:
-                    # This is redundant with later code, but it stops
-                    # a bunch of bogus tags from cluttering up the
-                    # debug log.
-                    def default_candidate_generator(tag):
-                        for child in tag.descendants:
-                            if not isinstance(child, Tag):
-                                continue
-                            if tag_name and not child.name == tag_name:
-                                continue
-                            yield child
-                    _use_candidate_generator = default_candidate_generator
-                else:
-                    _use_candidate_generator = lambda tag: tag.descendants
-            else:
-                _use_candidate_generator = _candidate_generator
-
-            count = 0
-            for tag in current_context:
-                if self._select_debug:
-                    print "    Running candidate generator on %s %s" % (
-                        tag.name, repr(tag.attrs))
-                for candidate in _use_candidate_generator(tag):
-                    if not isinstance(candidate, Tag):
-                        continue
-                    if tag_name and candidate.name != tag_name:
-                        continue
-                    if checker is not None:
-                        try:
-                            result = checker(candidate)
-                        except StopIteration:
-                            # The checker has decided we should no longer
-                            # run the generator.
-                            break
-                    if checker is None or result:
-                        if self._select_debug:
-                            print "     SUCCESS %s %s" % (candidate.name, repr(candidate.attrs))
-                        if id(candidate) not in new_context_ids:
-                            # If a tag matches a selector more than once,
-                            # don't include it in the context more than once.
-                            new_context.append(candidate)
-                            new_context_ids.add(id(candidate))
-                    elif self._select_debug:
-                        print "     FAILURE %s %s" % (candidate.name, repr(candidate.attrs))
-
-            current_context = new_context
-        if limit and len(current_context) >= limit:
-            current_context = current_context[:limit]
-
-        if self._select_debug:
-            print "Final verdict:"
-            for i in current_context:
-                print " %s %s" % (i.name, i.attrs)
-        return current_context
+        :param kwargs: Any extra arguments you'd like to pass in to
+        soupsieve.select().
+        """
+        if namespaces is None:
+            namespaces = self._namespaces
+        
+        if limit is None:
+            limit = 0
+        if soupsieve is None:
+            raise NotImplementedError(
+                "Cannot execute CSS selectors because the soupsieve package is not installed."
+            )
+            
+        return soupsieve.select(selector, self, namespaces, limit, **kwargs)
 
     # Old names for backwards compatibility
     def childGenerator(self):
@@ -1689,7 +1425,7 @@ def __init__(self, name=None, attrs={}, text=None, **kwargs):
     def _normalize_search_value(self, value):
         # Leave it alone if it's a Unicode string, a callable, a
         # regular expression, a boolean, or None.
-        if (isinstance(value, unicode) or callable(value) or hasattr(value, 'match')
+        if (isinstance(value, unicode) or isinstance(value, Callable) or hasattr(value, 'match')
             or isinstance(value, bool) or value is None):
             return value
 
diff --git a/ext2/bs4/testing.py b/ext2/bs4/testing.py
index 745a9c4af8..e4a0ffe036 100644
--- a/ext2/bs4/testing.py
+++ b/ext2/bs4/testing.py
@@ -1,8 +1,7 @@
 # encoding: utf-8
 """Helper classes for tests."""
 
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
+# Use of this source code is governed by the MIT license.
 __license__ = "MIT"
 
 import pickle
@@ -17,11 +16,48 @@
     ContentMetaAttributeValue,
     Doctype,
     SoupStrainer,
+    Tag
 )
 
 from bs4.builder import HTMLParserTreeBuilder
 default_builder = HTMLParserTreeBuilder
 
+BAD_DOCUMENT = u"""A bare string
+
+
+
+
HTML5 does allow CDATA sections in SVG
+
A tag
+
A
tag that supposedly has contents.
+
AT&T
+
+
+
This numeric entity is missing the final semicolon:
+
+
a
+
This document contains (do you see it?)
+
This document ends with That attribute value was bogus
+The doctype is invalid because it contains extra whitespace +
That boolean attribute had no value
+
Here's a nonexistent entity: &#foo; (do you see it?)
+
This document ends before the entity finishes: > +

Paragraphs shouldn't contain block display elements, but this one does:

you see?

+Multiple values for the same attribute. +
Here's a table
+
+
This tag contains nothing but whitespace:
+

This p tag is cut off by

the end of the blockquote tag
+
Here's a nested table:
foo
This table contains bare markup
+ +
This document contains a surprise doctype
+ +
Tag name contains Unicode characters
+ + +""" + class SoupTest(unittest.TestCase): @@ -60,6 +96,121 @@ def assertConnectedness(self, element): self.assertEqual(earlier, e.previous_element) earlier = e + def linkage_validator(self, el, _recursive_call=False): + """Ensure proper linkage throughout the document.""" + descendant = None + # Document element should have no previous element or previous sibling. + # It also shouldn't have a next sibling. + if el.parent is None: + assert el.previous_element is None,\ + "Bad previous_element\nNODE: {}\nPREV: {}\nEXPECTED: {}".format( + el, el.previous_element, None + ) + assert el.previous_sibling is None,\ + "Bad previous_sibling\nNODE: {}\nPREV: {}\nEXPECTED: {}".format( + el, el.previous_sibling, None + ) + assert el.next_sibling is None,\ + "Bad next_sibling\nNODE: {}\nNEXT: {}\nEXPECTED: {}".format( + el, el.next_sibling, None + ) + + idx = 0 + child = None + last_child = None + last_idx = len(el.contents) - 1 + for child in el.contents: + descendant = None + + # Parent should link next element to their first child + # That child should have no previous sibling + if idx == 0: + if el.parent is not None: + assert el.next_element is child,\ + "Bad next_element\nNODE: {}\nNEXT: {}\nEXPECTED: {}".format( + el, el.next_element, child + ) + assert child.previous_element is el,\ + "Bad previous_element\nNODE: {}\nPREV: {}\nEXPECTED: {}".format( + child, child.previous_element, el + ) + assert child.previous_sibling is None,\ + "Bad previous_sibling\nNODE: {}\nPREV {}\nEXPECTED: {}".format( + child, child.previous_sibling, None + ) + + # If not the first child, previous index should link as sibling to this index + # Previous element should match the last index or the last bubbled up descendant + else: + assert child.previous_sibling is el.contents[idx - 1],\ + "Bad previous_sibling\nNODE: {}\nPREV {}\nEXPECTED {}".format( + child, child.previous_sibling, el.contents[idx - 1] + ) + assert el.contents[idx - 1].next_sibling is child,\ + "Bad next_sibling\nNODE: {}\nNEXT {}\nEXPECTED {}".format( + el.contents[idx - 1], el.contents[idx - 1].next_sibling, child + ) + + if last_child is not None: + assert child.previous_element is last_child,\ + "Bad previous_element\nNODE: {}\nPREV {}\nEXPECTED {}\nCONTENTS {}".format( + child, child.previous_element, last_child, child.parent.contents + ) + assert last_child.next_element is child,\ + "Bad next_element\nNODE: {}\nNEXT {}\nEXPECTED {}".format( + last_child, last_child.next_element, child + ) + + if isinstance(child, Tag) and child.contents: + descendant = self.linkage_validator(child, True) + # A bubbled up descendant should have no next siblings + assert descendant.next_sibling is None,\ + "Bad next_sibling\nNODE: {}\nNEXT {}\nEXPECTED {}".format( + descendant, descendant.next_sibling, None + ) + + # Mark last child as either the bubbled up descendant or the current child + if descendant is not None: + last_child = descendant + else: + last_child = child + + # If last child, there are non next siblings + if idx == last_idx: + assert child.next_sibling is None,\ + "Bad next_sibling\nNODE: {}\nNEXT {}\nEXPECTED {}".format( + child, child.next_sibling, None + ) + idx += 1 + + child = descendant if descendant is not None else child + if child is None: + child = el + + if not _recursive_call and child is not None: + target = el + while True: + if target is None: + assert child.next_element is None, \ + "Bad next_element\nNODE: {}\nNEXT {}\nEXPECTED {}".format( + child, child.next_element, None + ) + break + elif target.next_sibling is not None: + assert child.next_element is target.next_sibling, \ + "Bad next_element\nNODE: {}\nNEXT {}\nEXPECTED {}".format( + child, child.next_element, target.next_sibling + ) + break + target = target.parent + + # We are done, so nothing to return + return None + else: + # Return the child to the recursive caller + return child + + class HTMLTreeBuilderSmokeTest(object): """A basic test of a treebuilder's competence. @@ -301,6 +452,18 @@ def test_correctly_nested_tables(self): "Bar" "Baz") + def test_multivalued_attribute_with_whitespace(self): + # Whitespace separating the values of a multi-valued attribute + # should be ignored. + + markup = '
' + soup = self.soup(markup) + self.assertEqual(['foo', 'bar'], soup.div['class']) + + # If you search by the literal name of the class it's like the whitespace + # wasn't there. + self.assertEqual(soup.div, soup.find('div', class_="foo bar")) + def test_deeply_nested_multivalued_attribute(self): # html5lib can set the attributes of the same tag many times # as it rearranges the tree. This has caused problems with @@ -615,6 +778,13 @@ def test_tag_with_no_attributes_can_have_attributes_added(self): data.a['foo'] = 'bar' self.assertEqual('text', data.a.decode()) + def test_worst_case(self): + """Test the worst case (currently) for linking issues.""" + + soup = self.soup(BAD_DOCUMENT) + self.linkage_validator(soup) + + class XMLTreeBuilderSmokeTest(object): def test_pickle_and_unpickle_identity(self): @@ -761,6 +931,12 @@ def test_copy_tag_preserves_namespace(self): # The two tags have the same namespace prefix. self.assertEqual(tag.prefix, duplicate.prefix) + def test_worst_case(self): + """Test the worst case (currently) for linking issues.""" + + soup = self.soup(BAD_DOCUMENT) + self.linkage_validator(soup) + class HTML5TreeBuilderSmokeTest(HTMLTreeBuilderSmokeTest): """Smoke test for a tree builder that supports HTML5.""" diff --git a/ext2/bs4/tests/test_html5lib.py b/ext2/bs4/tests/test_html5lib.py index 0f89d62445..3a04787cc0 100644 --- a/ext2/bs4/tests/test_html5lib.py +++ b/ext2/bs4/tests/test_html5lib.py @@ -128,3 +128,43 @@ def test_foster_parenting(self): markup = b"""A""" soup = self.soup(markup) self.assertEqual(u"A
", soup.body.decode()) + + def test_extraction(self): + """ + Test that extraction does not destroy the tree. + + https://bugs.launchpad.net/beautifulsoup/+bug/1782928 + """ + + markup = """ + +

hello

+""" + soup = self.soup(markup) + [s.extract() for s in soup('script')] + [s.extract() for s in soup('style')] + + self.assertEqual(len(soup.find_all("p")), 1) + + def test_empty_comment(self): + """ + Test that empty comment does not break structure. + + https://bugs.launchpad.net/beautifulsoup/+bug/1806598 + """ + + markup = """ + + +
+ +
+ + +""" + soup = self.soup(markup) + inputs = [] + for form in soup.find_all('form'): + inputs.extend(form.find_all('input')) + self.assertEqual(len(inputs), 1) diff --git a/ext2/bs4/tests/test_lxml.py b/ext2/bs4/tests/test_lxml.py index 8a8f690477..1a4f27cd90 100644 --- a/ext2/bs4/tests/test_lxml.py +++ b/ext2/bs4/tests/test_lxml.py @@ -80,3 +80,21 @@ class LXMLXMLTreeBuilderSmokeTest(SoupTest, XMLTreeBuilderSmokeTest): @property def default_builder(self): return LXMLTreeBuilderForXML() + + def test_namespace_indexing(self): + # We should not track un-prefixed namespaces as we can only hold one + # and it will be recognized as the default namespace by soupsieve, + # which may be confusing in some situations. When no namespace is provided + # for a selector, the default namespace (if defined) is assumed. + + soup = self.soup( + '\n' + '' + 'content' + 'content' + '' + ) + self.assertEqual( + soup._namespaces, + {'xml': 'http://www.w3.org/XML/1998/namespace', 'prefix': 'http://prefixed-namespace.com'} + ) diff --git a/ext2/bs4/tests/test_tree.py b/ext2/bs4/tests/test_tree.py index 883cd8abb9..6d79454b6c 100644 --- a/ext2/bs4/tests/test_tree.py +++ b/ext2/bs4/tests/test_tree.py @@ -1,4 +1,3 @@ - # -*- coding: utf-8 -*- """Tests for Beautiful Soup's tree traversal methods. @@ -932,6 +931,13 @@ def test_append_child_thats_already_at_the_end(self): soup.a.append(soup.b) self.assertEqual(data, soup.decode()) + def test_extend(self): + data = "" + soup = self.soup(data) + l = [soup.g, soup.f, soup.e, soup.d, soup.c, soup.b] + soup.a.extend(l) + self.assertEqual("", soup.decode()) + def test_move_tag_to_beginning_of_parent(self): data = "" soup = self.soup(data) @@ -958,6 +964,29 @@ def test_insert_before(self): self.assertEqual( soup.decode(), self.document_for("QUUXbarfooBAZ")) + # Can't insert an element before itself. + b = soup.b + self.assertRaises(ValueError, b.insert_before, b) + + # Can't insert before if an element has no parent. + b.extract() + self.assertRaises(ValueError, b.insert_before, "nope") + + # Can insert an identical element + soup = self.soup("") + soup.a.insert_before(soup.new_tag("a")) + + def test_insert_multiple_before(self): + soup = self.soup("foobar") + soup.b.insert_before("BAZ", " ", "QUUX") + soup.a.insert_before("QUUX", " ", "BAZ") + self.assertEqual( + soup.decode(), self.document_for("QUUX BAZfooBAZ QUUXbar")) + + soup.a.insert_before(soup.b, "FOO") + self.assertEqual( + soup.decode(), self.document_for("QUUX BAZbarFOOfooBAZ QUUX")) + def test_insert_after(self): soup = self.soup("foobar") soup.b.insert_after("BAZ") @@ -968,6 +997,28 @@ def test_insert_after(self): self.assertEqual( soup.decode(), self.document_for("QUUXbarfooBAZ")) + # Can't insert an element after itself. + b = soup.b + self.assertRaises(ValueError, b.insert_after, b) + + # Can't insert after if an element has no parent. + b.extract() + self.assertRaises(ValueError, b.insert_after, "nope") + + # Can insert an identical element + soup = self.soup("") + soup.a.insert_before(soup.new_tag("a")) + + def test_insert_multiple_after(self): + soup = self.soup("foobar") + soup.b.insert_after("BAZ", " ", "QUUX") + soup.a.insert_after("QUUX", " ", "BAZ") + self.assertEqual( + soup.decode(), self.document_for("fooQUUX BAZbarBAZ QUUX")) + soup.b.insert_after(soup.a, "FOO ") + self.assertEqual( + soup.decode(), self.document_for("QUUX BAZbarfooFOO BAZ QUUX")) + def test_insert_after_raises_exception_if_after_has_no_meaning(self): soup = self.soup("") tag = soup.new_tag("a") @@ -1783,7 +1834,7 @@ def test_tag_no_match(self): self.assertEqual(len(self.soup.select('del')), 0) def test_invalid_tag(self): - self.assertRaises(ValueError, self.soup.select, 'tag%t') + self.assertRaises(SyntaxError, self.soup.select, 'tag%t') def test_select_dashed_tag_ids(self): self.assertSelects('custom-dashed-tag', ['dash1', 'dash2']) @@ -1974,8 +2025,7 @@ def test_unsupported_pseudoclass(self): NotImplementedError, self.soup.select, "a:no-such-pseudoclass") self.assertRaises( - NotImplementedError, self.soup.select, "a:nth-of-type(a)") - + SyntaxError, self.soup.select, "a:nth-of-type(a)") def test_nth_of_type(self): # Try to select first paragraph @@ -1992,9 +2042,9 @@ def test_nth_of_type(self): els = self.soup.select('div#inner p:nth-of-type(4)') self.assertEqual(len(els), 0) - # Pass in an invalid value. - self.assertRaises( - ValueError, self.soup.select, 'div p:nth-of-type(0)') + # Zero will select no tags. + els = self.soup.select('div p:nth-of-type(0)') + self.assertEqual(len(els), 0) def test_nth_of_type_direct_descendant(self): els = self.soup.select('div#inner > p:nth-of-type(1)') @@ -2031,7 +2081,7 @@ def test_general_sibling_selector(self): self.assertEqual([], self.soup.select('#inner ~ h2')) def test_dangling_combinator(self): - self.assertRaises(ValueError, self.soup.select, 'h1 >') + self.assertRaises(SyntaxError, self.soup.select, 'h1 >') def test_sibling_combinator_wont_select_same_tag_twice(self): self.assertSelects('p[lang] ~ p', ['lang-en-gb', 'lang-en-us', 'lang-fr']) @@ -2062,8 +2112,8 @@ def test_multiple_select_indirect_descendant(self): self.assertSelects('div x,y, z', ['xid', 'yid', 'zida', 'zidb', 'zidab', 'zidac']) def test_invalid_multiple_select(self): - self.assertRaises(ValueError, self.soup.select, ',x, y') - self.assertRaises(ValueError, self.soup.select, 'x,,y') + self.assertRaises(SyntaxError, self.soup.select, ',x, y') + self.assertRaises(SyntaxError, self.soup.select, 'x,,y') def test_multiple_select_attrs(self): self.assertSelects('p[lang=en], p[lang=en-gb]', ['lang-en', 'lang-en-gb']) @@ -2087,4 +2137,3 @@ def test_select_duplicate_elements(self): # order. for element in soup.find_all(class_=['c1', 'c2']): assert element in selected - diff --git a/ext/configparser.py b/ext2/configparser.py similarity index 91% rename from ext/configparser.py rename to ext2/configparser.py index b899f9e327..d8dbe9311b 100644 --- a/ext/configparser.py +++ b/ext2/configparser.py @@ -8,7 +8,6 @@ from __future__ import print_function from __future__ import unicode_literals - from backports.configparser import ( RawConfigParser, ConfigParser, @@ -20,7 +19,6 @@ ExtendedInterpolation, LegacyInterpolation, - Error, NoSectionError, DuplicateSectionError, DuplicateOptionError, @@ -33,9 +31,13 @@ MissingSectionHeaderError, ConverterMapping, - _UNSET, DEFAULTSECT, MAX_INTERPOLATION_DEPTH, +) + +from backports.configparser import ( # noqa: F401 + Error, + _UNSET, _default_dict, _ChainMap, ) @@ -45,7 +47,7 @@ "InterpolationMissingOptionError", "InterpolationSyntaxError", "ParsingError", "MissingSectionHeaderError", "ConfigParser", "SafeConfigParser", "RawConfigParser", - "Interpolation", "BasicInterpolation", "ExtendedInterpolation", + "Interpolation", "BasicInterpolation", "ExtendedInterpolation", "LegacyInterpolation", "SectionProxy", "ConverterMapping", "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] diff --git a/ext2/github/AuthenticatedUser.py b/ext2/github/AuthenticatedUser.py index 604eb0c8ed..c76fbaffd9 100644 --- a/ext2/github/AuthenticatedUser.py +++ b/ext2/github/AuthenticatedUser.py @@ -55,6 +55,7 @@ import github.Event import github.Authorization import github.Notification +import github.Migration import Consts @@ -237,6 +238,14 @@ def name(self): self._completeIfNotSet(self._name) return self._name.value + @property + def node_id(self): + """ + :type: string + """ + self._completeIfNotSet(self._node_id) + return self._node_id.value + @property def organizations_url(self): """ @@ -1139,6 +1148,50 @@ def accept_invitation(self, invitation): input={} ) + def create_migration(self, repos, lock_repositories=github.GithubObject.NotSet, exclude_attachments=github.GithubObject.NotSet): + """ + :calls: `POST /user/migrations`_ + :param repos: list or tuple of str + :param lock_repositories: bool + :param exclude_attachments: bool + :rtype: :class:`github.Migration.Migration` + """ + assert isinstance(repos, (list, tuple)), repos + assert all(isinstance(repo, (str, unicode)) for repo in repos), repos + assert lock_repositories is github.GithubObject.NotSet or isinstance(lock_repositories, bool), lock_repositories + assert exclude_attachments is github.GithubObject.NotSet or isinstance(exclude_attachments, bool), exclude_attachments + post_parameters = { + "repositories": repos + } + if lock_repositories is not github.GithubObject.NotSet: + post_parameters["lock_repositories"] = lock_repositories + if exclude_attachments is not github.GithubObject.NotSet: + post_parameters["exclude_attachments"] = exclude_attachments + headers, data = self._requester.requestJsonAndCheck( + "POST", + "/user/migrations", + input=post_parameters, + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + return github.Migration.Migration(self._requester, headers, data, completed=True) + + def get_migrations(self): + """ + :calls: `GET /user/migrations`_ + :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Migration.Migration` + """ + return github.PaginatedList.PaginatedList( + github.Migration.Migration, + self._requester, + "/user/migrations", + None, + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + def _initAttributes(self): self._avatar_url = github.GithubObject.NotSet self._bio = github.GithubObject.NotSet @@ -1161,6 +1214,7 @@ def _initAttributes(self): self._location = github.GithubObject.NotSet self._login = github.GithubObject.NotSet self._name = github.GithubObject.NotSet + self._node_id = github.GithubObject.NotSet self._organizations_url = github.GithubObject.NotSet self._owned_private_repos = github.GithubObject.NotSet self._plan = github.GithubObject.NotSet @@ -1220,6 +1274,8 @@ def _useAttributes(self, attributes): self._login = self._makeStringAttribute(attributes["login"]) if "name" in attributes: # pragma no branch self._name = self._makeStringAttribute(attributes["name"]) + if "node_id" in attributes: # pragma no branch + self._node_id = self._makeStringAttribute(attributes["node_id"]) if "organizations_url" in attributes: # pragma no branch self._organizations_url = self._makeStringAttribute(attributes["organizations_url"]) if "owned_private_repos" in attributes: # pragma no branch diff --git a/ext2/github/Clones.py b/ext2/github/Clones.py new file mode 100644 index 0000000000..b8c1adc7c7 --- /dev/null +++ b/ext2/github/Clones.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +############################ Copyrights and license ############################ +# # +# Copyright 2018 Justin Kufro # +# Copyright 2018 Ivan Minno # +# Copyright 2018 Zilei Gu # +# Copyright 2018 Yves Zumbach # +# Copyright 2018 Leying Chen # +# # +# This file is part of PyGithub. # +# http://pygithub.readthedocs.io/ # +# # +# PyGithub is free software: you can redistribute it and/or modify it under # +# the terms of the GNU Lesser General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # +# details. # +# # +# You should have received a copy of the GNU Lesser General Public License # +# along with PyGithub. If not, see . # +# # +################################################################################ + +import github.GithubObject + + +class Clones(github.GithubObject.NonCompletableGithubObject): + """ + This class represents a popular Path for a GitHub repository. + The reference can be found here https://developer.github.com/v3/repos/traffic/ + """ + + def __repr__(self): + return self.get__repr__({ + "timestamp": self._timestamp.value, + "count": self._count.value, + "uniques": self._uniques.value + }) + + @property + def timestamp(self): + """ + :type: datetime.datetime + """ + return self._timestamp.value + + @property + def count(self): + """ + :type: integer + """ + return self._count.value + + @property + def uniques(self): + """ + :type: integer + """ + return self._uniques.value + + def _initAttributes(self): + self._timestamp = github.GithubObject.NotSet + self._count = github.GithubObject.NotSet + self._uniques = github.GithubObject.NotSet + + def _useAttributes(self, attributes): + if "timestamp" in attributes: # pragma no branch + self._timestamp = self._makeDatetimeAttribute(attributes["timestamp"]) + if "count" in attributes: # pragma no branch + self._count = self._makeIntAttribute(attributes["count"]) + if "uniques" in attributes: # pragma no branch + self._uniques = self._makeIntAttribute(attributes["uniques"]) diff --git a/ext2/github/Consts.py b/ext2/github/Consts.py index c59f419793..93fcd5b5f0 100644 --- a/ext2/github/Consts.py +++ b/ext2/github/Consts.py @@ -48,6 +48,7 @@ headerRateLimit = "x-ratelimit-limit" headerRateRemaining = "x-ratelimit-remaining" headerRateReset = "x-ratelimit-reset" +headerOAuthScopes = "x-oauth-scopes" headerOTP = "X-GitHub-OTP" defaultMediaType = "application/octet-stream" @@ -90,6 +91,9 @@ # https://developer.github.com/changes/2018-03-16-protected-branches-required-approving-reviews/ mediaTypeRequireMultipleApprovingReviews = "application/vnd.github.luke-cage-preview+json" +# https://developer.github.com/changes/2018-05-24-user-migration-api/ +mediaTypeMigrationPreview = "application/vnd.github.wyandotte-preview+json" + # https://developer.github.com/v3/search/#highlighting-code-search-results-1 highLightSearchPreview = "application/vnd.github.v3.text-match+json" diff --git a/ext2/github/GitRelease.py b/ext2/github/GitRelease.py index 831337a314..427dc8eaba 100644 --- a/ext2/github/GitRelease.py +++ b/ext2/github/GitRelease.py @@ -37,7 +37,7 @@ from os.path import basename import github.GithubObject -import github.GitAuthor +import github.NamedUser import github.GitReleaseAsset @@ -108,7 +108,7 @@ def prerelease(self): @property def author(self): """ - :type: :class:`github.GitAuthor.GitAuthor` + :type: :class:`github.NamedUser.NamedUser` """ self._completeIfNotSet(self._author) return self._author.value @@ -285,7 +285,7 @@ def _useAttributes(self, attributes): if "prerelease" in attributes: self._prerelease = self._makeBoolAttribute(attributes["prerelease"]) if "author" in attributes: - self._author = self._makeClassAttribute(github.GitAuthor.GitAuthor, attributes["author"]) + self._author = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["author"]) if "url" in attributes: self._url = self._makeStringAttribute(attributes["url"]) if "upload_url" in attributes: diff --git a/ext2/github/GithubObject.py b/ext2/github/GithubObject.py index f1ffa75292..60ed6c65fc 100644 --- a/ext2/github/GithubObject.py +++ b/ext2/github/GithubObject.py @@ -170,7 +170,7 @@ def parseDatetime(s): # The Downloads API has been removed. I'm keeping this branch because I have no mean # to check if it's really useless now. return datetime.datetime.strptime(s, "%Y-%m-%dT%H:%M:%S.000Z") # pragma no cover (This branch was used only when creating a download) - elif len(s) == 25: + elif len(s) >= 25: return datetime.datetime.strptime(s[:19], "%Y-%m-%dT%H:%M:%S") + (1 if s[19] == '-' else -1) * datetime.timedelta(hours=int(s[20:22]), minutes=int(s[23:25])) else: return datetime.datetime.strptime(s, "%Y-%m-%dT%H:%M:%SZ") diff --git a/ext2/github/MainClass.py b/ext2/github/MainClass.py index ae77af89e3..f12d092a37 100644 --- a/ext2/github/MainClass.py +++ b/ext2/github/MainClass.py @@ -53,7 +53,7 @@ import pickle import time import sys -from httplib import HTTPSConnection +import requests import jwt from Requester import Requester, json @@ -66,6 +66,7 @@ import Installation import Legacy import License +import Topic import github.GithubObject import HookDescription import GitignoreTemplate @@ -542,7 +543,7 @@ def search_topics(self, query, **qualifiers): :calls: `GET /search/topics `_ :param query: string :param qualifiers: keyword dict query qualifiers - :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Repository.Repository` + :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Topic.Topic` """ assert isinstance(query, (str, unicode)), query url_parameters = dict() @@ -558,7 +559,7 @@ def search_topics(self, query, **qualifiers): assert url_parameters["q"], "need at least one qualifier" return github.PaginatedList.PaginatedList( - github.Repository.Repository, + github.Topic.Topic, self.__requester, "/search/topics", url_parameters, @@ -771,28 +772,24 @@ def get_access_token(self, installation_id, user_id=None): :param installation_id: int :return: :class:`github.InstallationAuthorization.InstallationAuthorization` """ - body = None + body = {} if user_id: - body = json.dumps({"user_id": user_id}) - conn = HTTPSConnection("api.github.com") - conn.request( - method="POST", - url="/installations/{}/access_tokens".format(installation_id), + body = {"user_id": user_id} + response = requests.post( + "https://api.github.com/installations/{}/access_tokens".format(installation_id), headers={ "Authorization": "Bearer {}".format(self.create_jwt()), "Accept": Consts.mediaTypeIntegrationPreview, "User-Agent": "PyGithub/Python" }, - body=body + json=body ) - response = conn.getresponse() - response_text = response.read() + response_text = response.text if atLeastPython3: response_text = response_text.decode('utf-8') - conn.close() - if response.status == 201: + if response.status_code == 201: data = json.loads(response_text) return InstallationAuthorization.InstallationAuthorization( requester=None, # not required, this is a NonCompletableGithubObject @@ -800,17 +797,17 @@ def get_access_token(self, installation_id, user_id=None): attributes=data, completed=True ) - elif response.status == 403: + elif response.status_code == 403: raise GithubException.BadCredentialsException( - status=response.status, + status=response.status_code, data=response_text ) - elif response.status == 404: + elif response.status_code == 404: raise GithubException.UnknownObjectException( - status=response.status, + status=response.status_code, data=response_text ) raise GithubException.GithubException( - status=response.status, + status=response.status_code, data=response_text ) diff --git a/ext2/github/Migration.py b/ext2/github/Migration.py new file mode 100644 index 0000000000..3f6a623c77 --- /dev/null +++ b/ext2/github/Migration.py @@ -0,0 +1,219 @@ +# -*- coding: utf-8 -*- + +############################ Copyrights and license ############################ +# # +# Copyright 2012 Vincent Jacques # +# Copyright 2012 Zearin # +# Copyright 2013 AKFish # +# Copyright 2013 Vincent Jacques # +# Copyright 2013 martinqt # +# Copyright 2014 Andy Casey # +# Copyright 2014 Vincent Jacques # +# Copyright 2016 Jannis Gebauer # +# Copyright 2016 John Eskew # +# Copyright 2016 Peter Buckley # +# Copyright 2018 sfdye # +# # +# This file is part of PyGithub. # +# http://pygithub.readthedocs.io/ # +# # +# PyGithub is free software: you can redistribute it and/or modify it under # +# the terms of the GNU Lesser General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # +# details. # +# # +# You should have received a copy of the GNU Lesser General Public License # +# along with PyGithub. If not, see . # +# # +################################################################################ + +import github.GithubObject +import github.PaginatedList + +import github.NamedUser + +import Consts + +class Migration(github.GithubObject.CompletableGithubObject): + """ + This class represents Migrations. The reference can be found here http://developer.github.com/v3/migrations/ + """ + + def __repr__(self): + return self.get__repr__({"state": self._state.value, "url": self._url.value}) + + @property + def id(self): + """ + :type: int + """ + return self._id.value + + @property + def owner(self): + """ + :type: :class:`github.NamedUser.NamedUser` + """ + self._completeIfNotSet(self._owner) + return self._owner.value + + @property + def guid(self): + """ + :type: str + """ + self._completeIfNotSet(self._guid) + return self._guid.value + + @property + def state(self): + """ + :type: str + """ + self._completeIfNotSet(self._guid) + return self._state.value + + @property + def lock_repositories(self): + """ + :type: bool + """ + self._completeIfNotSet(self._repositories) + return self._lock_repositories.value + + @property + def exclude_attachments(self): + """ + :type: bool + """ + self._completeIfNotSet(self._exclude_attachments) + return self._exclude_attachments.value + + @property + def repositories(self): + """ + :type: :class:`github.PaginatedList.PaginatedList` of :class:`github.Repository.Repository` + """ + self._completeIfNotSet(self._repositories) + return self._repositories.value + + @property + def url(self): + """ + :type: str + """ + self._completeIfNotSet(self._url) + return self._url.value + + @property + def created_at(self): + """ + :type: datetime.datetime + :rtype: None + """ + self._completeIfNotSet(self._created_at) + return self._created_at.value + + @property + def updated_at(self): + """ + :type: datetime.datetime + :rtype: None + """ + self._completeIfNotSet(self._updated_at) + return self._updated_at.value + + def get_status(self): + """ + :calls: `GET /user/migrations/:migration_id`_ + :rtype: str + """ + headers, data = self._requester.requestJsonAndCheck( + "GET", + self.url, + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + self._useAttributes(data) + return self.state + + def get_archive_url(self): + """ + :calls: `GET /user/migrations/:migration_id/archive`_ + :rtype: str + """ + headers, data = self._requester.requestJsonAndCheck( + "GET", + self.url + "/archive", + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + return data["data"] + + def delete(self): + """ + :calls: `DELETE /user/migrations/:migration_id/archive`_ + """ + headers, data = self._requester.requestJsonAndCheck( + "DELETE", + self.url + "/archive", + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + + def unlock_repo(self, repo_name): + """ + :calls: `DELETE /user/migrations/:migration_id/repos/:repo_name/lock`_ + :param repo_name: str + :rtype: None + """ + assert isinstance(repo_name, (str, unicode)), repo_name + headers, data = self._requester.requestJsonAndCheck( + "DELETE", + self.url + "/repos/" + repo_name + "/lock", + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + + def _initAttributes(self): + self._id = github.GithubObject.NotSet + self._owner = github.GithubObject.NotSet + self._guid = github.GithubObject.NotSet + self._state = github.GithubObject.NotSet + self._lock_repositories = github.GithubObject.NotSet + self._exclude_attachments = github.GithubObject.NotSet + self._repositories = github.GithubObject.NotSet + self._url = github.GithubObject.NotSet + self._created_at = github.GithubObject.NotSet + self._updated_at = github.GithubObject.NotSet + + def _useAttributes(self, attributes): + if "id" in attributes: + self._id = self._makeIntAttribute(attributes["id"]) + if "owner" in attributes: + self._owner = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["owner"]) + if "guid" in attributes: + self._guid = self._makeStringAttribute(attributes["guid"]) + if "state" in attributes: + self._state = self._makeStringAttribute(attributes["state"]) + if "lock_repositories" in attributes: + self._lock_repositories = self._makeBoolAttribute(attributes["lock_repositories"]) + if "exclude_attachments" in attributes: + self._exclude_attachments = self._makeBoolAttribute(attributes["exclude_attachments"]) + if "repositories" in attributes: + self._repositories = self._makeListOfClassesAttribute(github.Repository.Repository, attributes["repositories"]) + if "url" in attributes: + self._url = self._makeStringAttribute(attributes["url"]) + if "created_at" in attributes: + self._created_at = self._makeDatetimeAttribute(attributes["created_at"]) + if "updated_at" in attributes: + self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"]) diff --git a/ext2/github/NamedUser.py b/ext2/github/NamedUser.py index 43f73aacfb..91c8524ef0 100644 --- a/ext2/github/NamedUser.py +++ b/ext2/github/NamedUser.py @@ -59,6 +59,14 @@ class NamedUser(github.GithubObject.CompletableGithubObject): def __repr__(self): return self.get__repr__({"login": self._login.value}) + @property + def node_id(self): + """ + :type: string + """ + self._completeIfNotSet(self._node_id) + return self._node_id.value + def __hash__(self): return hash((self.id, self.login)) @@ -605,6 +613,7 @@ def _initAttributes(self): self._location = github.GithubObject.NotSet self._login = github.GithubObject.NotSet self._name = github.GithubObject.NotSet + self._node_id = github.GithubObject.NotSet self._organizations_url = github.GithubObject.NotSet self._owned_private_repos = github.GithubObject.NotSet self._permissions = github.GithubObject.NotSet @@ -668,6 +677,8 @@ def _useAttributes(self, attributes): self._login = self._makeStringAttribute(attributes["login"]) if "name" in attributes: # pragma no branch self._name = self._makeStringAttribute(attributes["name"]) + if "node_id" in attributes: # pragma no branch + self._node_id = self._makeStringAttribute(attributes["node_id"]) if "organizations_url" in attributes: # pragma no branch self._organizations_url = self._makeStringAttribute(attributes["organizations_url"]) if "owned_private_repos" in attributes: # pragma no branch diff --git a/ext2/github/Organization.py b/ext2/github/Organization.py index b1051495a5..33a4e7c2ae 100644 --- a/ext2/github/Organization.py +++ b/ext2/github/Organization.py @@ -896,6 +896,50 @@ def remove_from_public_members(self, public_member): self.url + "/public_members/" + public_member._identity ) + def create_migration(self, repos, lock_repositories=github.GithubObject.NotSet, exclude_attachments=github.GithubObject.NotSet): + """ + :calls: `POST /orgs/:org/migrations`_ + :param repos: list or tuple of str + :param lock_repositories: bool + :param exclude_attachments: bool + :rtype: :class:`github.Migration.Migration` + """ + assert isinstance(repos, (list, tuple)), repos + assert all(isinstance(repo, (str, unicode)) for repo in repos), repos + assert lock_repositories is github.GithubObject.NotSet or isinstance(lock_repositories, bool), lock_repositories + assert exclude_attachments is github.GithubObject.NotSet or isinstance(exclude_attachments, bool), exclude_attachments + post_parameters = { + "repositories": repos + } + if lock_repositories is not github.GithubObject.NotSet: + post_parameters["lock_repositories"] = lock_repositories + if exclude_attachments is not github.GithubObject.NotSet: + post_parameters["exclude_attachments"] = exclude_attachments + headers, data = self._requester.requestJsonAndCheck( + "POST", + "/orgs/" + self.login + "/migrations", + input=post_parameters, + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + return github.Migration.Migration(self._requester, headers, data, completed=True) + + def get_migrations(self): + """ + :calls: `GET /orgs/:org/migrations`_ + :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Migration.Migration` + """ + return github.PaginatedList.PaginatedList( + github.Migration.Migration, + self._requester, + "/orgs/" + self.login + "/migrations", + None, + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + def _initAttributes(self): self._avatar_url = github.GithubObject.NotSet self._billing_email = github.GithubObject.NotSet diff --git a/ext2/github/PaginatedList.py b/ext2/github/PaginatedList.py index 586b4a8ed7..3de289f6fb 100644 --- a/ext2/github/PaginatedList.py +++ b/ext2/github/PaginatedList.py @@ -155,7 +155,12 @@ def totalCount(self): headers=self.__headers ) if 'link' not in headers: - self.__totalCount = len(data) if data else 0 + if data and "total_count" in data: + self.__totalCount = data["total_count"] + elif data: + self.__totalCount = len(data) + else: + self.__totalCount = 0 else: links = self.__parseLinkHeader(headers) lastUrl = links.get("last") diff --git a/ext2/github/Path.py b/ext2/github/Path.py new file mode 100644 index 0000000000..615c0da1b8 --- /dev/null +++ b/ext2/github/Path.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- + +############################ Copyrights and license ############################ +# # +# Copyright 2018 Justin Kufro # +# Copyright 2018 Ivan Minno # +# Copyright 2018 Zilei Gu # +# Copyright 2018 Yves Zumbach # +# Copyright 2018 Leying Chen # +# # +# This file is part of PyGithub. # +# http://pygithub.readthedocs.io/ # +# # +# PyGithub is free software: you can redistribute it and/or modify it under # +# the terms of the GNU Lesser General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # +# details. # +# # +# You should have received a copy of the GNU Lesser General Public License # +# along with PyGithub. If not, see . # +# # +################################################################################ + +import github.GithubObject + + +class Path(github.GithubObject.NonCompletableGithubObject): + """ + This class represents a popular Path for a GitHub repository. + The reference can be found here https://developer.github.com/v3/repos/traffic/ + """ + + def __repr__(self): + return self.get__repr__({ + "path": self._path.value, + "title": self._title.value, + "count": self._count.value, + "uniques": self._uniques.value + }) + + @property + def path(self): + """ + :type: string + """ + return self._path.value + + @property + def title(self): + """ + :type: string + """ + return self._title.value + + @property + def count(self): + """ + :type: integer + """ + return self._count.value + + @property + def uniques(self): + """ + :type: integer + """ + return self._uniques.value + + def _initAttributes(self): + self._path = github.GithubObject.NotSet + self._title = github.GithubObject.NotSet + self._count = github.GithubObject.NotSet + self._uniques = github.GithubObject.NotSet + + def _useAttributes(self, attributes): + if "path" in attributes: # pragma no branch + self._path = self._makeStringAttribute(attributes["path"]) + if "title" in attributes: # pragma no branch + self._title = self._makeStringAttribute(attributes["title"]) + if "count" in attributes: # pragma no branch + self._count = self._makeIntAttribute(attributes["count"]) + if "uniques" in attributes: # pragma no branch + self._uniques = self._makeIntAttribute(attributes["uniques"]) diff --git a/ext2/github/Project.py b/ext2/github/Project.py index cdfadc8b01..83b4220e73 100644 --- a/ext2/github/Project.py +++ b/ext2/github/Project.py @@ -30,6 +30,7 @@ import Consts + class Project(github.GithubObject.CompletableGithubObject): """ This class represents Projects. The reference can be found here http://developer.github.com/v3/projects @@ -156,6 +157,22 @@ def get_columns(self): {"Accept": Consts.mediaTypeProjectsPreview} ) + def create_column(self, name): + """ + calls: `POST https://developer.github.com/v3/projects/columns/#create-a-project-column>`_ + :param name: string + """ + assert isinstance(name, (str, unicode)), name + post_parameters = {"name": name} + import_header = {"Accept": Consts.mediaTypeProjectsPreview} + headers, data = self._requester.requestJsonAndCheck( + "POST", + self.url + "/columns", + headers=import_header, + input=post_parameters + ) + return github.ProjectColumn.ProjectColumn(self._requester, headers, data, completed=True) + def _initAttributes(self): self._body = github.GithubObject.NotSet self._columns_url = github.GithubObject.NotSet diff --git a/ext2/github/ProjectColumn.py b/ext2/github/ProjectColumn.py index 702412e7bb..76b6126910 100644 --- a/ext2/github/ProjectColumn.py +++ b/ext2/github/ProjectColumn.py @@ -30,6 +30,7 @@ import Consts + class ProjectColumn(github.GithubObject.CompletableGithubObject): """ This class represents Project Columns. The reference can be found here http://developer.github.com/v3/projects/columns @@ -94,7 +95,7 @@ def url(self): """ return self._url.value - def get_cards(self,archived_state=github.GithubObject.NotSet): + def get_cards(self, archived_state=github.GithubObject.NotSet): """ :calls: `GET /projects/columns/:column_id/cards `_ :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.ProjectCard.ProjectCard` @@ -114,6 +115,37 @@ def get_cards(self,archived_state=github.GithubObject.NotSet): {"Accept": Consts.mediaTypeProjectsPreview} ) + def create_card(self, note=github.GithubObject.NotSet, + content_id=github.GithubObject.NotSet, + content_type=github.GithubObject.NotSet): + """ + calls: `POST https://developer.github.com/v3/projects/cards/#create-a-project-card>`_ + :param note: string + :param content_id: integer + :param content_type: string + """ + post_parameters = {} + if isinstance(note, (str, unicode)): + assert content_id is github.GithubObject.NotSet, content_id + assert content_type is github.GithubObject.NotSet, content_type + post_parameters = {"note": note} + else: + assert note is github.GithubObject.NotSet, note + assert isinstance(content_id, int), content_id + assert isinstance(content_type, (str, unicode)), content_type + post_parameters = {"content_id": content_id, + "content_type": content_type} + + import_header = {"Accept": Consts.mediaTypeProjectsPreview} + headers, data = self._requester.requestJsonAndCheck( + "POST", + self.url + "/cards", + headers=import_header, + input=post_parameters + ) + return github.ProjectCard.ProjectCard(self._requester, headers, + data, completed=True) + def _initAttributes(self): self._cards_url = github.GithubObject.NotSet self._created_at = github.GithubObject.NotSet diff --git a/ext2/github/PullRequest.py b/ext2/github/PullRequest.py index 688e0625b9..2dc354f871 100644 --- a/ext2/github/PullRequest.py +++ b/ext2/github/PullRequest.py @@ -42,6 +42,7 @@ # # ################################################################################ +import datetime import urllib import github.GithubObject import github.PaginatedList diff --git a/ext2/github/Referrer.py b/ext2/github/Referrer.py new file mode 100644 index 0000000000..eb14931b33 --- /dev/null +++ b/ext2/github/Referrer.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +############################ Copyrights and license ############################ +# # +# Copyright 2018 Justin Kufro # +# Copyright 2018 Ivan Minno # +# Copyright 2018 Zilei Gu # +# Copyright 2018 Yves Zumbach # +# Copyright 2018 Leying Chen # +# # +# This file is part of PyGithub. # +# http://pygithub.readthedocs.io/ # +# # +# PyGithub is free software: you can redistribute it and/or modify it under # +# the terms of the GNU Lesser General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # +# details. # +# # +# You should have received a copy of the GNU Lesser General Public License # +# along with PyGithub. If not, see . # +# # +################################################################################ + +import github.GithubObject + + +class Referrer(github.GithubObject.NonCompletableGithubObject): + """ + This class represents a popylar Referrer for a GitHub repository. + The reference can be found here https://developer.github.com/v3/repos/traffic/ + """ + + def __repr__(self): + return self.get__repr__({ + "referrer": self._referrer.value, + "count": self._count.value, + "uniques": self._uniques.value + }) + + @property + def referrer(self): + """ + :type: string + """ + return self._referrer.value + + @property + def count(self): + """ + :type: integer + """ + return self._count.value + + @property + def uniques(self): + """ + :type: integer + """ + return self._uniques.value + + def _initAttributes(self): + self._referrer = github.GithubObject.NotSet + self._count = github.GithubObject.NotSet + self._uniques = github.GithubObject.NotSet + + def _useAttributes(self, attributes): + if "referrer" in attributes: # pragma no branch + self._referrer = self._makeStringAttribute(attributes["referrer"]) + if "count" in attributes: # pragma no branch + self._count = self._makeIntAttribute(attributes["count"]) + if "uniques" in attributes: # pragma no branch + self._uniques = self._makeIntAttribute(attributes["uniques"]) diff --git a/ext2/github/Repository.py b/ext2/github/Repository.py index 59b1acd390..6d3600207b 100644 --- a/ext2/github/Repository.py +++ b/ext2/github/Repository.py @@ -60,7 +60,12 @@ # Copyright 2018 per1234 # # Copyright 2018 sechastain # # Copyright 2018 sfdye # -# Copyright 2018 Vinay Hegde +# Copyright 2018 Vinay Hegde # +# Copyright 2018 Justin Kufro # +# Copyright 2018 Ivan Minno # +# Copyright 2018 Zilei Gu # +# Copyright 2018 Yves Zumbach # +# Copyright 2018 Leying Chen # # # # This file is part of PyGithub. # # http://pygithub.readthedocs.io/ # @@ -124,6 +129,10 @@ import github.StatsParticipation import github.StatsPunchCard import github.Stargazer +import github.Referrer +import github.Path +import github.Clones +import github.View import Consts @@ -1132,6 +1141,29 @@ def create_milestone(self, title, state=github.GithubObject.NotSet, description= ) return github.Milestone.Milestone(self._requester, headers, data, completed=True) + def create_project(self, name, body=github.GithubObject.NotSet): + """ + calls: `POST /repos/:owner/:repo/projects `_ + :param name: string + :param body: string + """ + assert isinstance(name, (str, unicode)), name + assert body is github.GithubObject.NotSet or isinstance(body, (str, unicode)), body + post_parameters = { + "name": name, + "body": body, + } + import_header = {"Accept": Consts.mediaTypeProjectsPreview} + if body is not github.GithubObject.NotSet: + post_parameters['body'] = body + headers, data = self._requester.requestJsonAndCheck( + "POST", + self.url + "/projects", + headers=import_header, + input=post_parameters + ) + return github.Project.Project(self._requester, headers, data, completed=True) + def create_pull(self, *args, **kwds): """ :calls: `POST /repos/:owner/:repo/pulls `_ @@ -1470,17 +1502,91 @@ def get_file_contents(self, path, ref=github.GithubObject.NotSet): ] return github.ContentFile.ContentFile(self._requester, headers, data, completed=True) + def get_top_referrers(self): + """ + :calls: `GET /repos/:owner/:repo/traffic/popular/referrers `_ + :rtype: :class:`list` of :class:`github.Referrer.Referrer` + """ + headers, data = self._requester.requestJsonAndCheck( + "GET", + self.url + "/traffic/popular/referrers" + ) + if isinstance(data, list): + return [ + github.Referrer.Referrer(self._requester, headers, item, completed=True) + for item in data + ] + + def get_top_paths(self): + """ + :calls: `GET /repos/:owner/:repo/traffic/popular/paths `_ + :rtype: :class:`list` of :class:`github.Path.Path` + """ + headers, data = self._requester.requestJsonAndCheck( + "GET", + self.url + "/traffic/popular/paths" + ) + if isinstance(data, list): + return [ + github.Path.Path(self._requester, headers, item, completed=True) + for item in data + ] + + def get_views_traffic(self, per=github.GithubObject.NotSet): + """ + :calls: `GET /repos/:owner/:repo/traffic/views `_ + :param per: string, must be one of day or week, day by default + :rtype: None or list of :class:`github.View.View` + """ + assert per is github.GithubObject.NotSet or (isinstance(per, (str, unicode)) and (per == "day" or per == "week")), "per must be day or week, day by default" + url_parameters = dict() + if per is not github.GithubObject.NotSet: + url_parameters["per"] = per + headers, data = self._requester.requestJsonAndCheck( + "GET", + self.url + "/traffic/views", + parameters=url_parameters + ) + if (isinstance(data, dict)) and ("views" in data) and (isinstance(data["views"], list)): + data["views"] = [ + github.View.View(self._requester, headers, item, completed=True) + for item in data["views"] + ] + return data + + def get_clones_traffic(self, per=github.GithubObject.NotSet): + """ + :calls: `GET /repos/:owner/:repo/traffic/clones `_ + :param per: string, must be one of day or week, day by default + :rtype: None or list of :class:`github.Clone.Clone` + """ + assert per is github.GithubObject.NotSet or (isinstance(per, (str, unicode)) and (per == "day" or per == "week")), "per must be day or week, day by default" + url_parameters = dict() + if per is not github.GithubObject.NotSet: + url_parameters["per"] = per + headers, data = self._requester.requestJsonAndCheck( + "GET", + self.url + "/traffic/clones", + parameters=url_parameters + ) + if (isinstance(data, dict)) and ("clones" in data) and (isinstance(data["clones"], list)): + data["clones"] = [ + github.Clones.Clones(self._requester, headers, item, completed=True) + for item in data["clones"] + ] + return data + def get_projects(self, state=github.GithubObject.NotSet): """ :calls: `GET /repos/:owner/:repo/projects `_ :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Project.Project` :param state: string """ - + url_parameters = dict() if state is not github.GithubObject.NotSet: url_parameters["state"] = state - + return github.PaginatedList.PaginatedList( github.Project.Project, self._requester, @@ -1883,7 +1989,7 @@ def get_issues(self, milestone=github.GithubObject.NotSet, state=github.GithubOb """ :calls: `GET /repos/:owner/:repo/issues `_ :param milestone: :class:`github.Milestone.Milestone` or "none" or "*" - :param state: string + :param state: string. `open`, `closed`, or `all`. If this is not set the GitHub API default behavior will be used. At the moment this is to return only open issues. This might change anytime on GitHub API side and it could be clever to explicitly specify the state value. :param assignee: string or :class:`github.NamedUser.NamedUser` or "none" or "*" :param mentioned: :class:`github.NamedUser.NamedUser` :param labels: list of :class:`github.Label.Label` @@ -2839,7 +2945,7 @@ def _useAttributes(self, attributes): self._teams_url = self._makeStringAttribute(attributes["teams_url"]) if "trees_url" in attributes: # pragma no branch self._trees_url = self._makeStringAttribute(attributes["trees_url"]) - if "topics" in attributes: # pragma no branch + if "topics" in attributes: # pragma no branch self._topics = self._makeListOfStringsAttribute(attributes["topics"]) if "updated_at" in attributes: # pragma no branch self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"]) diff --git a/ext2/github/Requester.py b/ext2/github/Requester.py index 85cbe4cffb..3ac8a9fa37 100644 --- a/ext2/github/Requester.py +++ b/ext2/github/Requester.py @@ -381,8 +381,8 @@ def __requestEncode(self, cnx, verb, url, parameters, requestHeaders, input, enc if Consts.headerRateReset in responseHeaders: self.rate_limiting_resettime = int(responseHeaders[Consts.headerRateReset]) - if "x-oauth-scopes" in responseHeaders: - self.oauth_scopes = responseHeaders["x-oauth-scopes"].split(", ") + if Consts.headerOAuthScopes in responseHeaders: + self.oauth_scopes = responseHeaders[Consts.headerOAuthScopes].split(", ") self.DEBUG_ON_RESPONSE(status, responseHeaders, output) diff --git a/ext2/github/Topic.py b/ext2/github/Topic.py new file mode 100644 index 0000000000..c347c2c280 --- /dev/null +++ b/ext2/github/Topic.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- + +############################ Copyrights and license ############################ +# # +# Copyright 2018 Steve Kowalik # +# # +# This file is part of PyGithub. # +# http://pygithub.readthedocs.io/ # +# # +# PyGithub is free software: you can redistribute it and/or modify it under # +# the terms of the GNU Lesser General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # +# details. # +# # +# You should have received a copy of the GNU Lesser General Public License # +# along with PyGithub. If not, see . # +# # +################################################################################ + +import github.GithubObject + + +class Topic(github.GithubObject.CompletableGithubObject): + """ + This class represents topics as used by https://github.com/topics. The object refereence can be found here https://developer.github.com/v3/search/#search-topics + """ + + def __repr__(self): + return self.get__repr__({"name": self._name.value}) + + @property + def name(self): + """ + :type: string + """ + self._completeIfNotSet(self._name) + return self._name.value + + @property + def display_name(self): + """ + :type: string + """ + self._completeIfNotSet(self._display_name) + return self._display_name.value + + @property + def short_description(self): + """ + :type: string + """ + self._completeIfNotSet(self._short_description) + return self._short_description.value + + @property + def description(self): + """ + :type: string + """ + self._completeIfNotSet(self._description) + return self._description.value + + def _initAttributes(self): + self._name = github.GithubObject.NotSet + self._display_name = github.GithubObject.NotSet + self._short_description = github.GithubObject.NotSet + self._description = github.GithubObject.NotSet + + def _useAttributes(self, attributes): + if "name" in attributes: # pragma no branch + self._name = self._makeStringAttribute(attributes["name"]) + if "display_name" in attributes: # pragma no branch + self._display_name = self._makeStringAttribute(attributes["display_name"]) + if "short_description" in attributes: # pragma no branch + self._short_description = self._makeStringAttribute(attributes["short_description"]) + if "description" in attributes: # pragma no branch + self._description = self._makeStringAttribute(attributes["description"]) diff --git a/ext2/github/View.py b/ext2/github/View.py new file mode 100644 index 0000000000..ed0bce5d06 --- /dev/null +++ b/ext2/github/View.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +############################ Copyrights and license ############################ +# # +# Copyright 2018 Justin Kufro # +# Copyright 2018 Ivan Minno # +# Copyright 2018 Zilei Gu # +# Copyright 2018 Yves Zumbach # +# Copyright 2018 Leying Chen # +# # +# This file is part of PyGithub. # +# http://pygithub.readthedocs.io/ # +# # +# PyGithub is free software: you can redistribute it and/or modify it under # +# the terms of the GNU Lesser General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # +# details. # +# # +# You should have received a copy of the GNU Lesser General Public License # +# along with PyGithub. If not, see . # +# # +################################################################################ + +import github.GithubObject + + +class View(github.GithubObject.NonCompletableGithubObject): + """ + This class represents a popular Path for a GitHub repository. + The reference can be found here https://developer.github.com/v3/repos/traffic/ + """ + + def __repr__(self): + return self.get__repr__({ + "timestamp": self._timestamp.value, + "count": self._count.value, + "uniques": self._uniques.value + }) + + @property + def timestamp(self): + """ + :type: datetime.datetime + """ + return self._timestamp.value + + @property + def count(self): + """ + :type: integer + """ + return self._count.value + + @property + def uniques(self): + """ + :type: integer + """ + return self._uniques.value + + def _initAttributes(self): + self._timestamp = github.GithubObject.NotSet + self._count = github.GithubObject.NotSet + self._uniques = github.GithubObject.NotSet + + def _useAttributes(self, attributes): + if "timestamp" in attributes: # pragma no branch + self._timestamp = self._makeDatetimeAttribute(attributes["timestamp"]) + if "count" in attributes: # pragma no branch + self._count = self._makeIntAttribute(attributes["count"]) + if "uniques" in attributes: # pragma no branch + self._uniques = self._makeIntAttribute(attributes["uniques"]) diff --git a/ext3/bs4/__init__.py b/ext3/bs4/__init__.py index 797a6826eb..008ec9f3c9 100644 --- a/ext3/bs4/__init__.py +++ b/ext3/bs4/__init__.py @@ -17,12 +17,10 @@ """ -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - __author__ = "Leonard Richardson (leonardr@segfault.org)" -__version__ = "4.6.3" -__copyright__ = "Copyright (c) 2004-2018 Leonard Richardson" +__version__ = "4.7.1" +__copyright__ = "Copyright (c) 2004-2019 Leonard Richardson" +# Use of this source code is governed by the MIT license. __license__ = "MIT" __all__ = ['BeautifulSoup'] @@ -237,10 +235,11 @@ def deprecated_argument(old_name, new_name): self.builder = builder self.is_xml = builder.is_xml self.known_xml = self.is_xml - self.builder.soup = self - + self._namespaces = dict() self.parse_only = parse_only + self.builder.initialize_soup(self) + if hasattr(markup, 'read'): # It's a file-type object. markup = markup.read() elif len(markup) <= 256 and ( @@ -382,7 +381,7 @@ def popTag(self): def pushTag(self, tag): #print "Push", tag.name - if self.currentTag: + if self.currentTag is not None: self.currentTag.contents.append(tag) self.tagStack.append(tag) self.currentTag = self.tagStack[-1] @@ -421,60 +420,71 @@ def endData(self, containerClass=NavigableString): def object_was_parsed(self, o, parent=None, most_recent_element=None): """Add an object to the parse tree.""" - parent = parent or self.currentTag - previous_element = most_recent_element or self._most_recent_element + if parent is None: + parent = self.currentTag + if most_recent_element is not None: + previous_element = most_recent_element + else: + previous_element = self._most_recent_element next_element = previous_sibling = next_sibling = None if isinstance(o, Tag): next_element = o.next_element next_sibling = o.next_sibling previous_sibling = o.previous_sibling - if not previous_element: + if previous_element is None: previous_element = o.previous_element + fix = parent.next_element is not None + o.setup(parent, previous_element, next_element, previous_sibling, next_sibling) self._most_recent_element = o parent.contents.append(o) - if parent.next_sibling: - # This node is being inserted into an element that has - # already been parsed. Deal with any dangling references. - index = len(parent.contents)-1 - while index >= 0: - if parent.contents[index] is o: - break - index -= 1 - else: - raise ValueError( - "Error building tree: supposedly %r was inserted " - "into %r after the fact, but I don't see it!" % ( - o, parent - ) - ) - if index == 0: - previous_element = parent - previous_sibling = None - else: - previous_element = previous_sibling = parent.contents[index-1] - if index == len(parent.contents)-1: - next_element = parent.next_sibling - next_sibling = None - else: - next_element = next_sibling = parent.contents[index+1] - - o.previous_element = previous_element - if previous_element: - previous_element.next_element = o - o.next_element = next_element - if next_element: - next_element.previous_element = o - o.next_sibling = next_sibling - if next_sibling: - next_sibling.previous_sibling = o - o.previous_sibling = previous_sibling - if previous_sibling: - previous_sibling.next_sibling = o + # Check if we are inserting into an already parsed node. + if fix: + self._linkage_fixer(parent) + + def _linkage_fixer(self, el): + """Make sure linkage of this fragment is sound.""" + + first = el.contents[0] + child = el.contents[-1] + descendant = child + + if child is first and el.parent is not None: + # Parent should be linked to first child + el.next_element = child + # We are no longer linked to whatever this element is + prev_el = child.previous_element + if prev_el is not None and prev_el is not el: + prev_el.next_element = None + # First child should be linked to the parent, and no previous siblings. + child.previous_element = el + child.previous_sibling = None + + # We have no sibling as we've been appended as the last. + child.next_sibling = None + + # This index is a tag, dig deeper for a "last descendant" + if isinstance(child, Tag) and child.contents: + descendant = child._last_descendant(False) + + # As the final step, link last descendant. It should be linked + # to the parent's next sibling (if found), else walk up the chain + # and find a parent with a sibling. It should have no next sibling. + descendant.next_element = None + descendant.next_sibling = None + target = el + while True: + if target is None: + break + elif target.next_sibling is not None: + descendant.next_element = target.next_sibling + target.next_sibling.previous_element = child + break + target = target.parent def _popToTag(self, name, nsprefix=None, inclusivePop=True): """Pops the tag stack up to and including the most recent @@ -520,7 +530,7 @@ def handle_starttag(self, name, namespace, nsprefix, attrs): self.currentTag, self._most_recent_element) if tag is None: return tag - if self._most_recent_element: + if self._most_recent_element is not None: self._most_recent_element.next_element = tag self._most_recent_element = tag self.pushTag(tag) diff --git a/ext3/bs4/builder/__init__.py b/ext3/bs4/builder/__init__.py index b80ad6845c..d1625283ff 100644 --- a/ext3/bs4/builder/__init__.py +++ b/ext3/bs4/builder/__init__.py @@ -1,5 +1,5 @@ -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +# Use of this source code is governed by the MIT license. +__license__ = "MIT" from collections import defaultdict import itertools @@ -8,7 +8,7 @@ CharsetMetaAttributeValue, ContentMetaAttributeValue, HTMLAwareEntitySubstitution, - whitespace_re + nonwhitespace_re ) __all__ = [ @@ -102,6 +102,12 @@ class TreeBuilder(object): def __init__(self): self.soup = None + def initialize_soup(self, soup): + """The BeautifulSoup object has been initialized and is now + being associated with the TreeBuilder. + """ + self.soup = soup + def reset(self): pass @@ -167,7 +173,7 @@ def _replace_cdata_list_attribute_values(self, tag_name, attrs): # values. Split it into a list. value = attrs[attr] if isinstance(value, str): - values = whitespace_re.split(value) + values = nonwhitespace_re.findall(value) else: # html5lib sometimes calls setAttributes twice # for the same tag when rearranging the parse diff --git a/ext3/bs4/builder/_html5lib.py b/ext3/bs4/builder/_html5lib.py index d9d468f5bb..a04abb0353 100644 --- a/ext3/bs4/builder/_html5lib.py +++ b/ext3/bs4/builder/_html5lib.py @@ -1,5 +1,5 @@ -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +# Use of this source code is governed by the MIT license. +__license__ = "MIT" __all__ = [ 'HTML5TreeBuilder', @@ -15,7 +15,7 @@ ) from bs4.element import ( NamespacedAttribute, - whitespace_re, + nonwhitespace_re, ) import html5lib from html5lib.constants import ( @@ -206,7 +206,7 @@ def __setitem__(self, name, value): # A node that is being cloned may have already undergone # this procedure. if not isinstance(value, list): - value = whitespace_re.split(value) + value = nonwhitespace_re.findall(value) self.element[name] = value def items(self): return list(self.attrs.items()) @@ -249,7 +249,7 @@ def appendChild(self, node): if not isinstance(child, str) and child.parent is not None: node.element.extract() - if (string_child and self.element.contents + if (string_child is not None and self.element.contents and self.element.contents[-1].__class__ == NavigableString): # We are appending a string onto another string. # TODO This has O(n^2) performance, for input like @@ -360,16 +360,16 @@ def reparentChildren(self, new_parent): # Set the first child's previous_element and previous_sibling # to elements within the new parent first_child = to_append[0] - if new_parents_last_descendant: + if new_parents_last_descendant is not None: first_child.previous_element = new_parents_last_descendant else: first_child.previous_element = new_parent_element first_child.previous_sibling = new_parents_last_child - if new_parents_last_descendant: + if new_parents_last_descendant is not None: new_parents_last_descendant.next_element = first_child else: new_parent_element.next_element = first_child - if new_parents_last_child: + if new_parents_last_child is not None: new_parents_last_child.next_sibling = first_child # Find the very last element being moved. It is now the @@ -379,7 +379,7 @@ def reparentChildren(self, new_parent): last_childs_last_descendant = to_append[-1]._last_descendant(False, True) last_childs_last_descendant.next_element = new_parents_last_descendant_next_element - if new_parents_last_descendant_next_element: + if new_parents_last_descendant_next_element is not None: # TODO: This code has no test coverage and I'm not sure # how to get html5lib to go through this path, but it's # just the other side of the previous line. diff --git a/ext3/bs4/builder/_htmlparser.py b/ext3/bs4/builder/_htmlparser.py index 7ae60272dd..5c4892b85a 100644 --- a/ext3/bs4/builder/_htmlparser.py +++ b/ext3/bs4/builder/_htmlparser.py @@ -1,8 +1,8 @@ # encoding: utf-8 """Use the HTMLParser library to parse HTML files that aren't too bad.""" -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +# Use of this source code is governed by the MIT license. +__license__ = "MIT" __all__ = [ 'HTMLParserTreeBuilder', diff --git a/ext3/bs4/builder/_lxml.py b/ext3/bs4/builder/_lxml.py index 0dc9affede..95f7c1982c 100644 --- a/ext3/bs4/builder/_lxml.py +++ b/ext3/bs4/builder/_lxml.py @@ -1,5 +1,6 @@ -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +# Use of this source code is governed by the MIT license. +__license__ = "MIT" + __all__ = [ 'LXMLTreeBuilderForXML', 'LXMLTreeBuilder', @@ -32,6 +33,10 @@ LXML = 'lxml' +def _invert(d): + "Invert a dictionary." + return dict((v,k) for k, v in list(d.items())) + class LXMLTreeBuilderForXML(TreeBuilder): DEFAULT_PARSER_CLASS = etree.XMLParser @@ -48,7 +53,29 @@ class LXMLTreeBuilderForXML(TreeBuilder): # This namespace mapping is specified in the XML Namespace # standard. - DEFAULT_NSMAPS = {'http://www.w3.org/XML/1998/namespace' : "xml"} + DEFAULT_NSMAPS = dict(xml='http://www.w3.org/XML/1998/namespace') + + DEFAULT_NSMAPS_INVERTED = _invert(DEFAULT_NSMAPS) + + def initialize_soup(self, soup): + """Let the BeautifulSoup object know about the standard namespace + mapping. + """ + super(LXMLTreeBuilderForXML, self).initialize_soup(soup) + self._register_namespaces(self.DEFAULT_NSMAPS) + + def _register_namespaces(self, mapping): + """Let the BeautifulSoup object know about namespaces encountered + while parsing the document. + + This might be useful later on when creating CSS selectors. + """ + for key, value in list(mapping.items()): + if key and key not in self.soup._namespaces: + # Let the BeautifulSoup object know about a new namespace. + # If there are multiple namespaces defined with the same + # prefix, the first one in the document takes precedence. + self.soup._namespaces[key] = value def default_parser(self, encoding): # This can either return a parser object or a class, which @@ -75,8 +102,8 @@ def __init__(self, parser=None, empty_element_tags=None): if empty_element_tags is not None: self.empty_element_tags = set(empty_element_tags) self.soup = None - self.nsmaps = [self.DEFAULT_NSMAPS] - + self.nsmaps = [self.DEFAULT_NSMAPS_INVERTED] + def _getNsTag(self, tag): # Split the namespace URL out of a fully-qualified lxml tag # name. Copied from lxml's src/lxml/sax.py. @@ -144,7 +171,7 @@ def feed(self, markup): raise ParserRejectedMarkup(str(e)) def close(self): - self.nsmaps = [self.DEFAULT_NSMAPS] + self.nsmaps = [self.DEFAULT_NSMAPS_INVERTED] def start(self, name, attrs, nsmap={}): # Make sure attrs is a mutable dict--lxml may send an immutable dictproxy. @@ -158,8 +185,14 @@ def start(self, name, attrs, nsmap={}): self.nsmaps.append(None) elif len(nsmap) > 0: # A new namespace mapping has come into play. - inverted_nsmap = dict((value, key) for key, value in list(nsmap.items())) - self.nsmaps.append(inverted_nsmap) + + # First, Let the BeautifulSoup object know about it. + self._register_namespaces(nsmap) + + # Then, add it to our running list of inverted namespace + # mappings. + self.nsmaps.append(_invert(nsmap)) + # Also treat the namespace mapping as a set of attributes on the # tag, so we can recreate it later. attrs = attrs.copy() diff --git a/ext3/bs4/dammit.py b/ext3/bs4/dammit.py index ae6d4ad81d..f5fcdb4a01 100644 --- a/ext3/bs4/dammit.py +++ b/ext3/bs4/dammit.py @@ -6,8 +6,7 @@ Feed Parser. It works best on XML and HTML, but it does not rewrite the XML or HTML to reflect a new encoding; that's the tree builder's job. """ -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +# Use of this source code is governed by the MIT license. __license__ = "MIT" import codecs diff --git a/ext3/bs4/diagnose.py b/ext3/bs4/diagnose.py index f97c77992c..b5f6e6c8ba 100644 --- a/ext3/bs4/diagnose.py +++ b/ext3/bs4/diagnose.py @@ -1,7 +1,6 @@ """Diagnostic functions, mainly for use when doing tech support.""" -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +# Use of this source code is governed by the MIT license. __license__ = "MIT" import cProfile @@ -155,7 +154,7 @@ def rword(length=5): def rsentence(length=4): "Generate a random sentence-like string." - return " ".join(rword(random.randint(4,9)) for i in range(length)) + return " ".join(rword(random.randint(4,9)) for i in list(range(length))) def rdoc(num_elements=1000): """Randomly generate an invalid HTML document.""" diff --git a/ext3/bs4/element.py b/ext3/bs4/element.py index d938905294..6ef80540e6 100644 --- a/ext3/bs4/element.py +++ b/ext3/bs4/element.py @@ -1,5 +1,4 @@ -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +# Use of this source code is governed by the MIT license. __license__ = "MIT" try: @@ -7,14 +6,25 @@ except ImportError as e: from collections import Callable import re -import shlex import sys import warnings +try: + import soupsieve +except ImportError as e: + soupsieve = None + warnings.warn( + 'The soupsieve package is not installed. CSS selectors cannot be used.' + ) + from bs4.dammit import EntitySubstitution DEFAULT_OUTPUT_ENCODING = "utf-8" PY3K = (sys.version_info[0] > 2) +nonwhitespace_re = re.compile(r"\S+") + +# NOTE: This isn't used as of 4.7.0. I'm leaving it for a little bit on +# the off chance someone imported it for their own use. whitespace_re = re.compile(r"\s+") def _alias(attr): @@ -207,7 +217,7 @@ def format_string(self, s, formatter='minimal'): if formatter is None: output = s else: - if callable(formatter): + if isinstance(formatter, Callable): # Backwards compatibility -- you used to pass in a formatting method. output = formatter(s) else: @@ -256,26 +266,26 @@ def setup(self, parent=None, previous_element=None, next_element=None, self.previous_element.next_element = self self.next_element = next_element - if self.next_element: + if self.next_element is not None: self.next_element.previous_element = self self.next_sibling = next_sibling - if self.next_sibling: + if self.next_sibling is not None: self.next_sibling.previous_sibling = self - if (not previous_sibling + if (previous_sibling is None and self.parent is not None and self.parent.contents): previous_sibling = self.parent.contents[-1] self.previous_sibling = previous_sibling - if previous_sibling: + if previous_sibling is not None: self.previous_sibling.next_sibling = self nextSibling = _alias("next_sibling") # BS3 previousSibling = _alias("previous_sibling") # BS3 def replace_with(self, replace_with): - if not self.parent: + if self.parent is None: raise ValueError( "Cannot replace one element with another when the" "element to be replaced is not part of a tree.") @@ -292,7 +302,7 @@ def replace_with(self, replace_with): def unwrap(self): my_parent = self.parent - if not self.parent: + if self.parent is None: raise ValueError( "Cannot replace an element with its contents when that" "element is not part of a tree.") @@ -340,7 +350,7 @@ def extract(self): def _last_descendant(self, is_initialized=True, accept_self=True): "Finds the last element beneath this object to be parsed." - if is_initialized and self.next_sibling: + if is_initialized and self.next_sibling is not None: last_child = self.next_sibling.previous_element else: last_child = self @@ -430,43 +440,54 @@ def append(self, tag): """Appends the given tag to the contents of this tag.""" self.insert(len(self.contents), tag) - def insert_before(self, predecessor): - """Makes the given element the immediate predecessor of this one. + def extend(self, tags): + """Appends the given tags to the contents of this tag.""" + for tag in tags: + self.append(tag) - The two elements will have the same parent, and the given element + def insert_before(self, *args): + """Makes the given element(s) the immediate predecessor of this one. + + The elements will have the same parent, and the given elements will be immediately before this one. """ - if self is predecessor: - raise ValueError("Can't insert an element before itself.") parent = self.parent if parent is None: raise ValueError( "Element has no parent, so 'before' has no meaning.") - # Extract first so that the index won't be screwed up if they - # are siblings. - if isinstance(predecessor, PageElement): - predecessor.extract() - index = parent.index(self) - parent.insert(index, predecessor) - - def insert_after(self, successor): - """Makes the given element the immediate successor of this one. - - The two elements will have the same parent, and the given element + if any(x is self for x in args): + raise ValueError("Can't insert an element before itself.") + for predecessor in args: + # Extract first so that the index won't be screwed up if they + # are siblings. + if isinstance(predecessor, PageElement): + predecessor.extract() + index = parent.index(self) + parent.insert(index, predecessor) + + def insert_after(self, *args): + """Makes the given element(s) the immediate successor of this one. + + The elements will have the same parent, and the given elements will be immediately after this one. """ - if self is successor: - raise ValueError("Can't insert an element after itself.") + # Do all error checking before modifying the tree. parent = self.parent if parent is None: raise ValueError( "Element has no parent, so 'after' has no meaning.") - # Extract first so that the index won't be screwed up if they - # are siblings. - if isinstance(successor, PageElement): - successor.extract() - index = parent.index(self) - parent.insert(index+1, successor) + if any(x is self for x in args): + raise ValueError("Can't insert an element after itself.") + + offset = 0 + for successor in args: + # Extract first so that the index won't be screwed up if they + # are siblings. + if isinstance(successor, PageElement): + successor.extract() + index = parent.index(self) + parent.insert(index+1+offset, successor) + offset += 1 def find_next(self, name=None, attrs={}, text=None, **kwargs): """Returns the first item that matches the given criteria and @@ -657,82 +678,6 @@ def parents(self): yield i i = i.parent - # Methods for supporting CSS selectors. - - tag_name_re = re.compile('^[a-zA-Z0-9][-.a-zA-Z0-9:_]*$') - - # /^([a-zA-Z0-9][-.a-zA-Z0-9:_]*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/ - # \---------------------------/ \---/\-------------/ \-------/ - # | | | | - # | | | The value - # | | ~,|,^,$,* or = - # | Attribute - # Tag - attribselect_re = re.compile( - r'^(?P[a-zA-Z0-9][-.a-zA-Z0-9:_]*)?\[(?P[\w-]+)(?P[=~\|\^\$\*]?)' + - r'=?"?(?P[^\]"]*)"?\]$' - ) - - def _attr_value_as_string(self, value, default=None): - """Force an attribute value into a string representation. - - A multi-valued attribute will be converted into a - space-separated stirng. - """ - value = self.get(value, default) - if isinstance(value, list) or isinstance(value, tuple): - value =" ".join(value) - return value - - def _tag_name_matches_and(self, function, tag_name): - if not tag_name: - return function - else: - def _match(tag): - return tag.name == tag_name and function(tag) - return _match - - def _attribute_checker(self, operator, attribute, value=''): - """Create a function that performs a CSS selector operation. - - Takes an operator, attribute and optional value. Returns a - function that will return True for elements that match that - combination. - """ - if operator == '=': - # string representation of `attribute` is equal to `value` - return lambda el: el._attr_value_as_string(attribute) == value - elif operator == '~': - # space-separated list representation of `attribute` - # contains `value` - def _includes_value(element): - attribute_value = element.get(attribute, []) - if not isinstance(attribute_value, list): - attribute_value = attribute_value.split() - return value in attribute_value - return _includes_value - elif operator == '^': - # string representation of `attribute` starts with `value` - return lambda el: el._attr_value_as_string( - attribute, '').startswith(value) - elif operator == '$': - # string representation of `attribute` ends with `value` - return lambda el: el._attr_value_as_string( - attribute, '').endswith(value) - elif operator == '*': - # string representation of `attribute` contains `value` - return lambda el: value in el._attr_value_as_string(attribute, '') - elif operator == '|': - # string representation of `attribute` is either exactly - # `value` or starts with `value` and then a dash. - def _is_or_starts_with_dash(element): - attribute_value = element._attr_value_as_string(attribute, '') - return (attribute_value == value or attribute_value.startswith( - value + '-')) - return _is_or_starts_with_dash - else: - return lambda el: el.has_attr(attribute) - # Old non-property versions of the generators, for backwards # compatibility with BS3. def nextGenerator(self): @@ -1193,7 +1138,7 @@ def decode(self, indent_level=None, # First off, turn a string formatter into a Formatter object. This # will stop the lookup from happening over and over again. - if not isinstance(formatter, Formatter) and not callable(formatter): + if not isinstance(formatter, Formatter) and not isinstance(formatter, Callable): formatter = self._formatter_for_name(formatter) attrs = [] if self.attrs: @@ -1298,7 +1243,7 @@ def decode_contents(self, indent_level=None, """ # First off, turn a string formatter into a Formatter object. This # will stop the lookup from happening over and over again. - if not isinstance(formatter, Formatter) and not callable(formatter): + if not isinstance(formatter, Formatter) and not isinstance(formatter, Callable): formatter = self._formatter_for_name(formatter) pretty_print = (indent_level is not None) @@ -1394,250 +1339,41 @@ def descendants(self): current = current.next_element # CSS selector code - - _selector_combinators = ['>', '+', '~'] - _select_debug = False - quoted_colon = re.compile('"[^"]*:[^"]*"') - def select_one(self, selector): + def select_one(self, selector, namespaces=None, **kwargs): """Perform a CSS selection operation on the current element.""" - value = self.select(selector, limit=1) + value = self.select(selector, namespaces, 1, **kwargs) if value: return value[0] return None - def select(self, selector, _candidate_generator=None, limit=None): - """Perform a CSS selection operation on the current element.""" + def select(self, selector, namespaces=None, limit=None, **kwargs): + """Perform a CSS selection operation on the current element. - # Handle grouping selectors if ',' exists, ie: p,a - if ',' in selector: - context = [] - selectors = [x.strip() for x in selector.split(",")] - - # If a selector is mentioned multiple times we don't want - # to use it more than once. - used_selectors = set() - - # We also don't want to select the same element more than once, - # if it's matched by multiple selectors. - selected_object_ids = set() - for partial_selector in selectors: - if partial_selector == '': - raise ValueError('Invalid group selection syntax: %s' % selector) - if partial_selector in used_selectors: - continue - used_selectors.add(partial_selector) - candidates = self.select(partial_selector, limit=limit) - for candidate in candidates: - # This lets us distinguish between distinct tags that - # represent the same markup. - object_id = id(candidate) - if object_id not in selected_object_ids: - context.append(candidate) - selected_object_ids.add(object_id) - if limit and len(context) >= limit: - break - return context - tokens = shlex.split(selector) - current_context = [self] + This uses the SoupSieve library. - if tokens[-1] in self._selector_combinators: - raise ValueError( - 'Final combinator "%s" is missing an argument.' % tokens[-1]) + :param selector: A string containing a CSS selector. - if self._select_debug: - print('Running CSS selector "%s"' % selector) + :param namespaces: A dictionary mapping namespace prefixes + used in the CSS selector to namespace URIs. By default, + Beautiful Soup will use the prefixes it encountered while + parsing the document. - for index, token in enumerate(tokens): - new_context = [] - new_context_ids = set([]) + :param limit: After finding this number of results, stop looking. - if tokens[index-1] in self._selector_combinators: - # This token was consumed by the previous combinator. Skip it. - if self._select_debug: - print(' Token was consumed by the previous combinator.') - continue - - if self._select_debug: - print(' Considering token "%s"' % token) - recursive_candidate_generator = None - tag_name = None - - # Each operation corresponds to a checker function, a rule - # for determining whether a candidate matches the - # selector. Candidates are generated by the active - # iterator. - checker = None - - m = self.attribselect_re.match(token) - if m is not None: - # Attribute selector - tag_name, attribute, operator, value = m.groups() - checker = self._attribute_checker(operator, attribute, value) - - elif '#' in token: - # ID selector - tag_name, tag_id = token.split('#', 1) - def id_matches(tag): - return tag.get('id', None) == tag_id - checker = id_matches - - elif '.' in token: - # Class selector - tag_name, klass = token.split('.', 1) - classes = set(klass.split('.')) - def classes_match(candidate): - return classes.issubset(candidate.get('class', [])) - checker = classes_match - - elif ':' in token and not self.quoted_colon.search(token): - # Pseudo-class - tag_name, pseudo = token.split(':', 1) - if tag_name == '': - raise ValueError( - "A pseudo-class must be prefixed with a tag name.") - pseudo_attributes = re.match(r'([a-zA-Z\d-]+)\(([a-zA-Z\d]+)\)', pseudo) - found = [] - if pseudo_attributes is None: - pseudo_type = pseudo - pseudo_value = None - else: - pseudo_type, pseudo_value = pseudo_attributes.groups() - if pseudo_type == 'nth-of-type': - try: - pseudo_value = int(pseudo_value) - except: - raise NotImplementedError( - 'Only numeric values are currently supported for the nth-of-type pseudo-class.') - if pseudo_value < 1: - raise ValueError( - 'nth-of-type pseudo-class value must be at least 1.') - class Counter(object): - def __init__(self, destination): - self.count = 0 - self.destination = destination - - def nth_child_of_type(self, tag): - self.count += 1 - if self.count == self.destination: - return True - else: - return False - checker = Counter(pseudo_value).nth_child_of_type - else: - raise NotImplementedError( - 'Only the following pseudo-classes are implemented: nth-of-type.') - - elif token == '*': - # Star selector -- matches everything - pass - elif token == '>': - # Run the next token as a CSS selector against the - # direct children of each tag in the current context. - recursive_candidate_generator = lambda tag: tag.children - elif token == '~': - # Run the next token as a CSS selector against the - # siblings of each tag in the current context. - recursive_candidate_generator = lambda tag: tag.next_siblings - elif token == '+': - # For each tag in the current context, run the next - # token as a CSS selector against the tag's next - # sibling that's a tag. - def next_tag_sibling(tag): - yield tag.find_next_sibling(True) - recursive_candidate_generator = next_tag_sibling - - elif self.tag_name_re.match(token): - # Just a tag name. - tag_name = token - else: - raise ValueError( - 'Unsupported or invalid CSS selector: "%s"' % token) - if recursive_candidate_generator: - # This happens when the selector looks like "> foo". - # - # The generator calls select() recursively on every - # member of the current context, passing in a different - # candidate generator and a different selector. - # - # In the case of "> foo", the candidate generator is - # one that yields a tag's direct children (">"), and - # the selector is "foo". - next_token = tokens[index+1] - def recursive_select(tag): - if self._select_debug: - print(' Calling select("%s") recursively on %s %s' % (next_token, tag.name, tag.attrs)) - print('-' * 40) - for i in tag.select(next_token, recursive_candidate_generator): - if self._select_debug: - print('(Recursive select picked up candidate %s %s)' % (i.name, i.attrs)) - yield i - if self._select_debug: - print('-' * 40) - _use_candidate_generator = recursive_select - elif _candidate_generator is None: - # By default, a tag's candidates are all of its - # children. If tag_name is defined, only yield tags - # with that name. - if self._select_debug: - if tag_name: - check = "[any]" - else: - check = tag_name - print(' Default candidate generator, tag name="%s"' % check) - if self._select_debug: - # This is redundant with later code, but it stops - # a bunch of bogus tags from cluttering up the - # debug log. - def default_candidate_generator(tag): - for child in tag.descendants: - if not isinstance(child, Tag): - continue - if tag_name and not child.name == tag_name: - continue - yield child - _use_candidate_generator = default_candidate_generator - else: - _use_candidate_generator = lambda tag: tag.descendants - else: - _use_candidate_generator = _candidate_generator - - count = 0 - for tag in current_context: - if self._select_debug: - print(" Running candidate generator on %s %s" % ( - tag.name, repr(tag.attrs))) - for candidate in _use_candidate_generator(tag): - if not isinstance(candidate, Tag): - continue - if tag_name and candidate.name != tag_name: - continue - if checker is not None: - try: - result = checker(candidate) - except StopIteration: - # The checker has decided we should no longer - # run the generator. - break - if checker is None or result: - if self._select_debug: - print(" SUCCESS %s %s" % (candidate.name, repr(candidate.attrs))) - if id(candidate) not in new_context_ids: - # If a tag matches a selector more than once, - # don't include it in the context more than once. - new_context.append(candidate) - new_context_ids.add(id(candidate)) - elif self._select_debug: - print(" FAILURE %s %s" % (candidate.name, repr(candidate.attrs))) - - current_context = new_context - if limit and len(current_context) >= limit: - current_context = current_context[:limit] - - if self._select_debug: - print("Final verdict:") - for i in current_context: - print(" %s %s" % (i.name, i.attrs)) - return current_context + :param kwargs: Any extra arguments you'd like to pass in to + soupsieve.select(). + """ + if namespaces is None: + namespaces = self._namespaces + + if limit is None: + limit = 0 + if soupsieve is None: + raise NotImplementedError( + "Cannot execute CSS selectors because the soupsieve package is not installed." + ) + + return soupsieve.select(selector, self, namespaces, limit, **kwargs) # Old names for backwards compatibility def childGenerator(self): @@ -1689,7 +1425,7 @@ def __init__(self, name=None, attrs={}, text=None, **kwargs): def _normalize_search_value(self, value): # Leave it alone if it's a Unicode string, a callable, a # regular expression, a boolean, or None. - if (isinstance(value, str) or callable(value) or hasattr(value, 'match') + if (isinstance(value, str) or isinstance(value, Callable) or hasattr(value, 'match') or isinstance(value, bool) or value is None): return value diff --git a/ext3/bs4/testing.py b/ext3/bs4/testing.py index 78dd1c2763..4d0d98b4e1 100644 --- a/ext3/bs4/testing.py +++ b/ext3/bs4/testing.py @@ -1,8 +1,7 @@ # encoding: utf-8 """Helper classes for tests.""" -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +# Use of this source code is governed by the MIT license. __license__ = "MIT" import pickle @@ -17,11 +16,48 @@ ContentMetaAttributeValue, Doctype, SoupStrainer, + Tag ) from bs4.builder import HTMLParserTreeBuilder default_builder = HTMLParserTreeBuilder +BAD_DOCUMENT = """A bare string + + +
+
HTML5 does allow CDATA sections in SVG
+
A tag
+
A
tag that supposedly has contents.
+
AT&T
+
+
+
This numeric entity is missing the final semicolon:
+ +
a
+
This document contains (do you see it?)
+
This document ends with That attribute value was bogus
+The doctype is invalid because it contains extra whitespace +
That boolean attribute had no value
+
Here's a nonexistent entity: &#foo; (do you see it?)
+
This document ends before the entity finishes: > +

Paragraphs shouldn't contain block display elements, but this one does:

you see?

+Multiple values for the same attribute. +
Here's a table
+
+
This tag contains nothing but whitespace:
+

This p tag is cut off by

the end of the blockquote tag
+
Here's a nested table:
foo
This table contains bare markup
+ +
This document contains a surprise doctype
+ +
Tag name contains Unicode characters
+ + +""" + class SoupTest(unittest.TestCase): @@ -60,6 +96,121 @@ def assertConnectedness(self, element): self.assertEqual(earlier, e.previous_element) earlier = e + def linkage_validator(self, el, _recursive_call=False): + """Ensure proper linkage throughout the document.""" + descendant = None + # Document element should have no previous element or previous sibling. + # It also shouldn't have a next sibling. + if el.parent is None: + assert el.previous_element is None,\ + "Bad previous_element\nNODE: {}\nPREV: {}\nEXPECTED: {}".format( + el, el.previous_element, None + ) + assert el.previous_sibling is None,\ + "Bad previous_sibling\nNODE: {}\nPREV: {}\nEXPECTED: {}".format( + el, el.previous_sibling, None + ) + assert el.next_sibling is None,\ + "Bad next_sibling\nNODE: {}\nNEXT: {}\nEXPECTED: {}".format( + el, el.next_sibling, None + ) + + idx = 0 + child = None + last_child = None + last_idx = len(el.contents) - 1 + for child in el.contents: + descendant = None + + # Parent should link next element to their first child + # That child should have no previous sibling + if idx == 0: + if el.parent is not None: + assert el.next_element is child,\ + "Bad next_element\nNODE: {}\nNEXT: {}\nEXPECTED: {}".format( + el, el.next_element, child + ) + assert child.previous_element is el,\ + "Bad previous_element\nNODE: {}\nPREV: {}\nEXPECTED: {}".format( + child, child.previous_element, el + ) + assert child.previous_sibling is None,\ + "Bad previous_sibling\nNODE: {}\nPREV {}\nEXPECTED: {}".format( + child, child.previous_sibling, None + ) + + # If not the first child, previous index should link as sibling to this index + # Previous element should match the last index or the last bubbled up descendant + else: + assert child.previous_sibling is el.contents[idx - 1],\ + "Bad previous_sibling\nNODE: {}\nPREV {}\nEXPECTED {}".format( + child, child.previous_sibling, el.contents[idx - 1] + ) + assert el.contents[idx - 1].next_sibling is child,\ + "Bad next_sibling\nNODE: {}\nNEXT {}\nEXPECTED {}".format( + el.contents[idx - 1], el.contents[idx - 1].next_sibling, child + ) + + if last_child is not None: + assert child.previous_element is last_child,\ + "Bad previous_element\nNODE: {}\nPREV {}\nEXPECTED {}\nCONTENTS {}".format( + child, child.previous_element, last_child, child.parent.contents + ) + assert last_child.next_element is child,\ + "Bad next_element\nNODE: {}\nNEXT {}\nEXPECTED {}".format( + last_child, last_child.next_element, child + ) + + if isinstance(child, Tag) and child.contents: + descendant = self.linkage_validator(child, True) + # A bubbled up descendant should have no next siblings + assert descendant.next_sibling is None,\ + "Bad next_sibling\nNODE: {}\nNEXT {}\nEXPECTED {}".format( + descendant, descendant.next_sibling, None + ) + + # Mark last child as either the bubbled up descendant or the current child + if descendant is not None: + last_child = descendant + else: + last_child = child + + # If last child, there are non next siblings + if idx == last_idx: + assert child.next_sibling is None,\ + "Bad next_sibling\nNODE: {}\nNEXT {}\nEXPECTED {}".format( + child, child.next_sibling, None + ) + idx += 1 + + child = descendant if descendant is not None else child + if child is None: + child = el + + if not _recursive_call and child is not None: + target = el + while True: + if target is None: + assert child.next_element is None, \ + "Bad next_element\nNODE: {}\nNEXT {}\nEXPECTED {}".format( + child, child.next_element, None + ) + break + elif target.next_sibling is not None: + assert child.next_element is target.next_sibling, \ + "Bad next_element\nNODE: {}\nNEXT {}\nEXPECTED {}".format( + child, child.next_element, target.next_sibling + ) + break + target = target.parent + + # We are done, so nothing to return + return None + else: + # Return the child to the recursive caller + return child + + class HTMLTreeBuilderSmokeTest(object): """A basic test of a treebuilder's competence. @@ -301,6 +452,18 @@ def test_correctly_nested_tables(self): "Bar" "Baz") + def test_multivalued_attribute_with_whitespace(self): + # Whitespace separating the values of a multi-valued attribute + # should be ignored. + + markup = '
' + soup = self.soup(markup) + self.assertEqual(['foo', 'bar'], soup.div['class']) + + # If you search by the literal name of the class it's like the whitespace + # wasn't there. + self.assertEqual(soup.div, soup.find('div', class_="foo bar")) + def test_deeply_nested_multivalued_attribute(self): # html5lib can set the attributes of the same tag many times # as it rearranges the tree. This has caused problems with @@ -615,6 +778,13 @@ def test_tag_with_no_attributes_can_have_attributes_added(self): data.a['foo'] = 'bar' self.assertEqual('text', data.a.decode()) + def test_worst_case(self): + """Test the worst case (currently) for linking issues.""" + + soup = self.soup(BAD_DOCUMENT) + self.linkage_validator(soup) + + class XMLTreeBuilderSmokeTest(object): def test_pickle_and_unpickle_identity(self): @@ -761,6 +931,12 @@ def test_copy_tag_preserves_namespace(self): # The two tags have the same namespace prefix. self.assertEqual(tag.prefix, duplicate.prefix) + def test_worst_case(self): + """Test the worst case (currently) for linking issues.""" + + soup = self.soup(BAD_DOCUMENT) + self.linkage_validator(soup) + class HTML5TreeBuilderSmokeTest(HTMLTreeBuilderSmokeTest): """Smoke test for a tree builder that supports HTML5.""" diff --git a/ext3/bs4/tests/test_html5lib.py b/ext3/bs4/tests/test_html5lib.py index 81fb7d3b28..eaf73038aa 100644 --- a/ext3/bs4/tests/test_html5lib.py +++ b/ext3/bs4/tests/test_html5lib.py @@ -128,3 +128,43 @@ def test_foster_parenting(self): markup = b"""A""" soup = self.soup(markup) self.assertEqual("A
", soup.body.decode()) + + def test_extraction(self): + """ + Test that extraction does not destroy the tree. + + https://bugs.launchpad.net/beautifulsoup/+bug/1782928 + """ + + markup = """ + +

hello

+""" + soup = self.soup(markup) + [s.extract() for s in soup('script')] + [s.extract() for s in soup('style')] + + self.assertEqual(len(soup.find_all("p")), 1) + + def test_empty_comment(self): + """ + Test that empty comment does not break structure. + + https://bugs.launchpad.net/beautifulsoup/+bug/1806598 + """ + + markup = """ + + +
+ +
+ + +""" + soup = self.soup(markup) + inputs = [] + for form in soup.find_all('form'): + inputs.extend(form.find_all('input')) + self.assertEqual(len(inputs), 1) diff --git a/ext3/bs4/tests/test_lxml.py b/ext3/bs4/tests/test_lxml.py index f0c60a70ad..1e6d4a1512 100644 --- a/ext3/bs4/tests/test_lxml.py +++ b/ext3/bs4/tests/test_lxml.py @@ -80,3 +80,21 @@ class LXMLXMLTreeBuilderSmokeTest(SoupTest, XMLTreeBuilderSmokeTest): @property def default_builder(self): return LXMLTreeBuilderForXML() + + def test_namespace_indexing(self): + # We should not track un-prefixed namespaces as we can only hold one + # and it will be recognized as the default namespace by soupsieve, + # which may be confusing in some situations. When no namespace is provided + # for a selector, the default namespace (if defined) is assumed. + + soup = self.soup( + '\n' + '' + 'content' + 'content' + '' + ) + self.assertEqual( + soup._namespaces, + {'xml': 'http://www.w3.org/XML/1998/namespace', 'prefix': 'http://prefixed-namespace.com'} + ) diff --git a/ext3/bs4/tests/test_tree.py b/ext3/bs4/tests/test_tree.py index e5ea5aca6b..c96099c5eb 100644 --- a/ext3/bs4/tests/test_tree.py +++ b/ext3/bs4/tests/test_tree.py @@ -1,4 +1,3 @@ - # -*- coding: utf-8 -*- """Tests for Beautiful Soup's tree traversal methods. @@ -932,6 +931,13 @@ def test_append_child_thats_already_at_the_end(self): soup.a.append(soup.b) self.assertEqual(data, soup.decode()) + def test_extend(self): + data = "" + soup = self.soup(data) + l = [soup.g, soup.f, soup.e, soup.d, soup.c, soup.b] + soup.a.extend(l) + self.assertEqual("", soup.decode()) + def test_move_tag_to_beginning_of_parent(self): data = "" soup = self.soup(data) @@ -958,6 +964,29 @@ def test_insert_before(self): self.assertEqual( soup.decode(), self.document_for("QUUXbarfooBAZ")) + # Can't insert an element before itself. + b = soup.b + self.assertRaises(ValueError, b.insert_before, b) + + # Can't insert before if an element has no parent. + b.extract() + self.assertRaises(ValueError, b.insert_before, "nope") + + # Can insert an identical element + soup = self.soup("") + soup.a.insert_before(soup.new_tag("a")) + + def test_insert_multiple_before(self): + soup = self.soup("foobar") + soup.b.insert_before("BAZ", " ", "QUUX") + soup.a.insert_before("QUUX", " ", "BAZ") + self.assertEqual( + soup.decode(), self.document_for("QUUX BAZfooBAZ QUUXbar")) + + soup.a.insert_before(soup.b, "FOO") + self.assertEqual( + soup.decode(), self.document_for("QUUX BAZbarFOOfooBAZ QUUX")) + def test_insert_after(self): soup = self.soup("foobar") soup.b.insert_after("BAZ") @@ -968,6 +997,28 @@ def test_insert_after(self): self.assertEqual( soup.decode(), self.document_for("QUUXbarfooBAZ")) + # Can't insert an element after itself. + b = soup.b + self.assertRaises(ValueError, b.insert_after, b) + + # Can't insert after if an element has no parent. + b.extract() + self.assertRaises(ValueError, b.insert_after, "nope") + + # Can insert an identical element + soup = self.soup("") + soup.a.insert_before(soup.new_tag("a")) + + def test_insert_multiple_after(self): + soup = self.soup("foobar") + soup.b.insert_after("BAZ", " ", "QUUX") + soup.a.insert_after("QUUX", " ", "BAZ") + self.assertEqual( + soup.decode(), self.document_for("fooQUUX BAZbarBAZ QUUX")) + soup.b.insert_after(soup.a, "FOO ") + self.assertEqual( + soup.decode(), self.document_for("QUUX BAZbarfooFOO BAZ QUUX")) + def test_insert_after_raises_exception_if_after_has_no_meaning(self): soup = self.soup("") tag = soup.new_tag("a") @@ -1783,7 +1834,7 @@ def test_tag_no_match(self): self.assertEqual(len(self.soup.select('del')), 0) def test_invalid_tag(self): - self.assertRaises(ValueError, self.soup.select, 'tag%t') + self.assertRaises(SyntaxError, self.soup.select, 'tag%t') def test_select_dashed_tag_ids(self): self.assertSelects('custom-dashed-tag', ['dash1', 'dash2']) @@ -1974,8 +2025,7 @@ def test_unsupported_pseudoclass(self): NotImplementedError, self.soup.select, "a:no-such-pseudoclass") self.assertRaises( - NotImplementedError, self.soup.select, "a:nth-of-type(a)") - + SyntaxError, self.soup.select, "a:nth-of-type(a)") def test_nth_of_type(self): # Try to select first paragraph @@ -1992,9 +2042,9 @@ def test_nth_of_type(self): els = self.soup.select('div#inner p:nth-of-type(4)') self.assertEqual(len(els), 0) - # Pass in an invalid value. - self.assertRaises( - ValueError, self.soup.select, 'div p:nth-of-type(0)') + # Zero will select no tags. + els = self.soup.select('div p:nth-of-type(0)') + self.assertEqual(len(els), 0) def test_nth_of_type_direct_descendant(self): els = self.soup.select('div#inner > p:nth-of-type(1)') @@ -2031,7 +2081,7 @@ def test_general_sibling_selector(self): self.assertEqual([], self.soup.select('#inner ~ h2')) def test_dangling_combinator(self): - self.assertRaises(ValueError, self.soup.select, 'h1 >') + self.assertRaises(SyntaxError, self.soup.select, 'h1 >') def test_sibling_combinator_wont_select_same_tag_twice(self): self.assertSelects('p[lang] ~ p', ['lang-en-gb', 'lang-en-us', 'lang-fr']) @@ -2062,8 +2112,8 @@ def test_multiple_select_indirect_descendant(self): self.assertSelects('div x,y, z', ['xid', 'yid', 'zida', 'zidb', 'zidab', 'zidac']) def test_invalid_multiple_select(self): - self.assertRaises(ValueError, self.soup.select, ',x, y') - self.assertRaises(ValueError, self.soup.select, 'x,,y') + self.assertRaises(SyntaxError, self.soup.select, ',x, y') + self.assertRaises(SyntaxError, self.soup.select, 'x,,y') def test_multiple_select_attrs(self): self.assertSelects('p[lang=en], p[lang=en-gb]', ['lang-en', 'lang-en-gb']) @@ -2087,4 +2137,3 @@ def test_select_duplicate_elements(self): # order. for element in soup.find_all(class_=['c1', 'c2']): assert element in selected - diff --git a/ext3/github/AuthenticatedUser.py b/ext3/github/AuthenticatedUser.py index 9541df2dad..50b49cd2c3 100644 --- a/ext3/github/AuthenticatedUser.py +++ b/ext3/github/AuthenticatedUser.py @@ -55,6 +55,7 @@ import github.Event import github.Authorization import github.Notification +import github.Migration from . import Consts @@ -237,6 +238,14 @@ def name(self): self._completeIfNotSet(self._name) return self._name.value + @property + def node_id(self): + """ + :type: string + """ + self._completeIfNotSet(self._node_id) + return self._node_id.value + @property def organizations_url(self): """ @@ -1139,6 +1148,50 @@ def accept_invitation(self, invitation): input={} ) + def create_migration(self, repos, lock_repositories=github.GithubObject.NotSet, exclude_attachments=github.GithubObject.NotSet): + """ + :calls: `POST /user/migrations`_ + :param repos: list or tuple of str + :param lock_repositories: bool + :param exclude_attachments: bool + :rtype: :class:`github.Migration.Migration` + """ + assert isinstance(repos, (list, tuple)), repos + assert all(isinstance(repo, str) for repo in repos), repos + assert lock_repositories is github.GithubObject.NotSet or isinstance(lock_repositories, bool), lock_repositories + assert exclude_attachments is github.GithubObject.NotSet or isinstance(exclude_attachments, bool), exclude_attachments + post_parameters = { + "repositories": repos + } + if lock_repositories is not github.GithubObject.NotSet: + post_parameters["lock_repositories"] = lock_repositories + if exclude_attachments is not github.GithubObject.NotSet: + post_parameters["exclude_attachments"] = exclude_attachments + headers, data = self._requester.requestJsonAndCheck( + "POST", + "/user/migrations", + input=post_parameters, + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + return github.Migration.Migration(self._requester, headers, data, completed=True) + + def get_migrations(self): + """ + :calls: `GET /user/migrations`_ + :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Migration.Migration` + """ + return github.PaginatedList.PaginatedList( + github.Migration.Migration, + self._requester, + "/user/migrations", + None, + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + def _initAttributes(self): self._avatar_url = github.GithubObject.NotSet self._bio = github.GithubObject.NotSet @@ -1161,6 +1214,7 @@ def _initAttributes(self): self._location = github.GithubObject.NotSet self._login = github.GithubObject.NotSet self._name = github.GithubObject.NotSet + self._node_id = github.GithubObject.NotSet self._organizations_url = github.GithubObject.NotSet self._owned_private_repos = github.GithubObject.NotSet self._plan = github.GithubObject.NotSet @@ -1220,6 +1274,8 @@ def _useAttributes(self, attributes): self._login = self._makeStringAttribute(attributes["login"]) if "name" in attributes: # pragma no branch self._name = self._makeStringAttribute(attributes["name"]) + if "node_id" in attributes: # pragma no branch + self._node_id = self._makeStringAttribute(attributes["node_id"]) if "organizations_url" in attributes: # pragma no branch self._organizations_url = self._makeStringAttribute(attributes["organizations_url"]) if "owned_private_repos" in attributes: # pragma no branch diff --git a/ext3/github/Clones.py b/ext3/github/Clones.py new file mode 100644 index 0000000000..b8c1adc7c7 --- /dev/null +++ b/ext3/github/Clones.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +############################ Copyrights and license ############################ +# # +# Copyright 2018 Justin Kufro # +# Copyright 2018 Ivan Minno # +# Copyright 2018 Zilei Gu # +# Copyright 2018 Yves Zumbach # +# Copyright 2018 Leying Chen # +# # +# This file is part of PyGithub. # +# http://pygithub.readthedocs.io/ # +# # +# PyGithub is free software: you can redistribute it and/or modify it under # +# the terms of the GNU Lesser General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # +# details. # +# # +# You should have received a copy of the GNU Lesser General Public License # +# along with PyGithub. If not, see . # +# # +################################################################################ + +import github.GithubObject + + +class Clones(github.GithubObject.NonCompletableGithubObject): + """ + This class represents a popular Path for a GitHub repository. + The reference can be found here https://developer.github.com/v3/repos/traffic/ + """ + + def __repr__(self): + return self.get__repr__({ + "timestamp": self._timestamp.value, + "count": self._count.value, + "uniques": self._uniques.value + }) + + @property + def timestamp(self): + """ + :type: datetime.datetime + """ + return self._timestamp.value + + @property + def count(self): + """ + :type: integer + """ + return self._count.value + + @property + def uniques(self): + """ + :type: integer + """ + return self._uniques.value + + def _initAttributes(self): + self._timestamp = github.GithubObject.NotSet + self._count = github.GithubObject.NotSet + self._uniques = github.GithubObject.NotSet + + def _useAttributes(self, attributes): + if "timestamp" in attributes: # pragma no branch + self._timestamp = self._makeDatetimeAttribute(attributes["timestamp"]) + if "count" in attributes: # pragma no branch + self._count = self._makeIntAttribute(attributes["count"]) + if "uniques" in attributes: # pragma no branch + self._uniques = self._makeIntAttribute(attributes["uniques"]) diff --git a/ext3/github/Consts.py b/ext3/github/Consts.py index c59f419793..93fcd5b5f0 100644 --- a/ext3/github/Consts.py +++ b/ext3/github/Consts.py @@ -48,6 +48,7 @@ headerRateLimit = "x-ratelimit-limit" headerRateRemaining = "x-ratelimit-remaining" headerRateReset = "x-ratelimit-reset" +headerOAuthScopes = "x-oauth-scopes" headerOTP = "X-GitHub-OTP" defaultMediaType = "application/octet-stream" @@ -90,6 +91,9 @@ # https://developer.github.com/changes/2018-03-16-protected-branches-required-approving-reviews/ mediaTypeRequireMultipleApprovingReviews = "application/vnd.github.luke-cage-preview+json" +# https://developer.github.com/changes/2018-05-24-user-migration-api/ +mediaTypeMigrationPreview = "application/vnd.github.wyandotte-preview+json" + # https://developer.github.com/v3/search/#highlighting-code-search-results-1 highLightSearchPreview = "application/vnd.github.v3.text-match+json" diff --git a/ext3/github/GitRelease.py b/ext3/github/GitRelease.py index 53616c4821..6c7a8bcdbf 100644 --- a/ext3/github/GitRelease.py +++ b/ext3/github/GitRelease.py @@ -37,7 +37,7 @@ from os.path import basename import github.GithubObject -import github.GitAuthor +import github.NamedUser import github.GitReleaseAsset @@ -108,7 +108,7 @@ def prerelease(self): @property def author(self): """ - :type: :class:`github.GitAuthor.GitAuthor` + :type: :class:`github.NamedUser.NamedUser` """ self._completeIfNotSet(self._author) return self._author.value @@ -285,7 +285,7 @@ def _useAttributes(self, attributes): if "prerelease" in attributes: self._prerelease = self._makeBoolAttribute(attributes["prerelease"]) if "author" in attributes: - self._author = self._makeClassAttribute(github.GitAuthor.GitAuthor, attributes["author"]) + self._author = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["author"]) if "url" in attributes: self._url = self._makeStringAttribute(attributes["url"]) if "upload_url" in attributes: diff --git a/ext3/github/GithubObject.py b/ext3/github/GithubObject.py index 16e903b168..1a9f9da3b8 100644 --- a/ext3/github/GithubObject.py +++ b/ext3/github/GithubObject.py @@ -170,7 +170,7 @@ def parseDatetime(s): # The Downloads API has been removed. I'm keeping this branch because I have no mean # to check if it's really useless now. return datetime.datetime.strptime(s, "%Y-%m-%dT%H:%M:%S.000Z") # pragma no cover (This branch was used only when creating a download) - elif len(s) == 25: + elif len(s) >= 25: return datetime.datetime.strptime(s[:19], "%Y-%m-%dT%H:%M:%S") + (1 if s[19] == '-' else -1) * datetime.timedelta(hours=int(s[20:22]), minutes=int(s[23:25])) else: return datetime.datetime.strptime(s, "%Y-%m-%dT%H:%M:%SZ") diff --git a/ext3/github/MainClass.py b/ext3/github/MainClass.py index ad8d58773d..7ccee886f1 100644 --- a/ext3/github/MainClass.py +++ b/ext3/github/MainClass.py @@ -53,7 +53,7 @@ import pickle import time import sys -from http.client import HTTPSConnection +import requests import jwt from .Requester import Requester, json @@ -66,6 +66,7 @@ from . import Installation from . import Legacy from . import License +from . import Topic import github.GithubObject from . import HookDescription from . import GitignoreTemplate @@ -542,7 +543,7 @@ def search_topics(self, query, **qualifiers): :calls: `GET /search/topics `_ :param query: string :param qualifiers: keyword dict query qualifiers - :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Repository.Repository` + :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Topic.Topic` """ assert isinstance(query, str), query url_parameters = dict() @@ -558,7 +559,7 @@ def search_topics(self, query, **qualifiers): assert url_parameters["q"], "need at least one qualifier" return github.PaginatedList.PaginatedList( - github.Repository.Repository, + github.Topic.Topic, self.__requester, "/search/topics", url_parameters, @@ -771,28 +772,24 @@ def get_access_token(self, installation_id, user_id=None): :param installation_id: int :return: :class:`github.InstallationAuthorization.InstallationAuthorization` """ - body = None + body = {} if user_id: - body = json.dumps({"user_id": user_id}) - conn = HTTPSConnection("api.github.com") - conn.request( - method="POST", - url="/installations/{}/access_tokens".format(installation_id), + body = {"user_id": user_id} + response = requests.post( + "https://api.github.com/installations/{}/access_tokens".format(installation_id), headers={ "Authorization": "Bearer {}".format(self.create_jwt()), "Accept": Consts.mediaTypeIntegrationPreview, "User-Agent": "PyGithub/Python" }, - body=body + json=body ) - response = conn.getresponse() - response_text = response.read() + response_text = response.text if atLeastPython3: response_text = response_text.decode('utf-8') - conn.close() - if response.status == 201: + if response.status_code == 201: data = json.loads(response_text) return InstallationAuthorization.InstallationAuthorization( requester=None, # not required, this is a NonCompletableGithubObject @@ -800,17 +797,17 @@ def get_access_token(self, installation_id, user_id=None): attributes=data, completed=True ) - elif response.status == 403: + elif response.status_code == 403: raise GithubException.BadCredentialsException( - status=response.status, + status=response.status_code, data=response_text ) - elif response.status == 404: + elif response.status_code == 404: raise GithubException.UnknownObjectException( - status=response.status, + status=response.status_code, data=response_text ) raise GithubException.GithubException( - status=response.status, + status=response.status_code, data=response_text ) diff --git a/ext3/github/Migration.py b/ext3/github/Migration.py new file mode 100644 index 0000000000..8e00aed9b5 --- /dev/null +++ b/ext3/github/Migration.py @@ -0,0 +1,219 @@ +# -*- coding: utf-8 -*- + +############################ Copyrights and license ############################ +# # +# Copyright 2012 Vincent Jacques # +# Copyright 2012 Zearin # +# Copyright 2013 AKFish # +# Copyright 2013 Vincent Jacques # +# Copyright 2013 martinqt # +# Copyright 2014 Andy Casey # +# Copyright 2014 Vincent Jacques # +# Copyright 2016 Jannis Gebauer # +# Copyright 2016 John Eskew # +# Copyright 2016 Peter Buckley # +# Copyright 2018 sfdye # +# # +# This file is part of PyGithub. # +# http://pygithub.readthedocs.io/ # +# # +# PyGithub is free software: you can redistribute it and/or modify it under # +# the terms of the GNU Lesser General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # +# details. # +# # +# You should have received a copy of the GNU Lesser General Public License # +# along with PyGithub. If not, see . # +# # +################################################################################ + +import github.GithubObject +import github.PaginatedList + +import github.NamedUser + +from . import Consts + +class Migration(github.GithubObject.CompletableGithubObject): + """ + This class represents Migrations. The reference can be found here http://developer.github.com/v3/migrations/ + """ + + def __repr__(self): + return self.get__repr__({"state": self._state.value, "url": self._url.value}) + + @property + def id(self): + """ + :type: int + """ + return self._id.value + + @property + def owner(self): + """ + :type: :class:`github.NamedUser.NamedUser` + """ + self._completeIfNotSet(self._owner) + return self._owner.value + + @property + def guid(self): + """ + :type: str + """ + self._completeIfNotSet(self._guid) + return self._guid.value + + @property + def state(self): + """ + :type: str + """ + self._completeIfNotSet(self._guid) + return self._state.value + + @property + def lock_repositories(self): + """ + :type: bool + """ + self._completeIfNotSet(self._repositories) + return self._lock_repositories.value + + @property + def exclude_attachments(self): + """ + :type: bool + """ + self._completeIfNotSet(self._exclude_attachments) + return self._exclude_attachments.value + + @property + def repositories(self): + """ + :type: :class:`github.PaginatedList.PaginatedList` of :class:`github.Repository.Repository` + """ + self._completeIfNotSet(self._repositories) + return self._repositories.value + + @property + def url(self): + """ + :type: str + """ + self._completeIfNotSet(self._url) + return self._url.value + + @property + def created_at(self): + """ + :type: datetime.datetime + :rtype: None + """ + self._completeIfNotSet(self._created_at) + return self._created_at.value + + @property + def updated_at(self): + """ + :type: datetime.datetime + :rtype: None + """ + self._completeIfNotSet(self._updated_at) + return self._updated_at.value + + def get_status(self): + """ + :calls: `GET /user/migrations/:migration_id`_ + :rtype: str + """ + headers, data = self._requester.requestJsonAndCheck( + "GET", + self.url, + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + self._useAttributes(data) + return self.state + + def get_archive_url(self): + """ + :calls: `GET /user/migrations/:migration_id/archive`_ + :rtype: str + """ + headers, data = self._requester.requestJsonAndCheck( + "GET", + self.url + "/archive", + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + return data["data"] + + def delete(self): + """ + :calls: `DELETE /user/migrations/:migration_id/archive`_ + """ + headers, data = self._requester.requestJsonAndCheck( + "DELETE", + self.url + "/archive", + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + + def unlock_repo(self, repo_name): + """ + :calls: `DELETE /user/migrations/:migration_id/repos/:repo_name/lock`_ + :param repo_name: str + :rtype: None + """ + assert isinstance(repo_name, str), repo_name + headers, data = self._requester.requestJsonAndCheck( + "DELETE", + self.url + "/repos/" + repo_name + "/lock", + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + + def _initAttributes(self): + self._id = github.GithubObject.NotSet + self._owner = github.GithubObject.NotSet + self._guid = github.GithubObject.NotSet + self._state = github.GithubObject.NotSet + self._lock_repositories = github.GithubObject.NotSet + self._exclude_attachments = github.GithubObject.NotSet + self._repositories = github.GithubObject.NotSet + self._url = github.GithubObject.NotSet + self._created_at = github.GithubObject.NotSet + self._updated_at = github.GithubObject.NotSet + + def _useAttributes(self, attributes): + if "id" in attributes: + self._id = self._makeIntAttribute(attributes["id"]) + if "owner" in attributes: + self._owner = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["owner"]) + if "guid" in attributes: + self._guid = self._makeStringAttribute(attributes["guid"]) + if "state" in attributes: + self._state = self._makeStringAttribute(attributes["state"]) + if "lock_repositories" in attributes: + self._lock_repositories = self._makeBoolAttribute(attributes["lock_repositories"]) + if "exclude_attachments" in attributes: + self._exclude_attachments = self._makeBoolAttribute(attributes["exclude_attachments"]) + if "repositories" in attributes: + self._repositories = self._makeListOfClassesAttribute(github.Repository.Repository, attributes["repositories"]) + if "url" in attributes: + self._url = self._makeStringAttribute(attributes["url"]) + if "created_at" in attributes: + self._created_at = self._makeDatetimeAttribute(attributes["created_at"]) + if "updated_at" in attributes: + self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"]) diff --git a/ext3/github/NamedUser.py b/ext3/github/NamedUser.py index fe1909285b..237eba0038 100644 --- a/ext3/github/NamedUser.py +++ b/ext3/github/NamedUser.py @@ -59,6 +59,14 @@ class NamedUser(github.GithubObject.CompletableGithubObject): def __repr__(self): return self.get__repr__({"login": self._login.value}) + @property + def node_id(self): + """ + :type: string + """ + self._completeIfNotSet(self._node_id) + return self._node_id.value + def __hash__(self): return hash((self.id, self.login)) @@ -605,6 +613,7 @@ def _initAttributes(self): self._location = github.GithubObject.NotSet self._login = github.GithubObject.NotSet self._name = github.GithubObject.NotSet + self._node_id = github.GithubObject.NotSet self._organizations_url = github.GithubObject.NotSet self._owned_private_repos = github.GithubObject.NotSet self._permissions = github.GithubObject.NotSet @@ -668,6 +677,8 @@ def _useAttributes(self, attributes): self._login = self._makeStringAttribute(attributes["login"]) if "name" in attributes: # pragma no branch self._name = self._makeStringAttribute(attributes["name"]) + if "node_id" in attributes: # pragma no branch + self._node_id = self._makeStringAttribute(attributes["node_id"]) if "organizations_url" in attributes: # pragma no branch self._organizations_url = self._makeStringAttribute(attributes["organizations_url"]) if "owned_private_repos" in attributes: # pragma no branch diff --git a/ext3/github/Organization.py b/ext3/github/Organization.py index a9b377a025..8486e3d120 100644 --- a/ext3/github/Organization.py +++ b/ext3/github/Organization.py @@ -896,6 +896,50 @@ def remove_from_public_members(self, public_member): self.url + "/public_members/" + public_member._identity ) + def create_migration(self, repos, lock_repositories=github.GithubObject.NotSet, exclude_attachments=github.GithubObject.NotSet): + """ + :calls: `POST /orgs/:org/migrations`_ + :param repos: list or tuple of str + :param lock_repositories: bool + :param exclude_attachments: bool + :rtype: :class:`github.Migration.Migration` + """ + assert isinstance(repos, (list, tuple)), repos + assert all(isinstance(repo, str) for repo in repos), repos + assert lock_repositories is github.GithubObject.NotSet or isinstance(lock_repositories, bool), lock_repositories + assert exclude_attachments is github.GithubObject.NotSet or isinstance(exclude_attachments, bool), exclude_attachments + post_parameters = { + "repositories": repos + } + if lock_repositories is not github.GithubObject.NotSet: + post_parameters["lock_repositories"] = lock_repositories + if exclude_attachments is not github.GithubObject.NotSet: + post_parameters["exclude_attachments"] = exclude_attachments + headers, data = self._requester.requestJsonAndCheck( + "POST", + "/orgs/" + self.login + "/migrations", + input=post_parameters, + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + return github.Migration.Migration(self._requester, headers, data, completed=True) + + def get_migrations(self): + """ + :calls: `GET /orgs/:org/migrations`_ + :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Migration.Migration` + """ + return github.PaginatedList.PaginatedList( + github.Migration.Migration, + self._requester, + "/orgs/" + self.login + "/migrations", + None, + headers={ + "Accept": Consts.mediaTypeMigrationPreview + } + ) + def _initAttributes(self): self._avatar_url = github.GithubObject.NotSet self._billing_email = github.GithubObject.NotSet diff --git a/ext3/github/PaginatedList.py b/ext3/github/PaginatedList.py index 8817bd5333..353e22a5d1 100644 --- a/ext3/github/PaginatedList.py +++ b/ext3/github/PaginatedList.py @@ -155,7 +155,12 @@ def totalCount(self): headers=self.__headers ) if 'link' not in headers: - self.__totalCount = len(data) if data else 0 + if data and "total_count" in data: + self.__totalCount = data["total_count"] + elif data: + self.__totalCount = len(data) + else: + self.__totalCount = 0 else: links = self.__parseLinkHeader(headers) lastUrl = links.get("last") diff --git a/ext3/github/Path.py b/ext3/github/Path.py new file mode 100644 index 0000000000..615c0da1b8 --- /dev/null +++ b/ext3/github/Path.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- + +############################ Copyrights and license ############################ +# # +# Copyright 2018 Justin Kufro # +# Copyright 2018 Ivan Minno # +# Copyright 2018 Zilei Gu # +# Copyright 2018 Yves Zumbach # +# Copyright 2018 Leying Chen # +# # +# This file is part of PyGithub. # +# http://pygithub.readthedocs.io/ # +# # +# PyGithub is free software: you can redistribute it and/or modify it under # +# the terms of the GNU Lesser General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # +# details. # +# # +# You should have received a copy of the GNU Lesser General Public License # +# along with PyGithub. If not, see . # +# # +################################################################################ + +import github.GithubObject + + +class Path(github.GithubObject.NonCompletableGithubObject): + """ + This class represents a popular Path for a GitHub repository. + The reference can be found here https://developer.github.com/v3/repos/traffic/ + """ + + def __repr__(self): + return self.get__repr__({ + "path": self._path.value, + "title": self._title.value, + "count": self._count.value, + "uniques": self._uniques.value + }) + + @property + def path(self): + """ + :type: string + """ + return self._path.value + + @property + def title(self): + """ + :type: string + """ + return self._title.value + + @property + def count(self): + """ + :type: integer + """ + return self._count.value + + @property + def uniques(self): + """ + :type: integer + """ + return self._uniques.value + + def _initAttributes(self): + self._path = github.GithubObject.NotSet + self._title = github.GithubObject.NotSet + self._count = github.GithubObject.NotSet + self._uniques = github.GithubObject.NotSet + + def _useAttributes(self, attributes): + if "path" in attributes: # pragma no branch + self._path = self._makeStringAttribute(attributes["path"]) + if "title" in attributes: # pragma no branch + self._title = self._makeStringAttribute(attributes["title"]) + if "count" in attributes: # pragma no branch + self._count = self._makeIntAttribute(attributes["count"]) + if "uniques" in attributes: # pragma no branch + self._uniques = self._makeIntAttribute(attributes["uniques"]) diff --git a/ext3/github/Project.py b/ext3/github/Project.py index 2ae577e572..496c817661 100644 --- a/ext3/github/Project.py +++ b/ext3/github/Project.py @@ -30,6 +30,7 @@ from . import Consts + class Project(github.GithubObject.CompletableGithubObject): """ This class represents Projects. The reference can be found here http://developer.github.com/v3/projects @@ -156,6 +157,22 @@ def get_columns(self): {"Accept": Consts.mediaTypeProjectsPreview} ) + def create_column(self, name): + """ + calls: `POST https://developer.github.com/v3/projects/columns/#create-a-project-column>`_ + :param name: string + """ + assert isinstance(name, str), name + post_parameters = {"name": name} + import_header = {"Accept": Consts.mediaTypeProjectsPreview} + headers, data = self._requester.requestJsonAndCheck( + "POST", + self.url + "/columns", + headers=import_header, + input=post_parameters + ) + return github.ProjectColumn.ProjectColumn(self._requester, headers, data, completed=True) + def _initAttributes(self): self._body = github.GithubObject.NotSet self._columns_url = github.GithubObject.NotSet diff --git a/ext3/github/ProjectColumn.py b/ext3/github/ProjectColumn.py index 51fdb6fd07..80ce18cfe3 100644 --- a/ext3/github/ProjectColumn.py +++ b/ext3/github/ProjectColumn.py @@ -30,6 +30,7 @@ from . import Consts + class ProjectColumn(github.GithubObject.CompletableGithubObject): """ This class represents Project Columns. The reference can be found here http://developer.github.com/v3/projects/columns @@ -94,7 +95,7 @@ def url(self): """ return self._url.value - def get_cards(self,archived_state=github.GithubObject.NotSet): + def get_cards(self, archived_state=github.GithubObject.NotSet): """ :calls: `GET /projects/columns/:column_id/cards `_ :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.ProjectCard.ProjectCard` @@ -114,6 +115,37 @@ def get_cards(self,archived_state=github.GithubObject.NotSet): {"Accept": Consts.mediaTypeProjectsPreview} ) + def create_card(self, note=github.GithubObject.NotSet, + content_id=github.GithubObject.NotSet, + content_type=github.GithubObject.NotSet): + """ + calls: `POST https://developer.github.com/v3/projects/cards/#create-a-project-card>`_ + :param note: string + :param content_id: integer + :param content_type: string + """ + post_parameters = {} + if isinstance(note, str): + assert content_id is github.GithubObject.NotSet, content_id + assert content_type is github.GithubObject.NotSet, content_type + post_parameters = {"note": note} + else: + assert note is github.GithubObject.NotSet, note + assert isinstance(content_id, int), content_id + assert isinstance(content_type, str), content_type + post_parameters = {"content_id": content_id, + "content_type": content_type} + + import_header = {"Accept": Consts.mediaTypeProjectsPreview} + headers, data = self._requester.requestJsonAndCheck( + "POST", + self.url + "/cards", + headers=import_header, + input=post_parameters + ) + return github.ProjectCard.ProjectCard(self._requester, headers, + data, completed=True) + def _initAttributes(self): self._cards_url = github.GithubObject.NotSet self._created_at = github.GithubObject.NotSet diff --git a/ext3/github/PullRequest.py b/ext3/github/PullRequest.py index da58e632a3..682014523b 100644 --- a/ext3/github/PullRequest.py +++ b/ext3/github/PullRequest.py @@ -42,6 +42,7 @@ # # ################################################################################ +import datetime import urllib.request, urllib.parse, urllib.error import github.GithubObject import github.PaginatedList diff --git a/ext3/github/Referrer.py b/ext3/github/Referrer.py new file mode 100644 index 0000000000..eb14931b33 --- /dev/null +++ b/ext3/github/Referrer.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +############################ Copyrights and license ############################ +# # +# Copyright 2018 Justin Kufro # +# Copyright 2018 Ivan Minno # +# Copyright 2018 Zilei Gu # +# Copyright 2018 Yves Zumbach # +# Copyright 2018 Leying Chen # +# # +# This file is part of PyGithub. # +# http://pygithub.readthedocs.io/ # +# # +# PyGithub is free software: you can redistribute it and/or modify it under # +# the terms of the GNU Lesser General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # +# details. # +# # +# You should have received a copy of the GNU Lesser General Public License # +# along with PyGithub. If not, see . # +# # +################################################################################ + +import github.GithubObject + + +class Referrer(github.GithubObject.NonCompletableGithubObject): + """ + This class represents a popylar Referrer for a GitHub repository. + The reference can be found here https://developer.github.com/v3/repos/traffic/ + """ + + def __repr__(self): + return self.get__repr__({ + "referrer": self._referrer.value, + "count": self._count.value, + "uniques": self._uniques.value + }) + + @property + def referrer(self): + """ + :type: string + """ + return self._referrer.value + + @property + def count(self): + """ + :type: integer + """ + return self._count.value + + @property + def uniques(self): + """ + :type: integer + """ + return self._uniques.value + + def _initAttributes(self): + self._referrer = github.GithubObject.NotSet + self._count = github.GithubObject.NotSet + self._uniques = github.GithubObject.NotSet + + def _useAttributes(self, attributes): + if "referrer" in attributes: # pragma no branch + self._referrer = self._makeStringAttribute(attributes["referrer"]) + if "count" in attributes: # pragma no branch + self._count = self._makeIntAttribute(attributes["count"]) + if "uniques" in attributes: # pragma no branch + self._uniques = self._makeIntAttribute(attributes["uniques"]) diff --git a/ext3/github/Repository.py b/ext3/github/Repository.py index 623d941650..558416323c 100644 --- a/ext3/github/Repository.py +++ b/ext3/github/Repository.py @@ -60,7 +60,12 @@ # Copyright 2018 per1234 # # Copyright 2018 sechastain # # Copyright 2018 sfdye # -# Copyright 2018 Vinay Hegde +# Copyright 2018 Vinay Hegde # +# Copyright 2018 Justin Kufro # +# Copyright 2018 Ivan Minno # +# Copyright 2018 Zilei Gu # +# Copyright 2018 Yves Zumbach # +# Copyright 2018 Leying Chen # # # # This file is part of PyGithub. # # http://pygithub.readthedocs.io/ # @@ -124,6 +129,10 @@ import github.StatsParticipation import github.StatsPunchCard import github.Stargazer +import github.Referrer +import github.Path +import github.Clones +import github.View from . import Consts @@ -1132,6 +1141,29 @@ def create_milestone(self, title, state=github.GithubObject.NotSet, description= ) return github.Milestone.Milestone(self._requester, headers, data, completed=True) + def create_project(self, name, body=github.GithubObject.NotSet): + """ + calls: `POST /repos/:owner/:repo/projects `_ + :param name: string + :param body: string + """ + assert isinstance(name, str), name + assert body is github.GithubObject.NotSet or isinstance(body, str), body + post_parameters = { + "name": name, + "body": body, + } + import_header = {"Accept": Consts.mediaTypeProjectsPreview} + if body is not github.GithubObject.NotSet: + post_parameters['body'] = body + headers, data = self._requester.requestJsonAndCheck( + "POST", + self.url + "/projects", + headers=import_header, + input=post_parameters + ) + return github.Project.Project(self._requester, headers, data, completed=True) + def create_pull(self, *args, **kwds): """ :calls: `POST /repos/:owner/:repo/pulls `_ @@ -1470,17 +1502,91 @@ def get_file_contents(self, path, ref=github.GithubObject.NotSet): ] return github.ContentFile.ContentFile(self._requester, headers, data, completed=True) + def get_top_referrers(self): + """ + :calls: `GET /repos/:owner/:repo/traffic/popular/referrers `_ + :rtype: :class:`list` of :class:`github.Referrer.Referrer` + """ + headers, data = self._requester.requestJsonAndCheck( + "GET", + self.url + "/traffic/popular/referrers" + ) + if isinstance(data, list): + return [ + github.Referrer.Referrer(self._requester, headers, item, completed=True) + for item in data + ] + + def get_top_paths(self): + """ + :calls: `GET /repos/:owner/:repo/traffic/popular/paths `_ + :rtype: :class:`list` of :class:`github.Path.Path` + """ + headers, data = self._requester.requestJsonAndCheck( + "GET", + self.url + "/traffic/popular/paths" + ) + if isinstance(data, list): + return [ + github.Path.Path(self._requester, headers, item, completed=True) + for item in data + ] + + def get_views_traffic(self, per=github.GithubObject.NotSet): + """ + :calls: `GET /repos/:owner/:repo/traffic/views `_ + :param per: string, must be one of day or week, day by default + :rtype: None or list of :class:`github.View.View` + """ + assert per is github.GithubObject.NotSet or (isinstance(per, str) and (per == "day" or per == "week")), "per must be day or week, day by default" + url_parameters = dict() + if per is not github.GithubObject.NotSet: + url_parameters["per"] = per + headers, data = self._requester.requestJsonAndCheck( + "GET", + self.url + "/traffic/views", + parameters=url_parameters + ) + if (isinstance(data, dict)) and ("views" in data) and (isinstance(data["views"], list)): + data["views"] = [ + github.View.View(self._requester, headers, item, completed=True) + for item in data["views"] + ] + return data + + def get_clones_traffic(self, per=github.GithubObject.NotSet): + """ + :calls: `GET /repos/:owner/:repo/traffic/clones `_ + :param per: string, must be one of day or week, day by default + :rtype: None or list of :class:`github.Clone.Clone` + """ + assert per is github.GithubObject.NotSet or (isinstance(per, str) and (per == "day" or per == "week")), "per must be day or week, day by default" + url_parameters = dict() + if per is not github.GithubObject.NotSet: + url_parameters["per"] = per + headers, data = self._requester.requestJsonAndCheck( + "GET", + self.url + "/traffic/clones", + parameters=url_parameters + ) + if (isinstance(data, dict)) and ("clones" in data) and (isinstance(data["clones"], list)): + data["clones"] = [ + github.Clones.Clones(self._requester, headers, item, completed=True) + for item in data["clones"] + ] + return data + def get_projects(self, state=github.GithubObject.NotSet): """ :calls: `GET /repos/:owner/:repo/projects `_ :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Project.Project` :param state: string """ - + url_parameters = dict() if state is not github.GithubObject.NotSet: url_parameters["state"] = state - + return github.PaginatedList.PaginatedList( github.Project.Project, self._requester, @@ -1883,7 +1989,7 @@ def get_issues(self, milestone=github.GithubObject.NotSet, state=github.GithubOb """ :calls: `GET /repos/:owner/:repo/issues `_ :param milestone: :class:`github.Milestone.Milestone` or "none" or "*" - :param state: string + :param state: string. `open`, `closed`, or `all`. If this is not set the GitHub API default behavior will be used. At the moment this is to return only open issues. This might change anytime on GitHub API side and it could be clever to explicitly specify the state value. :param assignee: string or :class:`github.NamedUser.NamedUser` or "none" or "*" :param mentioned: :class:`github.NamedUser.NamedUser` :param labels: list of :class:`github.Label.Label` @@ -2839,7 +2945,7 @@ def _useAttributes(self, attributes): self._teams_url = self._makeStringAttribute(attributes["teams_url"]) if "trees_url" in attributes: # pragma no branch self._trees_url = self._makeStringAttribute(attributes["trees_url"]) - if "topics" in attributes: # pragma no branch + if "topics" in attributes: # pragma no branch self._topics = self._makeListOfStringsAttribute(attributes["topics"]) if "updated_at" in attributes: # pragma no branch self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"]) diff --git a/ext3/github/Requester.py b/ext3/github/Requester.py index 59c4912f36..2282a73e61 100644 --- a/ext3/github/Requester.py +++ b/ext3/github/Requester.py @@ -381,8 +381,8 @@ def __requestEncode(self, cnx, verb, url, parameters, requestHeaders, input, enc if Consts.headerRateReset in responseHeaders: self.rate_limiting_resettime = int(responseHeaders[Consts.headerRateReset]) - if "x-oauth-scopes" in responseHeaders: - self.oauth_scopes = responseHeaders["x-oauth-scopes"].split(", ") + if Consts.headerOAuthScopes in responseHeaders: + self.oauth_scopes = responseHeaders[Consts.headerOAuthScopes].split(", ") self.DEBUG_ON_RESPONSE(status, responseHeaders, output) diff --git a/ext3/github/Topic.py b/ext3/github/Topic.py new file mode 100644 index 0000000000..c347c2c280 --- /dev/null +++ b/ext3/github/Topic.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- + +############################ Copyrights and license ############################ +# # +# Copyright 2018 Steve Kowalik # +# # +# This file is part of PyGithub. # +# http://pygithub.readthedocs.io/ # +# # +# PyGithub is free software: you can redistribute it and/or modify it under # +# the terms of the GNU Lesser General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # +# details. # +# # +# You should have received a copy of the GNU Lesser General Public License # +# along with PyGithub. If not, see . # +# # +################################################################################ + +import github.GithubObject + + +class Topic(github.GithubObject.CompletableGithubObject): + """ + This class represents topics as used by https://github.com/topics. The object refereence can be found here https://developer.github.com/v3/search/#search-topics + """ + + def __repr__(self): + return self.get__repr__({"name": self._name.value}) + + @property + def name(self): + """ + :type: string + """ + self._completeIfNotSet(self._name) + return self._name.value + + @property + def display_name(self): + """ + :type: string + """ + self._completeIfNotSet(self._display_name) + return self._display_name.value + + @property + def short_description(self): + """ + :type: string + """ + self._completeIfNotSet(self._short_description) + return self._short_description.value + + @property + def description(self): + """ + :type: string + """ + self._completeIfNotSet(self._description) + return self._description.value + + def _initAttributes(self): + self._name = github.GithubObject.NotSet + self._display_name = github.GithubObject.NotSet + self._short_description = github.GithubObject.NotSet + self._description = github.GithubObject.NotSet + + def _useAttributes(self, attributes): + if "name" in attributes: # pragma no branch + self._name = self._makeStringAttribute(attributes["name"]) + if "display_name" in attributes: # pragma no branch + self._display_name = self._makeStringAttribute(attributes["display_name"]) + if "short_description" in attributes: # pragma no branch + self._short_description = self._makeStringAttribute(attributes["short_description"]) + if "description" in attributes: # pragma no branch + self._description = self._makeStringAttribute(attributes["description"]) diff --git a/ext3/github/View.py b/ext3/github/View.py new file mode 100644 index 0000000000..ed0bce5d06 --- /dev/null +++ b/ext3/github/View.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +############################ Copyrights and license ############################ +# # +# Copyright 2018 Justin Kufro # +# Copyright 2018 Ivan Minno # +# Copyright 2018 Zilei Gu # +# Copyright 2018 Yves Zumbach # +# Copyright 2018 Leying Chen # +# # +# This file is part of PyGithub. # +# http://pygithub.readthedocs.io/ # +# # +# PyGithub is free software: you can redistribute it and/or modify it under # +# the terms of the GNU Lesser General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # +# details. # +# # +# You should have received a copy of the GNU Lesser General Public License # +# along with PyGithub. If not, see . # +# # +################################################################################ + +import github.GithubObject + + +class View(github.GithubObject.NonCompletableGithubObject): + """ + This class represents a popular Path for a GitHub repository. + The reference can be found here https://developer.github.com/v3/repos/traffic/ + """ + + def __repr__(self): + return self.get__repr__({ + "timestamp": self._timestamp.value, + "count": self._count.value, + "uniques": self._uniques.value + }) + + @property + def timestamp(self): + """ + :type: datetime.datetime + """ + return self._timestamp.value + + @property + def count(self): + """ + :type: integer + """ + return self._count.value + + @property + def uniques(self): + """ + :type: integer + """ + return self._uniques.value + + def _initAttributes(self): + self._timestamp = github.GithubObject.NotSet + self._count = github.GithubObject.NotSet + self._uniques = github.GithubObject.NotSet + + def _useAttributes(self, attributes): + if "timestamp" in attributes: # pragma no branch + self._timestamp = self._makeDatetimeAttribute(attributes["timestamp"]) + if "count" in attributes: # pragma no branch + self._count = self._makeIntAttribute(attributes["count"]) + if "uniques" in attributes: # pragma no branch + self._uniques = self._makeIntAttribute(attributes["uniques"]) diff --git a/lib/readme.md b/lib/readme.md index e1a8613817..b22f84e2f5 100644 --- a/lib/readme.md +++ b/lib/readme.md @@ -11,7 +11,6 @@ :: | `send2trash` | [1.3.0](https://pypi.org/project/send2trash/1.3.0/) | **`medusa`** | lib | **Modified** :: | `shutil_custom` | - | **`medusa`** | lib | **Custom** :: | `simpleanidb` | pymedusa/[5d26c8c](https://github.com/pymedusa/simpleanidb/tree/5d26c8c146891225c05651821ef34ced0c118221) | **`medusa`** | lib | - -:: | `synchronousdeluge` | ????? | **`medusa`** | lib | From CouchPotato? :: | `tmdbsimple` | [2.2.0](https://pypi.org/project/tmdbsimple/2.2.0/) | **`medusa`** | lib | **Modified**: [#4026](https://github.com/pymedusa/Medusa/pull/4026) -- [Upstream PR](https://github.com/celiao/tmdbsimple/pull/52) :: | `traktor` | - | **`medusa`** | lib | **Custom** :: | `tvdbapiv2` | pymedusa/[3a51858](https://github.com/pymedusa/tvdbv2/tree/3a51858640cfcb960be635e91394cbce1d73e036) | **`medusa`** | lib | **Modified**: [Upstream PR](https://github.com/pymedusa/tvdbv2/pull/2) diff --git a/lib/rtorrent/__init__.py b/lib/rtorrent/__init__.py index 13e52db604..10790f0940 100644 --- a/lib/rtorrent/__init__.py +++ b/lib/rtorrent/__init__.py @@ -20,8 +20,13 @@ import os.path import time -import urllib -import xmlrpclib + +try: + import xmlrpc.client as xmlrpc_client + from urllib.parse import urlparse +except ImportError: + import xmlrpclib as xmlrpc_client + from urlparse import urlparse import rtorrent.rpc from rtorrent import common @@ -42,7 +47,7 @@ MIN_RTORRENT_VERSION_STR = common.convert_version_tuple_to_str(MIN_RTORRENT_VERSION) -class RTorrent: +class RTorrent(object): """Create a new rTorrent connection.""" rpc_prefix = None @@ -54,7 +59,7 @@ def __init__(self, uri, username=None, password=None, self.username = username self.password = password - self.schema = urllib.splittype(uri)[0] + self.schema = urlparse(uri).scheme if sp: self.sp = sp @@ -182,7 +187,7 @@ def get_torrents(self, view='main'): results_dict = {} # build results_dict # result[0] is the info_hash - for m, r in zip(retriever_methods, result[1:]): + for m, r in list(zip(retriever_methods, result[1:])): results_dict[m.varname] = rtorrent.rpc.process_result(m, r) self.torrents.append( @@ -299,7 +304,7 @@ def load_torrent(self, torrent, **kwargs): p = self._get_conn() tp = TorrentParser(torrent) - torrent = xmlrpclib.Binary(tp._raw_torrent) + torrent = xmlrpc_client.Binary(tp._raw_torrent) info_hash = tp.info_hash func_name = self._get_load_function('raw', start, verbose) @@ -366,7 +371,7 @@ def load_torrent_simple(self, torrent, file_type, **kwargs): torrent = open(torrent, 'rb').read() if file_type in ['raw', 'file']: - finput = xmlrpclib.Binary(torrent) + finput = xmlrpc_client.Binary(torrent) elif file_type == 'url': finput = torrent @@ -663,6 +668,6 @@ def __check_supported_methods(rt): rtorrent.tracker.Tracker: rtorrent.tracker.methods, rtorrent.peer.Peer: rtorrent.peer.methods, } -for c in class_methods_pair.keys(): +for c in class_methods_pair: rtorrent.rpc._build_rpc_methods(c, class_methods_pair[c]) _build_class_methods(c) diff --git a/lib/rtorrent/compat.py b/lib/rtorrent/compat.py index cbe18bd785..ccdf01d3ac 100644 --- a/lib/rtorrent/compat.py +++ b/lib/rtorrent/compat.py @@ -23,9 +23,3 @@ def is_py3(): return sys.version_info[0] == 3 - - -if is_py3(): - import xmlrpc.client as xmlrpclib -else: - import xmlrpclib diff --git a/lib/rtorrent/file.py b/lib/rtorrent/file.py index deb22cde2c..44bb5240de 100644 --- a/lib/rtorrent/file.py +++ b/lib/rtorrent/file.py @@ -25,14 +25,14 @@ Method = rtorrent.rpc.Method -class File: +class File(object): """Represents an individual file within a L{Torrent} instance.""" def __init__(self, _rt_obj, info_hash, index, **kwargs): self._rt_obj = _rt_obj self.info_hash = info_hash # : info hash for the torrent the file is associated with self.index = index # : The position of the file within the file list - for k in kwargs.keys(): + for k in kwargs: setattr(self, k, kwargs.get(k, None)) self.rpc_id = '{0}:f{1}'.format( diff --git a/lib/rtorrent/group.py b/lib/rtorrent/group.py index d62b1a10f5..55e9abe8ab 100644 --- a/lib/rtorrent/group.py +++ b/lib/rtorrent/group.py @@ -23,7 +23,7 @@ Method = rtorrent.rpc.Method -class Group: +class Group(object): __name__ = 'Group' def __init__(self, _rt_obj, name): diff --git a/lib/rtorrent/lib/torrentparser.py b/lib/rtorrent/lib/torrentparser.py index f65caa9cf8..18a25aae31 100644 --- a/lib/rtorrent/lib/torrentparser.py +++ b/lib/rtorrent/lib/torrentparser.py @@ -23,15 +23,14 @@ import re import rtorrent.lib.bencode as bencode -from rtorrent.compat import is_py3 -if is_py3(): - from urllib.request import urlopen # @UnresolvedImport @UnusedImport -else: - from urllib2 import urlopen # @UnresolvedImport @Reimport +try: + from urllib.request import urlopen +except ImportError: + from urllib2 import urlopen -class TorrentParser(): +class TorrentParser(object): def __init__(self, torrent): """Decode and parse given torrent. @@ -78,7 +77,7 @@ def _get_raw_torrent(self): self.file_type = "file" self._raw_torrent = open(self.torrent, "rb").read() # url? - elif re.search("^(http|ftp):\/\/", self.torrent, re.I): + elif re.search(r"^(http|ftp):\/\/", self.torrent, re.I): self.file_type = "url" self._raw_torrent = urlopen(self.torrent).read() @@ -90,7 +89,7 @@ def _decode_torrent(self, raw_torrent=None): def _calc_info_hash(self): self.info_hash = None - if "info" in self._torrent_decoded.keys(): + if "info" in self._torrent_decoded: info_encoded = bencode.encode(self._torrent_decoded["info"]) if info_encoded: diff --git a/lib/rtorrent/lib/xmlrpc/basic_auth.py b/lib/rtorrent/lib/xmlrpc/basic_auth.py index 20c02d9a45..de5cffd728 100644 --- a/lib/rtorrent/lib/xmlrpc/basic_auth.py +++ b/lib/rtorrent/lib/xmlrpc/basic_auth.py @@ -22,12 +22,16 @@ from base64 import encodestring import string -import xmlrpclib +try: + import xmlrpc.client as xmlrpc_client +except ImportError: + import xmlrpclib as xmlrpc_client -class BasicAuthTransport(xmlrpclib.Transport): + +class BasicAuthTransport(xmlrpc_client.Transport): def __init__(self, username=None, password=None): - xmlrpclib.Transport.__init__(self) + xmlrpc_client.Transport.__init__(self) self.username = username self.password = password @@ -57,7 +61,7 @@ def single_request(self, host, handler, request_body, verbose=0): if response.status == 200: self.verbose = verbose return self.parse_response(response) - except xmlrpclib.Fault: + except xmlrpc_client.Fault: raise except Exception: self.close() @@ -66,7 +70,7 @@ def single_request(self, host, handler, request_body, verbose=0): #discard any response data and raise exception if response.getheader("content-length", 0): response.read() - raise xmlrpclib.ProtocolError( + raise xmlrpc_client.ProtocolError( host + handler, response.status, response.reason, response.msg, diff --git a/lib/rtorrent/lib/xmlrpc/http.py b/lib/rtorrent/lib/xmlrpc/http.py index 3eb8521041..353bbed3cd 100644 --- a/lib/rtorrent/lib/xmlrpc/http.py +++ b/lib/rtorrent/lib/xmlrpc/http.py @@ -18,6 +18,9 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -from rtorrent.compat import xmlrpclib +try: + import xmlrpc.client as xmlrpc_client +except ImportError: + import xmlrpclib as xmlrpc_client -HTTPServerProxy = xmlrpclib.ServerProxy +HTTPServerProxy = xmlrpc_client.ServerProxy diff --git a/lib/rtorrent/lib/xmlrpc/requests_transport.py b/lib/rtorrent/lib/xmlrpc/requests_transport.py index 326b38a1c8..2ab628f2e7 100644 --- a/lib/rtorrent/lib/xmlrpc/requests_transport.py +++ b/lib/rtorrent/lib/xmlrpc/requests_transport.py @@ -19,7 +19,6 @@ -SSL with Basic and Digest authentication -Proxies """ - try: import xmlrpc.client as xmlrpc_client except ImportError: diff --git a/lib/rtorrent/lib/xmlrpc/scgi.py b/lib/rtorrent/lib/xmlrpc/scgi.py index 5ba61fa5c9..6be5404574 100644 --- a/lib/rtorrent/lib/xmlrpc/scgi.py +++ b/lib/rtorrent/lib/xmlrpc/scgi.py @@ -28,12 +28,12 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -81,51 +81,73 @@ # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE # OF THIS SOFTWARE. -import httplib +try: + import xmlrpc.client as xmlrpc_client + import http.client as http_client + from urllib.parse import urlparse +except ImportError: + import xmlrpclib as xmlrpc_client + import httplib as http_client + from urlparse import urlparse + import re import socket -import urllib -import xmlrpclib import errno -class SCGITransport(xmlrpclib.Transport): +class SCGITransport(xmlrpc_client.Transport): # Added request() from Python 2.7 xmlrpclib here to backport to Python 2.6 def request(self, host, handler, request_body, verbose=0): - #retry request once if cached connection has gone cold + # retry request once if cached connection has gone cold for i in (0, 1): try: return self.single_request(host, handler, request_body, verbose) - except socket.error, e: + except socket.error as e: if i or e.errno not in (errno.ECONNRESET, errno.ECONNABORTED, errno.EPIPE): raise - except httplib.BadStatusLine: #close after we sent request + except http_client.BadStatusLine: # close after we sent request if i: raise + @staticmethod + def encode_netstring(input): + return str(len(input)).encode() + b':' + input + b',' + + @staticmethod + def encode_header(key, value): + return key + b'\x00' + value + b'\x00' + def single_request(self, host, handler, request_body, verbose=0): + """ + Parts of this file are public domain SCGITransport implementation from: + https://github.com/JohnDoee/autotorrent/blob/develop/autotorrent/scgitransport.py + """ # Add SCGI headers to the request. - headers = {'CONTENT_LENGTH': str(len(request_body)), 'SCGI': '1'} - header = '\x00'.join(('%s\x00%s' % item for item in headers.iteritems())) + '\x00' - header = '%d:%s' % (len(header), header) - request_body = '%s,%s' % (header, request_body) + request = self.encode_header(b'CONTENT_LENGTH', str(len(request_body)).encode()) + request += self.encode_header(b'SCGI', b'1') + request += self.encode_header(b'REQUEST_METHOD', b'POST') sock = None try: if host: - host, port = urllib.splitport(host) + parsed_host = urlparse('//' + host) + host, port = parsed_host.hostname, parsed_host.port addrinfo = socket.getaddrinfo(host, int(port), socket.AF_INET, socket.SOCK_STREAM) sock = socket.socket(*addrinfo[0][:3]) sock.connect(addrinfo[0][4]) else: + request += self.encode_header(b'REQUEST_URI', handler.encode()) sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect(handler) + request = self.encode_netstring(request) + request += request_body.encode() + self.verbose = verbose - sock.send(request_body) + sock.send(request) return self.parse_response(sock.makefile()) finally: if sock: @@ -134,19 +156,18 @@ def single_request(self, host, handler, request_body, verbose=0): def parse_response(self, response): p, u = self.getparser() - response_body = '' + r = b'' while True: data = response.read(1024) if not data: break - response_body += data + r += data.encode() # Remove SCGI headers from the response. - response_header, response_body = re.split(r'\n\s*?\n', response_body, - maxsplit=1) + response_header, response_body = re.split(r'\n\s*?\n', r.decode(), maxsplit=1) if self.verbose: - print 'body:', repr(response_body) + print('body: {0!r}'.format(response_body)) p.feed(response_body) p.close() @@ -154,13 +175,13 @@ def parse_response(self, response): return u.close() -class SCGIServerProxy(xmlrpclib.ServerProxy): +class SCGIServerProxy(xmlrpc_client.ServerProxy): def __init__(self, uri, transport=None, encoding=None, verbose=False, allow_none=False, use_datetime=False): - type, uri = urllib.splittype(uri) - if type not in ('scgi'): + parsed_url = urlparse(uri) + if parsed_url.scheme != 'scgi': raise IOError('unsupported XML-RPC protocol') - self.__host, self.__handler = urllib.splithost(uri) + self.__host, self.__handler = parsed_url.netloc, parsed_url.path if not self.__handler: self.__handler = '/' @@ -178,8 +199,8 @@ def __close(self): def __request(self, methodname, params): # call a method on the remote server - request = xmlrpclib.dumps(params, methodname, encoding=self.__encoding, - allow_none=self.__allow_none) + request = xmlrpc_client.dumps(params, methodname, encoding=self.__encoding, + allow_none=self.__allow_none) response = self.__transport.request( self.__host, @@ -203,7 +224,7 @@ def __repr__(self): def __getattr__(self, name): # magic method dispatcher - return xmlrpclib._Method(self.__request, name) + return xmlrpc_client._Method(self.__request, name) # note: to call a remote object with an non-standard name, use # result getattr(server, "strange-python-name")(args) diff --git a/lib/rtorrent/peer.py b/lib/rtorrent/peer.py index 2ab7cf9c6a..948370b5ad 100644 --- a/lib/rtorrent/peer.py +++ b/lib/rtorrent/peer.py @@ -18,20 +18,19 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# from rtorrent.rpc import Method import rtorrent.rpc from rtorrent.common import safe_repr Method = rtorrent.rpc.Method -class Peer: +class Peer(object): """Represents an individual peer within a L{Torrent} instance.""" def __init__(self, _rt_obj, info_hash, **kwargs): self._rt_obj = _rt_obj self.info_hash = info_hash # : info hash for the torrent the peer is associated with - for k in kwargs.keys(): + for k in kwargs: setattr(self, k, kwargs.get(k, None)) self.rpc_id = '{0}:p{1}'.format( diff --git a/lib/rtorrent/rpc/__init__.py b/lib/rtorrent/rpc/__init__.py index cf3cc73617..2a99bddc18 100644 --- a/lib/rtorrent/rpc/__init__.py +++ b/lib/rtorrent/rpc/__init__.py @@ -24,9 +24,13 @@ import rtorrent from rtorrent.common import (bool_to_int, convert_version_tuple_to_str, safe_repr) -from rtorrent.compat import xmlrpclib from rtorrent.err import MethodError +try: + import xmlrpc.client as xmlrpc_client +except ImportError: + import xmlrpclib as xmlrpc_client + def get_varname(rpc_call): """Transform rpc method into variable name. @@ -53,12 +57,12 @@ def _handle_unavailable_rpc_method(method, rt_obj): raise MethodError(msg) -class DummyClass: +class DummyClass(object): def __init__(self): pass -class Method: +class Method(object): """Represents an individual RPC method.""" def __init__(self, _class, method_name, @@ -115,7 +119,7 @@ def is_available(self, rt_obj): return(True) -class Multicall: +class Multicall(object): def __init__(self, class_obj, **kwargs): self.class_obj = class_obj if class_obj.__class__.__name__ == 'RTorrent': @@ -159,7 +163,7 @@ def call(self): @return: the results (post-processed), in the order they were added @rtype: tuple """ - m = xmlrpclib.MultiCall(self.rt_obj._get_conn()) + m = xmlrpc_client.MultiCall(self.rt_obj._get_conn()) for call in self.calls: method, args = call rpc_call = getattr(method, 'rpc_call') @@ -169,7 +173,7 @@ def call(self): results = tuple(results) results_processed = [] - for r, c in zip(results, self.calls): + for r, c in list(zip(results, self.calls)): method = c[0] # Method instance result = process_result(method, r) results_processed.append(result) diff --git a/lib/rtorrent/torrent.py b/lib/rtorrent/torrent.py index 3c22f6fb4e..06e9b46ca1 100644 --- a/lib/rtorrent/torrent.py +++ b/lib/rtorrent/torrent.py @@ -18,8 +18,6 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# from rtorrent.rpc import Method -import rtorrent.compat import rtorrent.file import rtorrent.peer import rtorrent.rpc @@ -32,14 +30,14 @@ Method = rtorrent.rpc.Method -class Torrent: +class Torrent(object): """Represents an individual torrent within a L{RTorrent} instance.""" def __init__(self, _rt_obj, info_hash, **kwargs): self._rt_obj = _rt_obj self.info_hash = info_hash # : info hash for the torrent self.rpc_id = self.info_hash # : unique id to pass to rTorrent - for k in kwargs.keys(): + for k in kwargs: setattr(self, k, kwargs.get(k, None)) self.peers = [] diff --git a/lib/rtorrent/tracker.py b/lib/rtorrent/tracker.py index b4222b2173..9f7d15abfa 100644 --- a/lib/rtorrent/tracker.py +++ b/lib/rtorrent/tracker.py @@ -18,20 +18,19 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# from rtorrent.rpc import Method import rtorrent.rpc from rtorrent.common import safe_repr Method = rtorrent.rpc.Method -class Tracker: +class Tracker(object): """Represents an individual tracker within a L{Torrent} instance.""" def __init__(self, _rt_obj, info_hash, **kwargs): self._rt_obj = _rt_obj self.info_hash = info_hash # : info hash for the torrent using this tracker - for k in kwargs.keys(): + for k in kwargs: setattr(self, k, kwargs.get(k, None)) # for clarity's sake... diff --git a/lib/synchronousdeluge/__init__.py b/lib/synchronousdeluge/__init__.py deleted file mode 100644 index bf5b20fe04..0000000000 --- a/lib/synchronousdeluge/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -"""A synchronous implementation of the Deluge RPC protocol - based on gevent-deluge by Christopher Rosell. - - https://github.com/chrippa/gevent-deluge - -Example usage: - - from synchronousdeluge import DelgueClient - - client = DelugeClient() - client.connect() - - # Wait for value - download_location = client.core.get_config_value("download_location").get() -""" - - -__title__ = "synchronous-deluge" -__version__ = "0.1" -__author__ = "Christian Dale" - -from synchronousdeluge.client import DelugeClient -from synchronousdeluge.exceptions import DelugeRPCError - diff --git a/lib/synchronousdeluge/client.py b/lib/synchronousdeluge/client.py deleted file mode 100644 index 22419e80ba..0000000000 --- a/lib/synchronousdeluge/client.py +++ /dev/null @@ -1,162 +0,0 @@ -import os -import platform - -from collections import defaultdict -from itertools import imap - -from synchronousdeluge.exceptions import DelugeRPCError -from synchronousdeluge.protocol import DelugeRPCRequest, DelugeRPCResponse -from synchronousdeluge.transfer import DelugeTransfer - -__all__ = ["DelugeClient"] - - -RPC_RESPONSE = 1 -RPC_ERROR = 2 -RPC_EVENT = 3 - - -class DelugeClient(object): - def __init__(self): - """A deluge client session.""" - self.transfer = DelugeTransfer() - self.modules = [] - self._request_counter = 0 - - def _get_local_auth(self): - auth_file = "" - username = password = "" - if platform.system() in ('Windows', 'Microsoft'): - appDataPath = os.environ.get("APPDATA") - if not appDataPath: - import _winreg - hkey = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders") - appDataReg = _winreg.QueryValueEx(hkey, "AppData") - appDataPath = appDataReg[0] - _winreg.CloseKey(hkey) - - auth_file = os.path.join(appDataPath, "deluge", "auth") - else: - from xdg.BaseDirectory import save_config_path - try: - auth_file = os.path.join(save_config_path("deluge"), "auth") - except OSError, e: - return username, password - - - if os.path.exists(auth_file): - for line in open(auth_file): - if line.startswith("#"): - # This is a comment line - continue - line = line.strip() - try: - lsplit = line.split(":") - except Exception, e: - continue - - if len(lsplit) == 2: - username, password = lsplit - elif len(lsplit) == 3: - username, password, level = lsplit - else: - continue - - if username == "localclient": - return (username, password) - - return ("", "") - - def _create_module_method(self, module, method): - fullname = "{0}.{1}".format(module, method) - - def func(obj, *args, **kwargs): - return self.remote_call(fullname, *args, **kwargs) - - func.__name__ = method - - return func - - def _introspect(self): - self.modules = [] - - methods = self.remote_call("daemon.get_method_list").get() - methodmap = defaultdict(dict) - splitter = lambda v: v.split(".") - - for module, method in imap(splitter, methods): - methodmap[module][method] = self._create_module_method(module, method) - - for module, methods in methodmap.items(): - clsname = "DelugeModule{0}".format(module.capitalize()) - cls = type(clsname, (), methods) - setattr(self, module, cls()) - self.modules.append(module) - - def remote_call(self, method, *args, **kwargs): - req = DelugeRPCRequest(self._request_counter, method, *args, **kwargs) - message = next(self.transfer.send_request(req)) - - response = DelugeRPCResponse() - - if not isinstance(message, tuple): - return - - if len(message) < 3: - return - - message_type = message[0] - -# if message_type == RPC_EVENT: -# event = message[1] -# values = message[2] -# -# if event in self._event_handlers: -# for handler in self._event_handlers[event]: -# gevent.spawn(handler, *values) -# -# elif message_type in (RPC_RESPONSE, RPC_ERROR): - if message_type in (RPC_RESPONSE, RPC_ERROR): - request_id = message[1] - value = message[2] - - if request_id == self._request_counter : - if message_type == RPC_RESPONSE: - response.set(value) - elif message_type == RPC_ERROR: - err = DelugeRPCError(*value) - response.set_exception(err) - - self._request_counter += 1 - return response - - def connect(self, host="127.0.0.1", port=58846, username="", password=""): - """Connects to a daemon process. - - :param host: str, the hostname of the daemon - :param port: int, the port of the daemon - :param username: str, the username to login with - :param password: str, the password to login with - """ - - # Connect transport - self.transfer.connect((host, port)) - - # Attempt to fetch local auth info if needed - if not username and host in ("127.0.0.1", "localhost"): - username, password = self._get_local_auth() - - # Authenticate - self.remote_call("daemon.login", username, password).get() - - # Introspect available methods - self._introspect() - - @property - def connected(self): - return self.transfer.connected - - def disconnect(self): - """Disconnects from the daemon.""" - self.transfer.disconnect() - diff --git a/lib/synchronousdeluge/exceptions.py b/lib/synchronousdeluge/exceptions.py deleted file mode 100644 index da6cf0228d..0000000000 --- a/lib/synchronousdeluge/exceptions.py +++ /dev/null @@ -1,11 +0,0 @@ -__all__ = ["DelugeRPCError"] - -class DelugeRPCError(Exception): - def __init__(self, name, msg, traceback): - self.name = name - self.msg = msg - self.traceback = traceback - - def __str__(self): - return "{0}: {1}: {2}".format(self.__class__.__name__, self.name, self.msg) - diff --git a/lib/synchronousdeluge/protocol.py b/lib/synchronousdeluge/protocol.py deleted file mode 100644 index 756d4dfc72..0000000000 --- a/lib/synchronousdeluge/protocol.py +++ /dev/null @@ -1,38 +0,0 @@ -__all__ = ["DelugeRPCRequest", "DelugeRPCResponse"] - -class DelugeRPCRequest(object): - def __init__(self, request_id, method, *args, **kwargs): - self.request_id = request_id - self.method = method - self.args = args - self.kwargs = kwargs - - def format(self): - return (self.request_id, self.method, self.args, self.kwargs) - -class DelugeRPCResponse(object): - def __init__(self): - self.value = None - self._exception = None - - def successful(self): - return self._exception is None - - @property - def exception(self): - if self._exception is not None: - return self._exception - - def set(self, value=None): - self.value = value - self._exception = None - - def set_exception(self, exception): - self._exception = exception - - def get(self): - if self._exception is None: - return self.value - else: - raise self._exception - diff --git a/lib/synchronousdeluge/transfer.py b/lib/synchronousdeluge/transfer.py deleted file mode 100644 index 472bb125c4..0000000000 --- a/lib/synchronousdeluge/transfer.py +++ /dev/null @@ -1,57 +0,0 @@ -import zlib -import struct -import socket -import ssl - -from synchronousdeluge import rencode - - -__all__ = ["DelugeTransfer"] - -class DelugeTransfer(object): - def __init__(self): - self.sock = None - self.conn = None - self.connected = False - - def connect(self, hostport): - if self.connected: - self.disconnect() - - self.sock = socket.create_connection(hostport) - self.conn = ssl.wrap_socket(self.sock, None, None, False, ssl.CERT_NONE, ssl.PROTOCOL_TLSv1) - self.connected = True - - def disconnect(self): - if self.conn: - self.conn.close() - self.connected = False - - def send_request(self, request): - data = (request.format(),) - payload = zlib.compress(rencode.dumps(data)) - self.conn.sendall(payload) - - buf = b"" - - while True: - data = self.conn.recv(1024) - - if not data: - self.connected = False - break - - buf += data - dobj = zlib.decompressobj() - - try: - message = rencode.loads(dobj.decompress(buf)) - except (ValueError, zlib.error, struct.error): - # Probably incomplete data, read more - continue - else: - buf = dobj.unused_data - - yield message - - diff --git a/lib/tvdbapiv2/api_client.py b/lib/tvdbapiv2/api_client.py index 47b08e1097..5209c8a75c 100644 --- a/lib/tvdbapiv2/api_client.py +++ b/lib/tvdbapiv2/api_client.py @@ -208,9 +208,9 @@ def deserialize(self, response, response_type): # fetch data from response object try: - data = json.loads(response.content) + data = response.json() except ValueError: - data = response.content + data = response.text return self.__deserialize(data, response_type) diff --git a/medusa/__main__.py b/medusa/__main__.py index 43fa69c615..1c350d080f 100755 --- a/medusa/__main__.py +++ b/medusa/__main__.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python # -*- coding: utf-8 -* # Author: Nic Wolfe # @@ -66,9 +66,10 @@ from medusa import ( app, auto_post_processor, cache, db, event_queue, exception_handler, - helpers, logger as app_logger, metadata, name_cache, naming, network_timezones, providers, - scheduler, show_queue, show_updater, subtitles, torrent_checker, trakt_checker, version_checker + helpers, logger as app_logger, metadata, name_cache, naming, network_timezones, + providers, scheduler, show_queue, show_updater, subtitles, trakt_checker ) +from medusa.clients.torrent import torrent_checker from medusa.common import SD, SKIPPED, WANTED from medusa.config import ( CheckSection, ConfigMigrator, check_setting_bool, check_setting_float, check_setting_int, check_setting_list, @@ -90,6 +91,7 @@ from medusa.system.shutdown import Shutdown from medusa.themes import read_themes from medusa.tv import Series +from medusa.updater.version_checker import CheckVersion logger = logging.getLogger(__name__) @@ -571,7 +573,6 @@ def initialize(self, console_logging=True): app.NAMING_CUSTOM_ANIME = bool(check_setting_int(app.CFG, 'General', 'naming_custom_anime', 0)) app.NAMING_MULTI_EP = check_setting_int(app.CFG, 'General', 'naming_multi_ep', 1) app.NAMING_ANIME_MULTI_EP = check_setting_int(app.CFG, 'General', 'naming_anime_multi_ep', 1) - app.NAMING_FORCE_FOLDERS = naming.check_force_season_folders() app.NAMING_STRIP_YEAR = bool(check_setting_int(app.CFG, 'General', 'naming_strip_year', 0)) app.USE_NZBS = bool(check_setting_int(app.CFG, 'General', 'use_nzbs', 0)) app.USE_TORRENTS = bool(check_setting_int(app.CFG, 'General', 'use_torrents', 1)) @@ -952,8 +953,8 @@ def initialize(self, console_logging=True): app.GIT_REMOTE_BRANCHES = [] app.KODI_LIBRARY_CLEAN_PENDING = False app.SELECTED_ROOT = check_setting_int(app.CFG, 'GUI', 'selected_root', -1) - app.BACKLOG_PERIOD = check_setting_str(app.CFG, 'GUI', 'backlog_period', 'all') - app.BACKLOG_STATUS = check_setting_str(app.CFG, 'GUI', 'backlog_status', 'all') + app.BACKLOG_PERIOD = check_setting_str(app.CFG, 'General', 'backlog_period', 'all') + app.BACKLOG_STATUS = check_setting_str(app.CFG, 'General', 'backlog_status', 'all') app.LAYOUT_WIDE = check_setting_bool(app.CFG, 'GUI', 'layout_wide', 0) app.SHOW_LIST_ORDER = check_setting_list(app.CFG, 'GUI', 'show_list_order', app.SHOW_LIST_ORDER) @@ -968,6 +969,10 @@ def initialize(self, console_logging=True): try: import pwd app.OS_USER = pwd.getpwuid(os.getuid()).pw_name + except KeyError: + # In the case of a usage with Docker run `user` feature, the username might not exist. + # See: https://docs.docker.com/engine/reference/run/#user + app.OS_USER = os.getuid() except ImportError: try: import getpass @@ -987,9 +992,9 @@ def initialize(self, console_logging=True): pass if app.VERSION_NOTIFY: - updater = version_checker.CheckVersion().updater + updater = CheckVersion().updater if updater: - app.APP_VERSION = updater.get_cur_version() + app.APP_VERSION = updater.current_version app.MAJOR_DB_VERSION, app.MINOR_DB_VERSION = db.DBConnection().checkDBVersion() @@ -1108,6 +1113,9 @@ def initialize(self, console_logging=True): main_db_con = db.DBConnection() db.sanityCheckDatabase(main_db_con, main_db.MainSanityCheck) + # checks that require DB existence + app.NAMING_FORCE_FOLDERS = naming.check_force_season_folders() + # migrate the config if it needs it migrator = ConfigMigrator(app.CFG) migrator.migrate_config() @@ -1128,7 +1136,7 @@ def initialize(self, console_logging=True): # initialize schedulers # updaters - app.version_check_scheduler = scheduler.Scheduler(version_checker.CheckVersion(), + app.version_check_scheduler = scheduler.Scheduler(CheckVersion(), cycleTime=datetime.timedelta(hours=app.UPDATE_FREQUENCY), threadName='CHECKVERSION', silent=False) @@ -2050,9 +2058,9 @@ def daemonize(self): sys.stderr.flush() devnull = getattr(os, 'devnull', '/dev/null') - stdin = file(devnull) - stdout = file(devnull, 'a+') - stderr = file(devnull, 'a+') + stdin = open(devnull) + stdout = open(devnull, 'a+') + stderr = open(devnull, 'a+') os.dup2(stdin.fileno(), getattr(sys.stdin, 'device', sys.stdin).fileno()) os.dup2(stdout.fileno(), getattr(sys.stdout, 'device', sys.stdout).fileno()) @@ -2073,16 +2081,9 @@ def stop_webserver(self): @staticmethod def restart(): """Restart application.""" - install_type = app.version_check_scheduler.action.install_type - - popen_list = [] - - if install_type in ('git', 'source'): - popen_list = [sys.executable, app.MY_FULLNAME] - elif install_type == 'win': - logger.error('You are using a binary Windows build of Medusa. Please switch to using git.') + popen_list = [sys.executable, app.MY_FULLNAME] - if popen_list and not app.NO_RESTART: + if not app.NO_RESTART: popen_list += app.MY_ARGS if '--nolaunch' not in popen_list: popen_list += ['--nolaunch'] diff --git a/medusa/browser.py b/medusa/browser.py index d04664e676..aab2b73b40 100644 --- a/medusa/browser.py +++ b/medusa/browser.py @@ -20,7 +20,9 @@ def get_win_drives(): drives = [] bitmask = windll.kernel32.GetLogicalDrives() # @UndefinedVariable - for letter in string.uppercase: + + drive_leters = string.ascii_uppercase + for letter in drive_leters: if bitmask & 1: drives.append(letter) bitmask >>= 1 diff --git a/medusa/clients/nzb/nzbget.py b/medusa/clients/nzb/nzbget.py index f301515997..fdf869f0b8 100644 --- a/medusa/clients/nzb/nzbget.py +++ b/medusa/clients/nzb/nzbget.py @@ -206,6 +206,6 @@ def sendNZB(nzb, proper=False): {'name': nzb.name}) return False except Exception: - log.warning('Connect Error to NZBget: could not add {file}.nzb to the' + log.warning('Connect Error to NZBget: could not add {name}.nzb to the' ' queue', {'name': nzb.name}) return False diff --git a/medusa/clients/torrent/__init__.py b/medusa/clients/torrent/__init__.py index 2cd2c58bd5..6072650d95 100644 --- a/medusa/clients/torrent/__init__.py +++ b/medusa/clients/torrent/__init__.py @@ -16,7 +16,6 @@ # You should have received a copy of the GNU General Public License # along with Medusa. If not, see . """Clients module.""" - from __future__ import unicode_literals @@ -34,7 +33,7 @@ def get_client_module(name): """Import the client module for the given name.""" - return __import__('{prefix}.{name}_client'.format(prefix=__name__, name=name.lower()), fromlist=_clients) + return __import__('{prefix}.{name}'.format(prefix=__name__, name=name.lower()), fromlist=_clients) def get_client_class(name): diff --git a/medusa/clients/torrent/deluge_client.py b/medusa/clients/torrent/deluge.py similarity index 99% rename from medusa/clients/torrent/deluge_client.py rename to medusa/clients/torrent/deluge.py index 18dacaf024..b0048db021 100644 --- a/medusa/clients/torrent/deluge_client.py +++ b/medusa/clients/torrent/deluge.py @@ -19,6 +19,7 @@ ) from medusa.logger.adapters.style import BraceAdapter +from requests.compat import urljoin from requests.exceptions import RequestException from six import viewitems @@ -54,7 +55,6 @@ def read_torrent_status(torrent_data): {'torrent': details['name']}) continue - status = 'busy' if details['is_finished']: status = 'completed' elif details['is_seed']: @@ -118,7 +118,7 @@ def __init__(self, host=None, username=None, password=None): """ super(DelugeAPI, self).__init__('Deluge', host, username, password) self.session.headers.update({'Content-Type': 'application/json'}) - self.url = '{host}json'.format(host=self.host) + self.url = urljoin(self.host, 'json') def _get_auth(self): post_data = json.dumps({ @@ -240,7 +240,7 @@ def _add_torrent_file(self, result): 'method': 'core.add_torrent_file', 'params': [ '{name}.torrent'.format(name=result.name), - b64encode(result.content), + b64encode(result.content).decode('utf-8'), {}, ], 'id': 2, diff --git a/medusa/clients/torrent/deluged_client.py b/medusa/clients/torrent/deluged.py similarity index 93% rename from medusa/clients/torrent/deluged_client.py rename to medusa/clients/torrent/deluged.py index d7d21c0802..134ac34199 100644 --- a/medusa/clients/torrent/deluged_client.py +++ b/medusa/clients/torrent/deluged.py @@ -12,13 +12,13 @@ from base64 import b64encode from builtins import object +from deluge_client import DelugeRPCClient + from medusa import app -from medusa.clients.torrent.deluge_client import read_torrent_status +from medusa.clients.torrent.deluge import read_torrent_status from medusa.clients.torrent.generic import GenericClient from medusa.logger.adapters.style import BraceAdapter -from synchronousdeluge import DelugeClient - log = BraceAdapter(logging.getLogger(__name__)) log.logger.addHandler(logging.NullHandler()) @@ -27,8 +27,6 @@ class DelugeDAPI(GenericClient): """Deluge Daemon API class.""" - drpc = None - def __init__(self, host=None, username=None, password=None): """Constructor. @@ -40,6 +38,7 @@ def __init__(self, host=None, username=None, password=None): :type password: string """ super(DelugeDAPI, self).__init__('DelugeD', host, username, password) + self.drpc = None def _get_auth(self): return True if self.connect() else None @@ -168,12 +167,6 @@ def remove_ratio_reached(self): class DelugeRPC(object): """Deluge RPC client class.""" - host = 'localhost' - port = 58846 - username = None - password = None - client = None - def __init__(self, host='localhost', port=58846, username=None, password=None): """Constructor. @@ -188,14 +181,14 @@ def __init__(self, host='localhost', port=58846, username=None, password=None): """ super(DelugeRPC, self).__init__() self.host = host - self.port = port + self.port = int(port) self.username = username self.password = password def connect(self): """Connect to the host using synchronousdeluge API.""" - self.client = DelugeClient() - self.client.connect(self.host, int(self.port), self.username, self.password) + self.client = DelugeRPCClient(self.host, self.port, self.username, self.password, decode_utf8=True) + self.client.connect() def test(self): """Test connection. @@ -220,7 +213,7 @@ def remove_torrent_data(self, torrent_id): """ try: self.connect() - self.client.core.remove_torrent(torrent_id, True).get() + self.client.core.remove_torrent(torrent_id, True) except Exception: return False else: @@ -241,7 +234,7 @@ def move_storage(self, torrent_id, location): """ try: self.connect() - self.client.core.move_storage(torrent_id, location).get() + self.client.core.move_storage(torrent_id, location) except Exception: return False else: @@ -264,10 +257,11 @@ def add_torrent_magnet(self, torrent, options, info_hash): """ try: self.connect() - torrent_id = self.client.core.add_torrent_magnet(torrent, options).get() + torrent_id = self.client.core.add_torrent_magnet(torrent, options) if not torrent_id: torrent_id = self._check_torrent(info_hash) except Exception: + raise return False else: return torrent_id @@ -291,7 +285,7 @@ def add_torrent_file(self, filename, torrent, options, info_hash): """ try: self.connect() - torrent_id = self.client.core.add_torrent_file(filename, b64encode(torrent), options).get() + torrent_id = self.client.core.add_torrent_file(filename, b64encode(torrent), options) if not torrent_id: torrent_id = self._check_torrent(info_hash) except Exception: @@ -314,7 +308,7 @@ def set_torrent_label(self, torrent_id, label): """ try: self.connect() - self.client.label.set_torrent(torrent_id, label).get() + self.client.label.set_torrent(torrent_id, label) except Exception: return False else: @@ -335,8 +329,8 @@ def set_torrent_path(self, torrent_id, path): """ try: self.connect() - self.client.core.set_torrent_move_completed_path(torrent_id, path).get() - self.client.core.set_torrent_move_completed(torrent_id, 1).get() + self.client.core.set_torrent_move_completed_path(torrent_id, path) + self.client.core.set_torrent_move_completed(torrent_id, 1) except Exception: return False else: @@ -358,7 +352,7 @@ def set_torrent_priority(self, torrent_id, priority): try: self.connect() if priority: - self.client.core.queue_top([torrent_id]).get() + self.client.core.queue_top([torrent_id]) except Exception: return False else: @@ -379,8 +373,8 @@ def set_torrent_ratio(self, torrent_id, ratio): """ try: self.connect() - self.client.core.set_torrent_stop_at_ratio(torrent_id, True).get() - self.client.core.set_torrent_stop_ratio(torrent_id, ratio).get() + self.client.core.set_torrent_stop_at_ratio(torrent_id, True) + self.client.core.set_torrent_stop_ratio(torrent_id, ratio) except Exception: return False else: @@ -399,7 +393,7 @@ def pause_torrent(self, torrent_ids): """ try: self.connect() - self.client.core.pause_torrent(torrent_ids).get() + self.client.core.pause_torrent(torrent_ids) except Exception: return False else: @@ -413,7 +407,7 @@ def disconnect(self): self.client.disconnect() def _check_torrent(self, info_hash): - torrent_id = self.client.core.get_torrent_status(info_hash, {}).get() + torrent_id = self.client.core.get_torrent_status(info_hash, {}) if torrent_id['hash']: log.debug('DelugeD: Torrent already exists in Deluge') return info_hash @@ -429,7 +423,7 @@ def get_all_torrents(self): self.connect() torrents_data = self.client.core.get_torrents_status({}, ('name', 'hash', 'progress', 'state', 'ratio', 'stop_ratio', 'is_seed', 'is_finished', - 'paused', 'files')).get() + 'paused', 'files')) except Exception: return False else: diff --git a/medusa/clients/torrent/downloadstation_client.py b/medusa/clients/torrent/downloadstation.py similarity index 100% rename from medusa/clients/torrent/downloadstation_client.py rename to medusa/clients/torrent/downloadstation.py diff --git a/medusa/clients/torrent/generic.py b/medusa/clients/torrent/generic.py index 26b6bf950e..7563b99251 100644 --- a/medusa/clients/torrent/generic.py +++ b/medusa/clients/torrent/generic.py @@ -80,24 +80,16 @@ def _request(self, method='get', params=None, data=None, files=None, cookies=Non try: self.response = self.session.request(method, self.url, params=params, data=data, files=files, cookies=cookies, timeout=120, verify=False) - except requests.exceptions.ConnectionError as msg: - log.error('{name}: Unable to connect {error}', - {'name': self.name, 'error': msg}) + except (requests.exceptions.MissingSchema, requests.exceptions.InvalidURL) as error: + log.warning('{name}: Invalid Host: {error}', {'name': self.name, 'error': error}) return False - except (requests.exceptions.MissingSchema, requests.exceptions.InvalidURL): - log.error('{name}: Invalid Host', {'name': self.name}) - return False - except requests.exceptions.HTTPError as msg: - log.error('{name}: Invalid HTTP Request {error}', - {'name': self.name, 'error': msg}) - return False - except requests.exceptions.Timeout as msg: - log.warning('{name}: Connection Timeout {error}', - {'name': self.name, 'error': msg}) + except requests.exceptions.RequestException as error: + log.warning('{name}: Error occurred during request: {error}', + {'name': self.name, 'error': error}) return False - except Exception as msg: - log.error('{name}: Unknown exception raised when send torrent to' - ' {name} : {error}', {'name': self.name, 'error': msg}) + except Exception as error: + log.error('{name}: Unknown exception raised when sending torrent to' + ' {name}: {error}', {'name': self.name, 'error': error}) return False if self.response.status_code == 401: diff --git a/medusa/clients/torrent/mlnet_client.py b/medusa/clients/torrent/mlnet.py similarity index 99% rename from medusa/clients/torrent/mlnet_client.py rename to medusa/clients/torrent/mlnet.py index f3c6dee5ca..95d4554547 100644 --- a/medusa/clients/torrent/mlnet_client.py +++ b/medusa/clients/torrent/mlnet.py @@ -50,4 +50,5 @@ def _add_torrent_file(self, result): } return self._request(method='get', params=params) + api = MLNetAPI diff --git a/medusa/clients/torrent/qbittorrent_client.py b/medusa/clients/torrent/qbittorrent.py similarity index 100% rename from medusa/clients/torrent/qbittorrent_client.py rename to medusa/clients/torrent/qbittorrent.py diff --git a/medusa/clients/torrent/rtorrent_client.py b/medusa/clients/torrent/rtorrent.py similarity index 98% rename from medusa/clients/torrent/rtorrent_client.py rename to medusa/clients/torrent/rtorrent.py index 2d4ad0d7b5..6a8b09fffe 100644 --- a/medusa/clients/torrent/rtorrent_client.py +++ b/medusa/clients/torrent/rtorrent.py @@ -2,7 +2,7 @@ """rTorrent Client.""" -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals import logging diff --git a/medusa/torrent_checker.py b/medusa/clients/torrent/torrent_checker.py similarity index 100% rename from medusa/torrent_checker.py rename to medusa/clients/torrent/torrent_checker.py diff --git a/medusa/clients/torrent/transmission_client.py b/medusa/clients/torrent/transmission.py similarity index 99% rename from medusa/clients/torrent/transmission_client.py rename to medusa/clients/torrent/transmission.py index b6e1a2bd25..ad7a015b0a 100644 --- a/medusa/clients/torrent/transmission_client.py +++ b/medusa/clients/torrent/transmission.py @@ -109,7 +109,7 @@ def _add_torrent_uri(self, result): def _add_torrent_file(self, result): arguments = { - 'metainfo': b64encode(result.content), + 'metainfo': b64encode(result.content).decode('utf-8'), 'paused': 1 if app.TORRENT_PAUSED else 0 } diff --git a/medusa/clients/torrent/utorrent_client.py b/medusa/clients/torrent/utorrent.py similarity index 99% rename from medusa/clients/torrent/utorrent_client.py rename to medusa/clients/torrent/utorrent.py index eecaff5103..7b84f525a5 100644 --- a/medusa/clients/torrent/utorrent_client.py +++ b/medusa/clients/torrent/utorrent.py @@ -26,7 +26,7 @@ def get_torrent_subfolder(result): root_dirs = app.ROOT_DIRS if root_dirs: root_location = root_dirs[int(root_dirs[0]) + 1] - torrent_path = result.series.raw_location + torrent_path = result.series.location if root_dirs and root_location != torrent_path: # Subfolder is under root, but possibly not directly under diff --git a/medusa/common.py b/medusa/common.py index a460410dff..444ba71e98 100644 --- a/medusa/common.py +++ b/medusa/common.py @@ -39,7 +39,7 @@ long = int INSTANCE_ID = str(uuid.uuid1()) -VERSION = '0.2.14' +VERSION = '0.3.0' USER_AGENT = 'Medusa/{version} ({system}; {release}; {instance})'.format( version=VERSION, system=platform.system(), release=platform.release(), instance=INSTANCE_ID) diff --git a/medusa/config.py b/medusa/config.py index df815c978d..089e7fea51 100644 --- a/medusa/config.py +++ b/medusa/config.py @@ -32,7 +32,7 @@ from medusa.helper.common import try_int from medusa.helpers.utils import split_and_strip from medusa.logger.adapters.style import BraceAdapter -from medusa.version_checker import CheckVersion +from medusa.updater.version_checker import CheckVersion from requests.compat import urlsplit diff --git a/medusa/databases/main_db.py b/medusa/databases/main_db.py index 427d3fbcb2..b4ac92261c 100644 --- a/medusa/databases/main_db.py +++ b/medusa/databases/main_db.py @@ -865,3 +865,39 @@ def execute(self): self.connection.action('DROP TABLE tmp_tv_episodes;') self.inc_minor_version() + + +class AddTvshowStartSearchOffset(AddEpisodeWatchedField): + """Add tv_show airdate_offset field.""" + + def test(self): + """Test if the version is at least 44.13""" + return self.connection.version >= (44, 13) + + def execute(self): + utils.backup_database(self.connection.path, self.connection.version) + + log.info(u'Adding new airdate_offset field in the tv_shows table') + if not self.hasColumn('tv_shows', 'airdate_offset'): + self.addColumn('tv_shows', 'airdate_offset', 'NUMERIC', 0) + + self.inc_minor_version() + + +class AddReleaseIgnoreRequireExludeOptions(AddTvshowStartSearchOffset): + """Add release ignore and require exclude option flags.""" + + def test(self): + """Test if the version is at least 44.14""" + return self.connection.version >= (44, 14) + + def execute(self): + utils.backup_database(self.connection.path, self.connection.version) + + log.info(u'Adding release ignore and require exclude option flags to the tv_shows table') + if not self.hasColumn('tv_shows', 'rls_require_exclude'): + self.addColumn('tv_shows', 'rls_require_exclude', 'NUMERIC', 0) + if not self.hasColumn('tv_shows', 'rls_ignore_exclude'): + self.addColumn('tv_shows', 'rls_ignore_exclude', 'NUMERIC', 0) + + self.inc_minor_version() diff --git a/medusa/generic_queue.py b/medusa/generic_queue.py index 9ef214a9f8..fbdbf63856 100644 --- a/medusa/generic_queue.py +++ b/medusa/generic_queue.py @@ -57,7 +57,7 @@ def run(self, force=False): """ with self.lock: # only start a new task if one isn't already going - if self.currentItem is None or not self.currentItem.isAlive(): + if self.currentItem is None or not self.currentItem.is_alive(): # if the thread is dead then the current item should be # finished diff --git a/medusa/github_client.py b/medusa/github_client.py index 106aa8d126..0ff05f961a 100644 --- a/medusa/github_client.py +++ b/medusa/github_client.py @@ -102,3 +102,21 @@ def get_github_repo(organization, repo, gh=None): except github.GithubException as e: logger.debug('Unable to contact Github: {ex!r}', ex=e) raise + + +def get_latest_release(organization, repo, gh=None): + """Return the latest release of a repository. + + :param repo: + :type repo: string + :param gh: + :type gh: Github + :return: + :rtype github.GitRelease.GitRelease + """ + try: + gh = gh or github.MainClass.Github(**OPTIONS) + return gh.get_organization(organization).get_repo(repo).get_latest_release() + except github.GithubException as e: + logger.debug('Unable to contact Github: {ex!r}', ex=e) + raise diff --git a/medusa/helper/common.py b/medusa/helper/common.py index f4cbca7d8e..f114c5f7ee 100644 --- a/medusa/helper/common.py +++ b/medusa/helper/common.py @@ -136,10 +136,10 @@ def http_code_description(http_code): """ Get the description of the provided HTTP status code. + :param http_code: The HTTP status code :return: The description of the provided ``http_code`` """ - description = http_status_code.get(try_int(http_code)) if isinstance(description, list): @@ -151,10 +151,10 @@ def http_code_description(http_code): def is_sync_file(filename): """ Check if the provided ``filename`` is a sync file, based on its name. + :param filename: The filename to check :return: ``True`` if the ``filename`` is a sync file, ``False`` otherwise """ - if isinstance(filename, (str, text_type)): extension = filename.rpartition('.')[2].lower() @@ -168,10 +168,10 @@ def is_sync_file(filename): def is_torrent_or_nzb_file(filename): """ Check if the provided ``filename`` is a NZB file or a torrent file, based on its extension. + :param filename: The filename to check :return: ``True`` if the ``filename`` is a NZB file or a torrent file, ``False`` otherwise """ - if not isinstance(filename, (str, text_type)): return False @@ -206,14 +206,15 @@ def pretty_file_size(size, use_decimal=False, **kwargs): def convert_size(size, default=None, use_decimal=False, **kwargs): """ - Convert a file size into the number of bytes + Convert a file size into the number of bytes. :param size: to be converted :param default: value to return if conversion fails :param use_decimal: use decimal instead of binary prefixes (e.g. kilo = 1000 instead of 1024) :keyword sep: Separator between size and units, default is space - :keyword units: A list of (uppercase) unit names in ascending order. Default units: ['B', 'KB', 'MB', 'GB', 'TB', 'PB'] + :keyword units: A list of (uppercase) unit names in ascending order. + Default units: ['B', 'KB', 'MB', 'GB', 'TB', 'PB'] :keyword default_units: Default unit if none is given, default is lowest unit in the scale, e.g. bytes :returns: the number of bytes, the default value, or 0 @@ -260,11 +261,11 @@ def convert_size(size, default=None, use_decimal=False, **kwargs): def remove_extension(filename): """ Remove the extension of the provided ``filename``. + The extension is only removed if it is in `medusa.helper.common.media_extensions` or ['nzb', 'torrent']. :param filename: The filename from which we want to remove the extension :return: The ``filename`` without its extension. """ - if isinstance(filename, (str, text_type)) and '.' in filename: basename, _, extension = filename.rpartition('.') @@ -277,11 +278,11 @@ def remove_extension(filename): def replace_extension(filename, new_extension): """ Replace the extension of the provided ``filename`` with a new extension. + :param filename: The filename for which we want to change the extension :param new_extension: The new extension to apply on the ``filename`` :return: The ``filename`` with the new extension """ - if isinstance(filename, (str, text_type)) and '.' in filename: basename, _, _ = filename.rpartition('.') @@ -294,10 +295,10 @@ def replace_extension(filename, new_extension): def sanitize_filename(filename): """ Remove specific characters from the provided ``filename``. + :param filename: The filename to clean :return: The cleaned ``filename`` """ - if isinstance(filename, (str, text_type)): # https://stackoverflow.com/a/31976060/7597273 remove = r''.join(( @@ -321,24 +322,24 @@ def sanitize_filename(filename): def try_int(candidate, default_value=0): """ Try to convert ``candidate`` to int, or return the ``default_value``. + :param candidate: The value to convert to int :param default_value: The value to return if the conversion fails :return: ``candidate`` as int, or ``default_value`` if the conversion fails """ - try: return int(candidate) except (ValueError, TypeError): - if candidate and (',' in candidate or '.' in candidate): + if candidate: # Get the current stack trace (excluding the following line) stack_trace = traceback.format_stack(limit=10)[:-2] - log.exception(u'Failed parsing provider.\nStack trace:\n{0}', ''.join(stack_trace)) + log.exception('Casting to int failed.\nStack trace:\n{0}'.format(''.join(stack_trace))) return default_value def episode_num(season=None, episode=None, numbering='standard'): """ - Convert season and episode into string + Convert season and episode into string. :param season: Season number :type season: int or None @@ -357,9 +358,7 @@ def episode_num(season=None, episode=None, numbering='standard'): def enabled_providers(search_type): - """ - Return providers based on search type: daily, backlog and manualsearch - """ + """Return providers based on search type: daily, backlog and manual search.""" from medusa import providers return [x for x in providers.sorted_provider_list(app.RANDOMIZE_PROVIDERS) if x.is_active() and x.get_id() not in app.BROKEN_PROVIDERS and @@ -369,7 +368,7 @@ def enabled_providers(search_type): def remove_strings(old_string, unwanted_strings): """ - Return string removing all unwanted strings on it + Return string removing all unwanted strings on it. :param old_string: String that will be cleaned :param unwanted_strings: List of unwanted strings diff --git a/medusa/helpers/__init__.py b/medusa/helpers/__init__.py index 2fd98b672c..988eb9916b 100644 --- a/medusa/helpers/__init__.py +++ b/medusa/helpers/__init__.py @@ -23,13 +23,13 @@ import time import traceback import uuid -import xml.etree.ElementTree as ET import zipfile from builtins import chr from builtins import hex from builtins import str from builtins import zip from itertools import cycle +from xml.etree import ElementTree from cachecontrol import CacheControlAdapter from cachecontrol.cache import DictCache @@ -54,7 +54,7 @@ import requests from requests.compat import urlparse -from six import string_types, text_type, viewitems +from six import binary_type, ensure_binary, ensure_text, string_types, text_type, viewitems from six.moves import http_client log = BraceAdapter(logging.getLogger(__name__)) @@ -286,7 +286,7 @@ def copy_file(src_file, dest_file): except (SpecialFileError, Error) as error: log.warning('Error copying file: {error}', {'error': error}) except OSError as error: - msg = BraceMessage('OSError: {0}', error.message) + msg = BraceMessage('OSError: {0!r}', error) if error.errno == errno.ENOSPC: # Only warn if device is out of space log.warning(msg) @@ -953,24 +953,19 @@ def check_url(url): def encrypt(data, encryption_version=0, _decrypt=False): - # Version 1: Simple XOR encryption (this is not very secure, but works) - if encryption_version == 1: - if _decrypt: - return ''.join(chr(ord(x) ^ ord(y)) for (x, y) in zip(base64.decodestring(data), cycle(unique_key1))) - else: - return base64.encodestring( - ''.join(chr(ord(x) ^ ord(y)) for (x, y) in zip(data, cycle(unique_key1)))).strip() - # Version 2: Simple XOR encryption (this is not very secure, but works) - elif encryption_version == 2: - if _decrypt: - return ''.join(chr(ord(x) ^ ord(y)) for (x, y) in zip(base64.decodestring(data), - cycle(app.ENCRYPTION_SECRET))) - else: - return base64.encodestring( - ''.join(chr(ord(x) ^ ord(y)) for (x, y) in zip(data, cycle(app.ENCRYPTION_SECRET)))).strip() # Version 0: Plain text - else: + if encryption_version == 0: return data + else: + # Simple XOR encryption, Base64 encoded + # Version 1: unique_key1; Version 2: app.ENCRYPTION_SECRET + key = unique_key1 if encryption_version == 1 else app.ENCRYPTION_SECRET + if _decrypt: + data = ensure_text(base64.decodestring(ensure_binary(data))) + return ''.join(chr(ord(x) ^ ord(y)) for (x, y) in zip(data, cycle(key))) + else: + data = ''.join(chr(ord(x) ^ ord(y)) for (x, y) in zip(data, cycle(key))) + return ensure_text(base64.encodestring(ensure_binary(data))).strip() def decrypt(data, encryption_version=0): @@ -1025,8 +1020,8 @@ def get_show(name, try_indexers=False): match_name_only = (s.name for s in app.showList if text_type(s.imdb_year) in s.name and series_name.lower() == s.name.lower().replace(' ({year})'.format(year=s.imdb_year), '')) for found_series in match_name_only: - log.warning("Consider adding '{name}' in scene exceptions for series '{series}'".format - (name=series_name, series=found_series)) + log.info("Consider adding '{name}' in scene exceptions for series '{series}'".format + (name=series_name, series=found_series)) # add show to cache if series and not from_cache: @@ -1089,7 +1084,7 @@ def validate_show(show, season=None, episode=None): return show.indexer_api[show.indexerid][season][episode] except (IndexerEpisodeNotFound, IndexerSeasonNotFound, IndexerShowNotFound) as error: - log.debug(u'Unable to validate show. Reason: {0!r}', error.message) + log.debug(u'Unable to validate show. Reason: {0!r}', error) pass @@ -1308,8 +1303,8 @@ def get_size(start_path='.'): def generate_api_key(): """Return a new randomized API_KEY.""" log.info(u'Generating New API key') - secure_hash = hashlib.sha512(str(time.time())) - secure_hash.update(str(random.SystemRandom().getrandbits(4096))) + secure_hash = hashlib.sha512(str(time.time()).encode('utf-8')) + secure_hash.update(str(random.SystemRandom().getrandbits(4096)).encode('utf-8')) return secure_hash.hexdigest()[:32] @@ -1467,7 +1462,7 @@ def get_tvdb_from_id(indexer_id, indexer): return tvdb_id with suppress(SyntaxError): - tree = ET.fromstring(data) + tree = ElementTree.fromstring(data) for show in tree.iter('Series'): tvdb_id = show.findtext('seriesid') @@ -1481,7 +1476,7 @@ def get_tvdb_from_id(indexer_id, indexer): return tvdb_id with suppress(SyntaxError): - tree = ET.fromstring(data) + tree = ElementTree.fromstring(data) for show in tree.iter('Series'): tvdb_id = show.findtext('seriesid') @@ -1611,6 +1606,25 @@ def unicodify(value): return value +def to_text(s, encoding='utf-8', errors='strict'): + """Coerce *s* to six.text_type. + + This code is part of the six library. + For Python 2: + - `unicode` -> `unicode` + - `str` -> `unicode` + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + if isinstance(s, binary_type): + return s.decode(encoding, errors) + elif isinstance(s, text_type): + return s + else: + raise TypeError("not expecting type '%s'" % type(s)) + + def single_or_list(value, allow_multi=False): """Return a single value or a list. @@ -1728,7 +1742,13 @@ def title_to_imdb(title, start_year, imdb_api=None): if imdb_api is None: imdb_api = Imdb() - titles = imdb_api.search_for_title(title) + try: + titles = imdb_api.search_for_title(title) + except ValueError as error: + # FIXME: Putting an error here, as this is a known error with the lib imdbpie. And should be fix. + log.warning('Could not get a result from imdbpie for the title {title}, error: {error}', + {'title': title, 'error': error}) + return None if len(titles) == 1: return titles[0]['imdb_id'] diff --git a/medusa/helpers/anidb.py b/medusa/helpers/anidb.py index c8bd0ae70d..391b89a60b 100644 --- a/medusa/helpers/anidb.py +++ b/medusa/helpers/anidb.py @@ -1,5 +1,5 @@ """Helper for anidb communications.""" - +from __future__ import unicode_literals import logging from os.path import join @@ -12,6 +12,7 @@ from medusa.helper.exceptions import AnidbAdbaConnectionException from medusa.logger.adapters.style import BraceAdapter +import six log = BraceAdapter(logging.getLogger(__name__)) log.logger.addHandler(logging.NullHandler()) @@ -47,13 +48,16 @@ def set_up_anidb_connection(): return app.ADBA_CONNECTION.authed() -def create_key_encode_utf_8(namespace, fn, **kw): +def create_key(namespace, fn, **kw): def generate_key(*args, **kw): - return namespace + '|' + args[0].encode('utf-8') + show_key = namespace + '|' + args[0] + if six.PY2: + return show_key.encode('utf-8') + return show_key return generate_key -@anidb_cache.cache_on_arguments(namespace='anidb', function_key_generator=create_key_encode_utf_8) +@anidb_cache.cache_on_arguments(namespace='anidb', function_key_generator=create_key) def get_release_groups_for_anime(series_name): """Get release groups for an anidb anime.""" groups = [] @@ -62,7 +66,7 @@ def get_release_groups_for_anime(series_name): anime = adba.Anime(app.ADBA_CONNECTION, name=series_name, cache_path=join(app.CACHE_DIR, 'adba')) groups = anime.get_groups() except Exception as error: - log.warning(u'Unable to retrieve Fansub Groups from AniDB. Error: {error}', {'error': error.message}) + log.warning(u'Unable to retrieve Fansub Groups from AniDB. Error: {error!r}', {'error': error}) raise AnidbAdbaConnectionException(error) return groups diff --git a/medusa/helpers/externals.py b/medusa/helpers/externals.py index fa22e5bc15..d7ef7e7eec 100644 --- a/medusa/helpers/externals.py +++ b/medusa/helpers/externals.py @@ -35,9 +35,8 @@ def trakt_request(api, trakt_url): app.TRAKT_ACCESS_TOKEN = api.access_token app.TRAKT_REFRESH_TOKEN = api.refresh_token app.instance.save_config() - except (AuthException, TraktException, TokenExpiredException) as e: - log.info(u'Could not use Trakt to enrich with externals: {0}', - e.message or e) + except (AuthException, TraktException, TokenExpiredException) as error: + log.info(u'Could not use Trakt to enrich with externals: {0!r}', error) return [] else: return trakt_result @@ -112,8 +111,8 @@ def get_externals(show=None, indexer=None, indexed_show=None): except (IndexerException, RequestException) as error: log.warning( u'Error getting external ids for other' - u' indexer {name}: {reason}', - {'name': indexerApi(other_indexer).name, 'reason': error.message}) + u' indexer {name}: {reason!r}', + {'name': indexerApi(other_indexer).name, 'reason': error}) # Try to update with the Trakt externals. if app.USE_TRAKT: @@ -198,7 +197,7 @@ def load_externals_from_db(indexer=None, indexer_id=None): externals[mappings[result['mindexer']]] = result['mindexer_id'] else: externals[mappings[result['indexer']]] = result['indexer_id'] - except KeyError as e: - log.error(u'Indexer not supported in current mappings: {id}', {'id': e.message}) + except KeyError as error: + log.error(u'Indexer not supported in current mappings: {id!r}', {'id': error}) return externals diff --git a/medusa/helpers/utils.py b/medusa/helpers/utils.py index f1e212b2ae..7fc2a204eb 100644 --- a/medusa/helpers/utils.py +++ b/medusa/helpers/utils.py @@ -6,7 +6,6 @@ from builtins import str from collections import Iterable from datetime import datetime -from distutils.util import strtobool from dateutil import tz @@ -66,6 +65,24 @@ def truth_to_bool(value): return bool(strtobool(str(value))) if value else False +def strtobool(val): + """ + Convert a string representation of truth to true (1) or false (0). + + Ported from: https://is.gd/FSeBX8 + True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values + are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if + 'val' is anything else. + """ + val = val.lower() + if val in ('y', 'yes', 't', 'true', 'on', '1'): + return 1 + elif val in ('n', 'no', 'f', 'false', 'off', '0'): + return 0 + else: + raise ValueError('invalid truth value %r' % (val,)) + + def to_timestamp(dt): """Return POSIX timestamp corresponding to the datetime instance. @@ -79,3 +96,9 @@ def to_timestamp(dt): dt_utc = dt.astimezone(tz.gettz('UTC')) return (dt_utc - epoch).total_seconds() + + +def to_camel_case(snake_str): + """Convert a snake formatted string to camel case.""" + components = snake_str.split('_') + return components[0] + ''.join(x.title() for x in components[1:]) diff --git a/medusa/indexers/indexer_api.py b/medusa/indexers/indexer_api.py index 8cf2d8e2f9..0efd0b5e70 100644 --- a/medusa/indexers/indexer_api.py +++ b/medusa/indexers/indexer_api.py @@ -7,7 +7,7 @@ from medusa import app from medusa.helper.common import try_int -from medusa.indexers.indexer_config import indexerConfig, initConfig +from medusa.indexers.indexer_config import indexerConfig, init_config from medusa.indexers.tvdbv2.fallback import PlexFallBackConfig from six import itervalues @@ -33,8 +33,8 @@ def config(self): if self.indexer_id: return indexerConfig[self.indexer_id] # Sort and put the default language first - initConfig['valid_languages'].sort(key=lambda i: '\0' if i == app.INDEXER_DEFAULT_LANGUAGE else i) - return initConfig + init_config['valid_languages'].sort(key=lambda i: '\0' if i == app.INDEXER_DEFAULT_LANGUAGE else i) + return init_config @property def name(self): diff --git a/medusa/indexers/indexer_config.py b/medusa/indexers/indexer_config.py index 04d0d9a707..bfa5219f85 100644 --- a/medusa/indexers/indexer_config.py +++ b/medusa/indexers/indexer_config.py @@ -14,7 +14,7 @@ from six import iteritems -initConfig = { +init_config = { 'valid_languages': [ 'da', 'fi', 'nl', 'de', 'it', 'es', 'fr', 'pl', 'hu', 'el', 'tr', 'ru', 'he', 'ja', 'pt', 'zh', 'cs', 'sl', 'hr', 'ko', 'en', 'sv', 'no' @@ -146,8 +146,8 @@ def get_indexer_config(): } main = { - 'validLanguages': initConfig['valid_languages'], - 'langabbvToId': initConfig['langabbv_to_id'], + 'validLanguages': init_config['valid_languages'], + 'langabbvToId': init_config['langabbv_to_id'], 'externalMappings': {str(k): v for k, v in iteritems(EXTERNAL_MAPPINGS)}, 'traktIndexers': TRAKT_INDEXERS, 'statusMap': STATUS_MAP diff --git a/medusa/indexers/tvdbv2/fallback.py b/medusa/indexers/tvdbv2/fallback.py index 76dbd2d0eb..ceb42867e3 100644 --- a/medusa/indexers/tvdbv2/fallback.py +++ b/medusa/indexers/tvdbv2/fallback.py @@ -114,12 +114,12 @@ def fallback_notification(): except (IndexerEpisodeNotFound, IndexerSeasonNotFound, IndexerShowIncomplete, IndexerShowNotFound, IndexerShowNotFoundInLanguage): raise - except ApiException as e: - logger.warning("could not connect to TheTvdb.com, reason '%s'", e.reason) - except IndexerUnavailable as e: - logger.warning("could not connect to TheTvdb.com, with reason '%s'", e.message) - except Exception as e: - logger.warning("could not connect to TheTvdb.com, with reason '%s'", e.message) + except ApiException as error: + logger.warning("could not connect to TheTvdb.com, reason '%s'", error.reason) + except IndexerUnavailable as error: + logger.warning("could not connect to TheTvdb.com, with reason '%r'", error) + except Exception as error: + logger.warning("could not connect to TheTvdb.com, with reason '%r'", error) # If we got this far, it means we hit an exception, and we want to switch to the plex fallback. session.api_client.host = fallback_config['api_base_url'] = app.FALLBACK_PLEX_API_URL diff --git a/medusa/indexers/tvdbv2/tvdbv2_api.py b/medusa/indexers/tvdbv2/tvdbv2_api.py index 2d93703bdb..eb9d4e4b4e 100644 --- a/medusa/indexers/tvdbv2/tvdbv2_api.py +++ b/medusa/indexers/tvdbv2/tvdbv2_api.py @@ -301,8 +301,8 @@ def _query_series(self, tvdb_id, specials=False, aired_season=None, full_info=Fa 'could not get any episodes. Did a {search_type} search. Exception: {e}'.format (search_type='full' if not aired_season else 'season {season}'.format(season=aired_season), e=e.reason) ) - except RequestException as e: - raise IndexerUnavailable('Error connecting to Tvdb api. Caused by: {e}'.format(e=e.message)) + except RequestException as error: + raise IndexerUnavailable('Error connecting to Tvdb api. Caused by: {error!r}'.format(error=error)) if not results: log.debug('Series results incomplete') @@ -455,7 +455,7 @@ def _parse_images(self, sid): sid, accept_language=self.config['language'] ) except (ApiException, RequestException) as error: - log.info('Could not get image count for show id: {0} with reason: {1!r}', sid, error.message) + log.info('Could not get image count for show id: {0} with reason: {1!r}', sid, error) return for image_type, image_count in viewitems(self._object_to_dict(series_images_count)): diff --git a/medusa/init/__init__.py b/medusa/init/__init__.py index 6d056b427f..434da9b779 100644 --- a/medusa/init/__init__.py +++ b/medusa/init/__init__.py @@ -18,7 +18,9 @@ def initialize(): """Initialize all fixes and workarounds.""" _check_python_version() _configure_syspath() - _monkey_patch_fs_functions() + # Not working in python3, maybe it's not necessary anymore + if sys.version_info[0] == 2: + _monkey_patch_fs_functions() _monkey_patch_logging_functions() _early_basic_logging() _register_utf8_codec() @@ -26,7 +28,9 @@ def initialize(): _configure_mimetypes() _handle_old_tornado() _unload_system_dogpile() - _use_shutil_custom() + # Not working in python3, maybe it's not necessary anymore + if sys.version_info[0] == 2: + _use_shutil_custom() _urllib3_disable_warnings() _strptime_workaround() _monkey_patch_bdecode() diff --git a/medusa/init/filesystem.py b/medusa/init/filesystem.py index f85d4fdcdf..251ba95f10 100644 --- a/medusa/init/filesystem.py +++ b/medusa/init/filesystem.py @@ -127,7 +127,7 @@ def initialize(): return affected_functions = { - certifi: ['where', 'old_where'], + certifi: ['where'], glob: ['glob'], io: ['open'], os: ['access', 'chdir', 'listdir', 'makedirs', 'mkdir', 'remove', diff --git a/medusa/init/logconfig.py b/medusa/init/logconfig.py index 28e65f4fb5..5e6b11434a 100644 --- a/medusa/init/logconfig.py +++ b/medusa/init/logconfig.py @@ -4,7 +4,11 @@ import logging from builtins import object -from inspect import getargspec + +try: + from inspect import getfullargspec +except ImportError: + from inspect import getargspec as getfullargspec from six import text_type @@ -15,7 +19,7 @@ class StyleAdapter(logging.LoggerAdapter): adapter_members = {attr: attr for attr in dir(logging.LoggerAdapter) if not callable(attr) and not attr.startswith('__')} adapter_members.update({'warn': 'warning', 'fatal': 'critical'}) - reserved_keywords = getargspec(logging.Logger._log).args[1:] + reserved_keywords = getfullargspec(logging.Logger._log).args[1:] def __init__(self, target_logger, extra=None): """Constructor. diff --git a/medusa/logger/__init__.py b/medusa/logger/__init__.py index c08302b356..114f6ed37a 100644 --- a/medusa/logger/__init__.py +++ b/medusa/logger/__init__.py @@ -68,7 +68,6 @@ } FORMATTER_PATTERN = '%(asctime)s %(levelname)-8s %(threadName)s :: [%(curhash)s] %(message)s' -default_encoding = 'utf-8' censored_items = {} censored = [] @@ -80,7 +79,9 @@ def rebuild_censored_list(): for value in itervalues(censored_items): if not value: continue - if isinstance(value, collections.Iterable) and not isinstance(value, string_types): + + if isinstance(value, collections.Iterable) and not isinstance( + value, (string_types, bytes, bytearray)): for item in value: if item and item != '0': results.add(item) @@ -90,13 +91,13 @@ def rebuild_censored_list(): def quote_unicode(value): """Quote a unicode value by encoding it to bytes first.""" if isinstance(value, text_type): - return quote(value.encode(default_encoding, 'replace')) + return quote(value.encode('utf-8', 'replace')) return quote(value) # set of censored items and urlencoded counterparts results |= {quote_unicode(item) for item in results} # convert set items to unicode and typecast to list - results = list({item.decode(default_encoding, 'replace') + results = list({item.decode('utf-8', 'replace') if not isinstance(item, text_type) else item for item in results}) # sort the list in order of descending length so that entire item is censored # e.g. password and password_1 both get censored instead of getting ********_1 @@ -202,53 +203,88 @@ def read_loglines(log_file=None, modification_time=None, start_index=0, max_line yield formatter(logline) -def reverse_readlines(filename, buf_size=2097152, encoding=default_encoding): - """A generator that returns the lines of a file in reverse order. +def blocks_r(filename, size=64 * 1024, reset_offset=True): + """ + Yields the data within a file in reverse-ordered blocks of given size. - Thanks to Andomar: http://stackoverflow.com/a/23646049 + This code is part of the flyingcircus package: https://pypi.org/project/flyingcircus/ + The code was adapted for our use case. + All credits go to the original author. + + Note that: + - the content of the block is NOT reversed. + + Args: + filename (str): The input file name. + size (int|None): The block size. + If int, the file is yielded in blocks of the specified size. + If None, the file is yielded at once. + reset_offset (bool): Reset the file offset. + If True, starts reading from the end of the file. + Otherwise, starts reading from where the file current position is. + + Yields: + block (bytes): The data within the blocks. - :param filename: - :type filename: str - :param encoding: - :type encoding: str - :param buf_size: - :return: - :rtype: collections.Iterable of str """ - new_line = '\n' - with io.open(filename, 'rb') as fh: - segment = None + with io.open(filename, 'rb') as file_obj: offset = 0 - fh.seek(0, os.SEEK_END) - file_size = remaining_size = fh.tell() + if reset_offset: + file_size = remaining_size = file_obj.seek(0, os.SEEK_END) + else: + file_size = remaining_size = file_obj.tell() + rounding = 0 while remaining_size > 0: - offset = min(file_size, offset + buf_size) - fh.seek(file_size - offset) - buf = fh.read(min(remaining_size, buf_size)) - if os.name == 'nt': - buf = buf.decode(encoding, errors='replace') - if not isinstance(buf, text_type): - buf = text_type(buf, errors='replace') - remaining_size -= buf_size - lines = buf.split(new_line) - # the first line of the buffer is probably not a complete line so - # we'll save it and append it to the last line of the next buffer - # we read - if segment is not None: - # if the previous chunk starts right from the beginning of line - # do not concact the segment to the last line of new chunk - # instead, yield the segment first - if buf[-1] is not new_line: - lines[-1] += segment - else: - yield segment - segment = lines[0] - for index in range(len(lines) - 1, 0, -1): - if len(lines[index]): - yield lines[index] - # Don't yield None if the file was empty - if segment is not None: - yield segment + offset = min(file_size, offset + size) + file_obj.seek(file_size - offset) + block = file_obj.read(min(remaining_size, size)) + remaining_size -= size + yield block[:len(block) + rounding] if rounding else block + + +def reverse_readlines(filename, skip_empty=True, append_newline=False, block_size=512 * 1024, + reset_offset=True, encoding='utf-8'): + """ + Flexible function for reversing read lines incrementally. + + This code is part of the flyingcircus package: https://pypi.org/project/flyingcircus/ + The code was adapted for our use case. + All credits go to the original author. + + Args: + filename (str): The input file name. + skip_empty (bool): Skip empty lines. + append_newline (bool): + block_size (int|None): The block size. + If int, the file is processed in blocks of the specified size. + If None, the file is processed at once. + reset_offset (bool): Reset the file offset. + If True, starts reading from the end of the file. + Otherwise, starts reading from where the file current position is. + encoding (str|None): The encoding for correct block size computation. + If `str`, must be a valid string encoding. + If None, the default encoding is used. + + Yields: + line (str): The next line. + + """ + newline = '\n' + empty = '' + remainder = empty + block_generator_kws = dict(size=block_size, reset_offset=reset_offset) + block_generator = blocks_r + for block in block_generator(filename, **block_generator_kws): + lines = block.decode(encoding).split(newline) + if remainder: + lines[-1] = lines[-1] + remainder + remainder = lines[0] + mask = slice(-1, 0, -1) + for line in lines[mask]: + if line or not skip_empty: + yield line + (newline if append_newline else empty) + if remainder or not skip_empty: + yield remainder + (newline if append_newline else empty) def filter_logline(logline, min_level=None, thread_name=None, search_query=None): @@ -539,7 +575,7 @@ class CensoredFormatter(logging.Formatter, object): # Needed because Newznab apikey isn't stored as key=value in a section. apikey_re = re.compile(r'(?P[&?]r|[&?]apikey|[&?]api_key)(?:=|%3D)([^&]*)(?P[&\w]?)', re.IGNORECASE) - def __init__(self, fmt=None, datefmt=None, encoding=default_encoding): + def __init__(self, fmt=None, datefmt=None, encoding='utf-8'): """Constructor.""" super(CensoredFormatter, self).__init__(fmt, datefmt) self.encoding = encoding @@ -647,7 +683,7 @@ def reconfigure_file_handler(self): target_size = int(app.LOG_SIZE * 1024 * 1024) target_number = int(app.LOG_NR) if not self.file_handler or self.log_file != target_file or self.file_handler.backupCount != target_number or self.file_handler.maxBytes != target_size: - file_handler = RotatingFileHandler(target_file, maxBytes=target_size, backupCount=target_number, encoding=default_encoding) + file_handler = RotatingFileHandler(target_file, maxBytes=target_size, backupCount=target_number, encoding='utf-8') file_handler.setFormatter(CensoredFormatter(FORMATTER_PATTERN, dateTimeFormat)) file_handler.setLevel(self.log_level) diff --git a/medusa/metadata/generic.py b/medusa/metadata/generic.py index 7c232f64ee..8133c428d4 100644 --- a/medusa/metadata/generic.py +++ b/medusa/metadata/generic.py @@ -165,19 +165,19 @@ def _has_season_all_banner(self, show_obj): return self._check_exists(self.get_season_all_banner_path(show_obj)) def get_show_file_path(self, show_obj): - return os.path.join(show_obj.location, self._show_metadata_filename) + return os.path.join(show_obj.validate_location, self._show_metadata_filename) def get_episode_file_path(self, ep_obj): return replace_extension(ep_obj.location, self._ep_nfo_extension) def get_fanart_path(self, show_obj): - return os.path.join(show_obj.location, self.fanart_name) + return os.path.join(show_obj.validate_location, self.fanart_name) def get_poster_path(self, show_obj): - return os.path.join(show_obj.location, self.poster_name) + return os.path.join(show_obj.validate_location, self.poster_name) def get_banner_path(self, show_obj): - return os.path.join(show_obj.location, self.banner_name) + return os.path.join(show_obj.validate_location, self.banner_name) def get_image_path(self, show_obj, image_type): """Based on the image_type (banner, poster, fanart) call the correct method, and return the path.""" @@ -224,7 +224,7 @@ def get_season_poster_path(show_obj, season): else: season_poster_filename = u'season' + str(season).zfill(2) - return os.path.join(show_obj.location, season_poster_filename + u'-poster.jpg') + return os.path.join(show_obj.validate_location, season_poster_filename + u'-poster.jpg') @staticmethod def get_season_banner_path(show_obj, season): @@ -241,13 +241,13 @@ def get_season_banner_path(show_obj, season): else: season_banner_filename = u'season' + str(season).zfill(2) - return os.path.join(show_obj.location, season_banner_filename + u'-banner.jpg') + return os.path.join(show_obj.validate_location, season_banner_filename + u'-banner.jpg') def get_season_all_poster_path(self, show_obj): - return os.path.join(show_obj.location, self.season_all_poster_name) + return os.path.join(show_obj.validate_location, self.season_all_poster_name) def get_season_all_banner_path(self, show_obj): - return os.path.join(show_obj.location, self.season_all_banner_name) + return os.path.join(show_obj.validate_location, self.season_all_banner_name) # pylint: disable=unused-argument,no-self-use def _show_data(self, show_obj): @@ -424,7 +424,7 @@ def _get_episode_thumb_url(self, indexer_series, episode): try: indexer_episode = indexer_series[ep.season][ep.episode] except (IndexerEpisodeNotFound, IndexerSeasonNotFound) as error: - log.debug(u'Unable to find season or episode. Reason: {0!r}', error.message) + log.debug(u'Unable to find season or episode. Reason: {0!r}', error) continue thumb_url = getattr(indexer_episode, 'filename', None) diff --git a/medusa/metadata/kodi.py b/medusa/metadata/kodi.py index 9605643636..fd920f229a 100644 --- a/medusa/metadata/kodi.py +++ b/medusa/metadata/kodi.py @@ -104,7 +104,7 @@ def get_season_poster_path(show_obj, season): else: season_poster_filename = 'season' + text_type(season).zfill(2) - return os.path.join(show_obj.location, season_poster_filename + '.tbn') + return os.path.join(show_obj.validate_location, season_poster_filename + '.tbn') # present a standard "interface" from the module diff --git a/medusa/metadata/media_browser.py b/medusa/metadata/media_browser.py index abf23e90b5..8df7f905fc 100644 --- a/medusa/metadata/media_browser.py +++ b/medusa/metadata/media_browser.py @@ -138,10 +138,10 @@ def get_season_poster_path(show_obj, season): If no season folder exists, None is returned """ - dir_list = [x for x in os.listdir(show_obj.location) if - os.path.isdir(os.path.join(show_obj.location, x))] + dir_list = [x for x in os.listdir(show_obj.validate_location) if + os.path.isdir(os.path.join(show_obj.validate_location, x))] - season_dir_regex = ur'^Season\s+(\d+)$' + season_dir_regex = r'^Season\s+(\d+)$' season_dir = None @@ -170,7 +170,7 @@ def get_season_poster_path(show_obj, season): log.debug(u'Using {path}/folder.jpg as season directory for season {number}', {u'path': season_dir, u'number': season}) - return os.path.join(show_obj.location, season_dir, u'folder.jpg') + return os.path.join(show_obj.validate_location, season_dir, u'folder.jpg') @staticmethod def get_season_banner_path(show_obj, season): @@ -180,10 +180,10 @@ def get_season_banner_path(show_obj, season): If no season folder exists, None is returned """ - dir_list = [x for x in os.listdir(show_obj.location) if - os.path.isdir(os.path.join(show_obj.location, x))] + dir_list = [x for x in os.listdir(show_obj.validate_location) if + os.path.isdir(os.path.join(show_obj.validate_location, x))] - season_dir_regex = ur'^Season\s+(\d+)$' + season_dir_regex = r'^Season\s+(\d+)$' season_dir = None @@ -212,7 +212,7 @@ def get_season_banner_path(show_obj, season): log.debug(u'Using {path}/banner.jpg as season directory for season {number}', {u'path': season_dir, u'number': season}) - return os.path.join(show_obj.location, season_dir, u'banner.jpg') + return os.path.join(show_obj.validate_location, season_dir, u'banner.jpg') def _show_data(self, show_obj): """ diff --git a/medusa/metadata/wdtv.py b/medusa/metadata/wdtv.py index 3f3c03fa90..c17feac597 100644 --- a/medusa/metadata/wdtv.py +++ b/medusa/metadata/wdtv.py @@ -130,8 +130,8 @@ def get_season_poster_path(show_obj, season): If no season folder exists, None is returned """ - dir_list = [x for x in os.listdir(show_obj.location) if - os.path.isdir(os.path.join(show_obj.location, x))] + dir_list = [x for x in os.listdir(show_obj.validate_location) if + os.path.isdir(os.path.join(show_obj.validate_location, x))] season_dir_regex = r'^Season\s+(\d+)$' @@ -159,7 +159,7 @@ def get_season_poster_path(show_obj, season): log.debug('Using {location}/folder.jpg as season dir for season {number}', {'location': season_dir, 'number': season}) - return os.path.join(show_obj.location, season_dir, 'folder.jpg') + return os.path.join(show_obj.validate_location, season_dir, 'folder.jpg') def _ep_data(self, ep_obj): """ diff --git a/medusa/name_cache.py b/medusa/name_cache.py index 72f4a28cb3..4220c1f1fa 100644 --- a/medusa/name_cache.py +++ b/medusa/name_cache.py @@ -21,7 +21,7 @@ log.logger.addHandler(logging.NullHandler()) name_cache = {} -nameCacheLock = threading.Lock() +name_cache_lock = threading.Lock() def addNameToCache(name, indexer_id=1, series_id=0): @@ -114,7 +114,7 @@ def _cache_name(cache_series_obj): 'names': u', '.join(list(names)) }) - with nameCacheLock: + with name_cache_lock: retrieve_exceptions() # Create cache from db for the scene_exceptions. diff --git a/medusa/name_parser/parser.py b/medusa/name_parser/parser.py index 3c7de74608..7b4cf729f6 100644 --- a/medusa/name_parser/parser.py +++ b/medusa/name_parser/parser.py @@ -132,14 +132,14 @@ def _parse_air_by_date(self, result): episode_numbers = [] except IndexerError as error: log.warning( - 'Unable to contact {indexer_api.name}: {error}', - {'indexer_api': indexer_api, 'error': error.message} + 'Unable to contact {indexer_api.name}: {error!r}', + {'indexer_api': indexer_api, 'error': error} ) episode_numbers = [] except IndexerException as error: log.warning( - 'Indexer exception: {indexer_api.name}: {error}', - {'indexer_api': indexer_api, 'error': error.message} + 'Indexer exception: {indexer_api.name}: {error!r}', + {'indexer_api': indexer_api, 'error': error} ) episode_numbers = [] @@ -198,8 +198,8 @@ def _parse_anime(result): # # Don't assume that scene_exceptions season is the same as indexer season. # E.g.: [HorribleSubs] Cardcaptor Sakura Clear Card - 08 [720p].mkv thetvdb s04, thexem s02 - if result.series.is_scene or (result.season_number is None and - scene_season is not None and scene_season > 0): + if result.series.is_scene or (result.season_number is None + and scene_season is not None and scene_season > 0): a = scene_numbering.get_indexer_absolute_numbering( result.series, absolute_episode, True, scene_season ) @@ -218,8 +218,9 @@ def _parse_anime(result): ) else: log.debug( - 'Scene numbering enabled series {name} using indexer for absolute {absolute}: {ep}', - {'name': result.series.name, 'absolute': a, 'ep': episode_num(season, episode, 'absolute')} + 'Scene numbering enabled series {name} with season {season} using indexer for absolute {absolute}: {ep}', + {'name': result.series.name, 'season': season, 'absolute': a, + 'ep': episode_num(season, episode, 'absolute')} ) new_absolute_numbers.append(a) @@ -300,10 +301,12 @@ def _parse_string(self, name): elif result.season_number and result.episode_numbers: new_episode_numbers, new_season_numbers, new_absolute_numbers = self._parse_series(result) + # Remove None from the list of seasons, as we can't sort on that + new_season_numbers = sorted({season for season in new_season_numbers if season is not None}) + # need to do a quick sanity check here ex. It's possible that we now have episodes # from more than one season (by tvdb numbering), and this is just too much # for the application, so we'd need to flag it. - new_season_numbers = sorted(set(new_season_numbers)) # remove duplicates if len(new_season_numbers) > 1: raise InvalidNameException('Scene numbering results episodes from seasons {seasons}, (i.e. more than one) ' 'and Medusa does not support this. Sorry.'.format(seasons=new_season_numbers)) @@ -413,9 +416,18 @@ def to_parse_result(self, name, guess): :return: :rtype: ParseResult """ - season_numbers = helpers.ensure_list(guess.get('season')) - if len(season_numbers) > 1 and not self.allow_multi_season: - raise InvalidNameException("Discarding result. Multi-season detected for '{name}': {guess}".format(name=name, guess=guess)) + if not self.allow_multi_season: + season_numbers = helpers.ensure_list(guess.get('season')) + if len(season_numbers) > 1: + raise InvalidNameException( + "Discarding result. Multi-season detected for '{name}': {guess}" + .format(name=name, guess=guess)) + + versions = helpers.ensure_list(guess.get('version')) + if len(versions) > 1: + raise InvalidNameException( + "Discarding result. Multi-version detected for '{name}': {guess}" + .format(name=name, guess=guess)) return ParseResult(guess, original_name=name, series_name=guess.get('alias') or guess.get('title'), season_number=helpers.single_or_list(season_numbers, self.allow_multi_season), @@ -590,10 +602,14 @@ def remove(self, indexer, indexer_id): """Remove cache item given indexer and indexer_id.""" if not indexer or not indexer_id: return - to_remove = (cached_name for cached_name, cached_parsed_result in iteritems(self.cache) if - cached_parsed_result.series.indexer == indexer and cached_parsed_result.series.indexerid == indexer_id) + to_remove = [ + cached_name + for cached_name, cached_parsed_result in iteritems(self.cache) + if cached_parsed_result.series.indexer == indexer + and cached_parsed_result.series.indexerid == indexer_id + ] for item in to_remove: - self.cache.popitem(item) + del self.cache[item] log.debug('Removed parsed cached result for release: {release}'.format(release=item)) diff --git a/medusa/name_parser/rules/properties.py b/medusa/name_parser/rules/properties.py index c5063df4a6..56a4bd6f86 100644 --- a/medusa/name_parser/rules/properties.py +++ b/medusa/name_parser/rules/properties.py @@ -14,6 +14,8 @@ from rebulk.rebulk import Rebulk from rebulk.rules import RemoveMatch, Rule +import six + def blacklist(): """Blacklisted patterns. @@ -107,7 +109,10 @@ def container(): other.name == 'container' and 'extension' not in other.tags else '__default__') - nzb = [b'nzb'] + if six.PY3: + nzb = ['nzb'] + else: + nzb = [b'nzb'] rebulk.regex(r'\.' + build_or_pattern(nzb) + '$', exts=nzb, tags=['extension', 'torrent']) diff --git a/medusa/name_parser/rules/rules.py b/medusa/name_parser/rules/rules.py index a69ba7f44a..83e7750479 100644 --- a/medusa/name_parser/rules/rules.py +++ b/medusa/name_parser/rules/rules.py @@ -694,7 +694,7 @@ def when(self, matches, context): index=0, predicate=lambda match: match.name == 'episode_title' and match.value.isdigit(), ) - if episode_title: + if episode_title and to_append: if matches.input_string[episode.end:episode_title.start + 1] in range_separator: end_value = int(episode_title.value) for i in range(absolute_episode.value + 1, end_value + 1): @@ -923,116 +923,6 @@ def when(self, matches, context): return to_remove -class FixWordAsLanguage(Rule): - """Fix word getting parsed as language with multiple fileparts. - - Related bug report: https://github.com/guessit-io/guessit/issues/578 - - e.g.: Por Trece Razones - Temporada 2 [HDTV 720p][Cap.201][AC3 5.1 Castellano]/Por Trece Razones 2x01 [des202].mkv - - without the rule: - GuessIt found: { - "language": [ - "Portuguese", - "Catalan" - ], - "title": "Trece Razones", - "season": 2, - "source": "HDTV", - "screen_size": "720p", - "episode": 1, - "audio_codec": "Dolby Digital", - "audio_channels": "5.1", - "release_group": "des202", - "container": "mkv", - "mimetype": "video/x-matroska", - "type": "episode" - } - - with the rule: - GuessIt found: { - "language": "Catalan", - "title": "Por Trece Razones", - "season": 2, - "source": "HDTV", - "screen_size": "720p", - "episode": 1, - "audio_codec": "Dolby Digital", - "audio_channels": "5.1", - "release_group": "des202", - "container": "mkv", - "mimetype": "video/x-matroska", - "type": "episode" - } - """ - - priority = POST_PROCESS - consequence = [RemoveMatch, AppendMatch] - - def when(self, matches, context): - """Evaluate the rule. - - :param matches: - :type matches: rebulk.match.Matches - :param context: - :type context: dict - :return: - """ - languages = matches.named('language') - if not languages: - return - - fileparts = matches.markers.named('path') - parts_len = len(fileparts) - if parts_len < 2: - return - - titles = matches.named('title') - if not titles: - return - - first_title = titles[0] - last_title = titles[-1] - - # Always use the first language - first_language = languages[0] - for language in languages[1:]: - if language.start < first_language.start: - first_language = language - - lang_start = first_language.start - lang_end = first_language.end - - start = end = None - # Language is before titles - if lang_end == first_title.start: - start = lang_start - end = last_title.end - # Language is after titles - elif last_title.end == lang_start: - start = first_title.start - end = lang_end - # Language is between titles - elif len(titles) > 1: - lang_code = last_title.value.split()[0].lower() - if lang_code in context.get('allowed_languages', []): - start = first_title.start - end = last_title.end - - if start is not None: - second_filepart = fileparts[parts_len - 2] - rel_start = start - second_filepart.start - rel_end = end - second_filepart.end - - new_title = second_filepart.value[rel_start:rel_end] - titles[0].value = cleanup(new_title) - - to_append = titles[0] - to_remove = first_language - - return to_remove, to_append - - class FixParentFolderReplacingTitle(Rule): """Fix folder name replacing title when it ends with digits. @@ -1095,7 +985,7 @@ def when(self, matches, context): if second_part.startswith(title[0].value): season = matches.named('season') - if season and not second_part.endswith(season[-1].initiator.value): + if season and not second_part.endswith(str(season[-1].initiator.value)): episode_title[0].name = 'title' to_append = episode_title to_remove = title @@ -1498,7 +1388,6 @@ def rules(): CreateAliasWithCountryOrYear, ReleaseGroupPostProcessor, FixParentFolderReplacingTitle, - FixWordAsLanguage, FixMultipleSources, AudioCodecStandardizer, SourceStandardizer, diff --git a/medusa/naming.py b/medusa/naming.py index 0df64be754..eb3505ce73 100644 --- a/medusa/naming.py +++ b/medusa/naming.py @@ -15,17 +15,17 @@ # # You should have received a copy of the GNU General Public License # along with Medusa. If not, see . - from __future__ import unicode_literals import datetime import os -from builtins import object from builtins import str -from medusa import app, common, logger, tv +from medusa import app, logger from medusa.common import DOWNLOADED, Quality from medusa.name_parser.parser import InvalidNameException, InvalidShowException, NameParser +from medusa.tv import Episode, Series + name_presets = ( '%SN - %Sx%0E - %EN', @@ -50,66 +50,6 @@ ) -class TVShow(object): # pylint: disable=too-few-public-methods - def __init__(self): - self.name = 'Show Name' - self.genre = 'Comedy' - self.indexerid = 1 - self.air_by_date = 0 - self.sports = 0 - self.anime = 0 - self.scene = 0 - - @property - def series_id(self): - """To make a clear distinction between an indexer and the id for the series. You can now also use series_id.""" - return self.indexerid - - def _is_anime(self): - """ - Find out if show is anime - :return: True if show is anime, False if not - """ - return bool(self.anime) - - is_anime = property(_is_anime) - - def _is_sports(self): - """ - Find out if show is sports - :return: True if show is sports, False if not - """ - return bool(self.sports) - - is_sports = property(_is_sports) - - def _is_scene(self): - """ - Find out if show is scene numbering - :return: True if show is scene numbering, False if not - """ - return bool(self.scene) - - is_scene = property(_is_scene) - - -class TVEpisode(tv.Episode): # pylint: disable=too-many-instance-attributes - def __init__(self, season, episode, absolute_number, name): # pylint: disable=super-init-not-called - super(TVEpisode, self).__init__(None, season, episode) - self.related_episodes = [] - self.name = name - self.absolute_number = absolute_number - self.scene_season = season - self.scene_episode = episode - self.scene_absolute_number = absolute_number - self.airdate = datetime.date(2010, 3, 9) - self.status = common.DOWNLOADED - self.quality = common.Quality.SDTV - self.release_name = 'Show.Name.S02E03.HDTV.x264-RLSGROUP' - self.is_proper = True - self.series = TVShow() - - def check_force_season_folders(pattern=None, multi=None, anime_type=None): """ Checks if the name can still be parsed if you strip off the folders to determine if we need to force season folders @@ -183,8 +123,7 @@ def check_valid_sports_naming(pattern=None): return valid -def validate_name(pattern, multi=None, anime_type=None, # pylint: disable=too-many-arguments, too-many-return-statements - file_only=False, abd=False, sports=False): +def validate_name(pattern, multi=None, anime_type=None, file_only=False, abd=False, sports=False): """ See if we understand a name @@ -238,13 +177,22 @@ def validate_name(pattern, multi=None, anime_type=None, # pylint: disable=too-m def generate_sample_ep(multi=None, abd=False, sports=False, anime_type=None): + series = Series(indexer=1, indexerid=12345, lang='en') + series.name = 'Show Name' + series.genre = 'Comedy' + if anime_type: + series.anime = 1 + # make a fake episode object - ep = TVEpisode(2, 3, 3, 'Ep Name') + ep = Episode(series=series, season=2, episode=3) - # pylint: disable=protected-access ep.status = DOWNLOADED ep.quality = Quality.HDTV ep.airdate = datetime.date(2011, 3, 9) + ep.name = 'Ep Name' + ep.absolute_number = 13 + ep.release_name = 'Show.Name.S02E03.HDTV.x264-RLSGROUP' + ep.is_proper = True if abd: ep.release_name = 'Show.Name.2011.03.09.HDTV.x264-RLSGROUP' @@ -252,42 +200,31 @@ def generate_sample_ep(multi=None, abd=False, sports=False, anime_type=None): elif sports: ep.release_name = 'Show.Name.2011.03.09.HDTV.x264-RLSGROUP' ep.series.sports = 1 - else: - if anime_type != 3: - ep.series.anime = 1 - ep.release_name = 'Show.Name.003.HDTV.x264-RLSGROUP' - else: - ep.release_name = 'Show.Name.S02E03.HDTV.x264-RLSGROUP' + elif anime_type: + ep.release_name = 'Show.Name.013.HDTV.x264-RLSGROUP' if multi is not None: ep.name = 'Ep Name (1)' - - if anime_type != 3: - ep.series.anime = 1 - - ep.release_name = 'Show.Name.003-004.HDTV.x264-RLSGROUP' - - secondEp = TVEpisode(2, 4, 4, 'Ep Name (2)') - secondEp.status = DOWNLOADED - secondEp.quality = Quality.HDTV - secondEp.release_name = ep.release_name - - ep.related_episodes.append(secondEp) - else: - ep.release_name = 'Show.Name.S02E03E04E05.HDTV.x264-RLSGROUP' - - secondEp = TVEpisode(2, 4, 4, 'Ep Name (2)') - secondEp.status = DOWNLOADED - secondEp.quality = Quality.HDTV - secondEp.release_name = ep.release_name - - thirdEp = TVEpisode(2, 5, 5, 'Ep Name (3)') - thirdEp.status = DOWNLOADED - thirdEp.quality = Quality.HDTV - thirdEp.release_name = ep.release_name - - ep.related_episodes.append(secondEp) - ep.related_episodes.append(thirdEp) + ep.release_name = 'Show.Name.S02E03E04E05.HDTV.x264-RLSGROUP' + if anime_type: + ep.release_name = 'Show.Name.013-015.HDTV.x264-RLSGROUP' + + second_ep = Episode(series, 2, 4) + second_ep.name = 'Ep Name (2)' + second_ep.status = DOWNLOADED + second_ep.quality = Quality.HDTV + second_ep.absolute_number = 14 + second_ep.release_name = ep.release_name + + third_ep = Episode(series, 2, 5) + third_ep.name = 'Ep Name (3)' + third_ep.status = DOWNLOADED + third_ep.quality = Quality.HDTV + third_ep.absolute_number = 15 + third_ep.release_name = ep.release_name + + ep.related_episodes.append(second_ep) + ep.related_episodes.append(third_ep) return ep diff --git a/medusa/notifiers/__init__.py b/medusa/notifiers/__init__.py index 56d845f118..417614734f 100644 --- a/medusa/notifiers/__init__.py +++ b/medusa/notifiers/__init__.py @@ -99,7 +99,7 @@ def notify_download(ep_obj): try: n.notify_download(ep_obj) except (RequestException, socket.gaierror, socket.timeout) as error: - log.debug(u'Unable to send download notification. Error: {0}', error.message) + log.debug(u'Unable to send download notification. Error: {0!r}', error) def notify_subtitle_download(ep_obj, lang): @@ -107,7 +107,7 @@ def notify_subtitle_download(ep_obj, lang): try: n.notify_subtitle_download(ep_obj, lang) except (RequestException, socket.gaierror, socket.timeout) as error: - log.debug(u'Unable to send subtitle download notification. Error: {0}', error.message) + log.debug(u'Unable to send subtitle download notification. Error: {0!r}', error) def notify_snatch(ep_obj, result): @@ -115,10 +115,10 @@ def notify_snatch(ep_obj, result): is_proper = bool(result.proper_tags) title = notifyStrings[(NOTIFY_SNATCH, NOTIFY_SNATCH_PROPER)[is_proper]] - if all([app.SEEDERS_LEECHERS_IN_NOTIFY, result.seeders not in (-1, None), - result.leechers not in (-1, None)]): - message = u'{0} with {1} seeders and {2} leechers from {3}'.format( - ep_name, result.seeders, result.leechers, result.provider.name) + has_peers = result.seeders not in (-1, None) and result.leechers not in (-1, None) + if app.SEEDERS_LEECHERS_IN_NOTIFY and has_peers: + message = u'{0} with {1} seeders and {2} leechers from {3}'.format( + ep_name, result.seeders, result.leechers, result.provider.name) else: message = u'{0} from {1}'.format(ep_name, result.provider.name) @@ -126,7 +126,7 @@ def notify_snatch(ep_obj, result): try: n.notify_snatch(title, message) except (RequestException, socket.gaierror, socket.timeout) as error: - log.debug(u'Unable to send snatch notification. Error: {0}', error.message) + log.debug(u'Unable to send snatch notification. Error: {0!r}', error) def notify_git_update(new_version=''): @@ -135,7 +135,7 @@ def notify_git_update(new_version=''): try: n.notify_git_update(new_version) except (RequestException, socket.gaierror, socket.timeout) as error: - log.debug(u'Unable to send new update notification. Error: {0}', error.message) + log.debug(u'Unable to send new update notification. Error: {0!r}', error) def notify_login(ipaddress): @@ -144,4 +144,4 @@ def notify_login(ipaddress): try: n.notify_login(ipaddress) except (RequestException, socket.gaierror, socket.timeout) as error: - log.debug(u'Unable to new login notification. Error: {0}', error.message) + log.debug(u'Unable to new login notification. Error: {0!r}', error) diff --git a/medusa/notifiers/emailnotify.py b/medusa/notifiers/emailnotify.py index 110df60ae2..c19180dc96 100644 --- a/medusa/notifiers/emailnotify.py +++ b/medusa/notifiers/emailnotify.py @@ -372,7 +372,7 @@ def _sendmail(self, host, port, smtp_from, use_tls, user, pwd, to, msg, smtp_deb srv.ehlo() if user and pwd: log.debug('Sending LOGIN command!') - srv.login(user.encode('utf-8'), pwd.encode('utf-8')) + srv.login(user, pwd) srv.sendmail(smtp_from, to, msg.as_string()) srv.quit() diff --git a/medusa/notifiers/join.py b/medusa/notifiers/join.py index 88cd9e546e..789e6eb06d 100644 --- a/medusa/notifiers/join.py +++ b/medusa/notifiers/join.py @@ -84,9 +84,9 @@ def _sendjoin(self, title, message, join_api=None, join_device=None, force=False join_device = join_device or app.JOIN_DEVICE icon_url = 'https://cdn.pymedusa.com/images/ico/favicon-310.png' - post_data = {'title': title, 'text': message, 'deviceId': join_device, 'apikey': join_api, 'icon': icon_url} + params = {'title': title, 'text': message, 'deviceId': join_device, 'apikey': join_api, 'icon': icon_url} - r = requests.get(self.url, params=post_data) + r = requests.get(self.url, params=params) try: response = r.json() except ValueError: @@ -96,8 +96,8 @@ def _sendjoin(self, title, message, join_api=None, join_device=None, force=False failed = response.pop('errorMessage', {}) if failed: - log.warning('Join notification failed: {0}', failed.get('message')) - push_result['error'] = 'Join notification failed: {0}'.format(failed.get('message')) + log.warning('Join notification failed: {0}', failed) + push_result['error'] = 'Join notification failed: {0}'.format(failed) else: log.debug('Join notification sent.') push_result['success'] = True diff --git a/medusa/notifiers/kodi.py b/medusa/notifiers/kodi.py index 2ebe5056d9..5efb58517c 100644 --- a/medusa/notifiers/kodi.py +++ b/medusa/notifiers/kodi.py @@ -61,6 +61,8 @@ def _get_kodi_version(self, host, username, password, dest_app='KODI'): result = self._send_to_kodi(check_command, host, username, password, dest_app) if result and 'error' not in result: + if isinstance(result['result']['version'], dict): + return result['result']['version'].get('major') return result['result']['version'] else: return False @@ -103,11 +105,11 @@ def _notify_kodi(self, title, message, host=None, username=None, password=None, return False result = '' - for curHost in [x.strip() for x in host if x.strip()]: + for cur_host in [x.strip() for x in host if x.strip()]: log.debug(u'Sending {app} notification to {host} - {msg}', - {'app': dest_app, 'host': curHost, 'msg': message}) + {'app': dest_app, 'host': cur_host, 'msg': message}) - kodi_api = self._get_kodi_version(curHost, username, password, dest_app) + kodi_api = self._get_kodi_version(cur_host, username, password, dest_app) if kodi_api: if kodi_api <= 4: log.warning(u'Detected {app} version <= 11, this version is not supported by Medusa. ' @@ -126,17 +128,17 @@ def _notify_kodi(self, title, message, host=None, username=None, password=None, }, 'id': '1', } - notify_result = self._send_to_kodi(command, curHost, username, password, dest_app) - if notify_result and notify_result.get('result'): # pylint: disable=no-member - result += curHost + ':' + notify_result['result'].decode(app.SYS_ENCODING) + notify_result = self._send_to_kodi(command, cur_host, username, password, dest_app) + if notify_result and notify_result.get('result'): + result += cur_host + ':' + notify_result['result'].decode('utf-8') else: if app.KODI_ALWAYS_ON or force: log.warning( u'Failed to detect {app} version for {host},' u' check configuration and try again.', - {'app': dest_app, 'host': curHost} + {'app': dest_app, 'host': cur_host} ) - result += curHost + ':False' + result += cur_host + ':False' return result diff --git a/medusa/notifiers/pytivo.py b/medusa/notifiers/pytivo.py index 498c16fdaf..0f6d439c4f 100644 --- a/medusa/notifiers/pytivo.py +++ b/medusa/notifiers/pytivo.py @@ -7,13 +7,10 @@ from builtins import object from medusa import app -from medusa.helper.exceptions import ex from medusa.logger.adapters.style import BraceAdapter -from requests.compat import urlencode - -from six.moves.urllib.error import HTTPError -from six.moves.urllib.request import Request, urlopen +import requests +from requests.exceptions import RequestException log = BraceAdapter(logging.getLogger(__name__)) log.logger.addHandler(logging.NullHandler()) @@ -75,24 +72,23 @@ def update_library(self, ep_obj): filename = '/' + absPath.replace(root, '') # Finally create the url and make request - requestUrl = 'http://' + host + '/TiVoConnect?' + urlencode( - {'Command': 'Push', 'Container': container, 'File': filename, 'tsn': tsn}) - - log.debug(u'pyTivo notification: Requesting {0}', requestUrl) + request_url = 'http://{host}/TiVoConnect'.format(host=host) + params = {'Command': 'Push', 'Container': container, 'File': filename, 'tsn': tsn} - request = Request(requestUrl) + log.debug(u'pyTivo notification: Requesting {0}', request_url) try: - urlopen(request) - except HTTPError as e: - if hasattr(e, 'reason'): - log.error(u'pyTivo notification: Error, failed to reach a server - {0}', e.reason) + r = requests.get(request_url, params=params) + r.raise_for_status() + except RequestException as error: + if hasattr(error, 'response'): + if hasattr(error.response, 'reason'): + log.error(u'pyTivo notification: Error, failed to reach a server - {0}', error.response.reason) + elif hasattr(error.response, 'status_code'): + log.error(u'pyTivo notification: Error, the server could not fulfill the request - {0}', error.response.status_code) return False - elif hasattr(e, 'code'): - log.error(u'pyTivo notification: Error, the server could not fulfill the request - {0}', e.code) - return False - except Exception as e: - log.error(u'PYTIVO: Unknown exception: {0}', ex(e)) + except Exception as error: + log.error(u'PYTIVO: Unknown exception: {0!r}', error) return False else: log.info(u'pyTivo notification: Successfully requested transfer of file') diff --git a/medusa/notifiers/telegram.py b/medusa/notifiers/telegram.py index 1243d52963..3aaa83fa12 100644 --- a/medusa/notifiers/telegram.py +++ b/medusa/notifiers/telegram.py @@ -18,9 +18,8 @@ from medusa.helper.common import http_status_code from medusa.logger.adapters.style import BraceAdapter -from requests.compat import urlencode - -from six.moves.urllib.request import Request, urlopen +import requests +from requests.exceptions import RequestException log = BraceAdapter(logging.getLogger(__name__)) log.logger.addHandler(logging.NullHandler()) @@ -58,29 +57,28 @@ def _send_telegram_msg(self, title, msg, user_id=None, api_key=None): log.debug('Telegram in use with API KEY: {0}', api_key) message = '{0} : {1}'.format(title, msg).encode('utf-8') - payload = urlencode({'chat_id': user_id, 'text': message}) - telegram_api = 'https://api.telegram.org/bot%s/%s' - - req = Request(telegram_api % (api_key, 'sendMessage'), payload) + payload = {'chat_id': user_id, 'text': message} + telegram_api = 'https://api.telegram.org/bot{api_key}/sendMessage' success = False try: - urlopen(req) + r = requests.post(telegram_api.format(api_key=api_key), data=payload) + r.raise_for_status() message = 'Telegram message sent successfully.' success = True - except IOError as e: - message = 'Unknown IO error: %s' % e - if hasattr(e, 'code'): + except RequestException as error: + message = 'Unknown IO error: %s' % error + if hasattr(error, 'response') and error.response is not None: error_message = { 400: 'Missing parameter(s). Double check your settings or if the channel/user exists.', 401: 'Authentication failed.', 420: 'Too many messages.', 500: 'Server error. Please retry in a few moments.', } - if e.code in error_message: - message = error_message.get(e.code) + if error.response.status_code in error_message: + message = error_message.get(error.response.status_code) else: - http_status_code.get(e.code, message) + message = http_status_code.get(error.response.status_code, message) except Exception as e: message = 'Error while sending Telegram message: %s ' % e finally: diff --git a/medusa/post_processor.py b/medusa/post_processor.py index c1d4d9cb56..afa47f204e 100644 --- a/medusa/post_processor.py +++ b/medusa/post_processor.py @@ -304,7 +304,7 @@ def _search_files(path, pattern='*', subfolders=False, basename_only=False, sort pattern = new_pattern + pattern files = [] - for root, __, filenames in os.walk(directory): + for root, _, filenames in os.walk(directory): for filename in fnmatch.filter(filenames, pattern): files.append(os.path.join(root, filename)) if not subfolders: @@ -1203,11 +1203,11 @@ def process(self): # find the destination folder try: proper_path = ep_obj.proper_path() - proper_absolute_path = os.path.join(ep_obj.series.location, proper_path) + proper_absolute_path = os.path.join(ep_obj.series.validate_location, proper_path) dest_path = os.path.dirname(proper_absolute_path) except ShowDirectoryNotFoundException: raise EpisodePostProcessingFailedException(u"Unable to post-process an episode if the show dir '{0}' " - u"doesn't exist, quitting".format(ep_obj.series.raw_location)) + u"doesn't exist, quitting".format(ep_obj.series.location)) self.log(u'Destination folder for this episode: {0}'.format(dest_path), logger.DEBUG) diff --git a/medusa/providers/__init__.py b/medusa/providers/__init__.py index c9ea575a0e..4b5868250f 100644 --- a/medusa/providers/__init__.py +++ b/medusa/providers/__init__.py @@ -24,7 +24,6 @@ bitcannon, bithdtv, bjshare, - btdb, btn, cinemaz, danishbits, @@ -33,12 +32,10 @@ hdspace, hdtorrents, hebits, - horriblesubs, iptorrents, limetorrents, morethantv, nebulance, - newpct, norbits, nordicbits, nyaa, @@ -53,7 +50,6 @@ thepiratebay, tntvillage, tokyotoshokan, - torrent9, torrentbytes, torrentday, torrenting, @@ -67,12 +63,12 @@ __all__ = [ 'btn', 'thepiratebay', 'torrentleech', 'hdtorrents', 'torrentday', 'hdbits', - 'speedcd', 'nyaa', 'torrentbytes', 'torrent9', 'morethantv', 'tokyotoshokan', 'iptorrents', + 'speedcd', 'nyaa', 'torrentbytes', 'morethantv', 'tokyotoshokan', 'iptorrents', 'hebits', 'alpharatio', 'sdbits', 'shazbat', 'rarbg', 'tntvillage', 'binsearch', 'xthor', 'abnormal', 'scenetime', 'nebulance', 'tvchaosuk', 'bitcannon', 'torrentz2', 'pretome', 'anizb', - 'hdspace', 'newpct', 'nordicbits', 'danishbits', 'limetorrents', 'norbits', 'bithdtv', - 'zooqle', 'animebytes', 'animetorrents', 'horriblesubs', 'anidex', 'shanaproject', 'torrenting', - 'yggtorrent', 'elitetracker', 'archetorrent', 'privatehd', 'cinemaz', 'avistaz', 'bjshare', 'btdb' + 'hdspace', 'nordicbits', 'danishbits', 'limetorrents', 'norbits', 'bithdtv', + 'zooqle', 'animebytes', 'animetorrents', 'anidex', 'shanaproject', 'torrenting', + 'yggtorrent', 'elitetracker', 'archetorrent', 'privatehd', 'cinemaz', 'avistaz', 'bjshare' ] diff --git a/medusa/providers/generic_provider.py b/medusa/providers/generic_provider.py index 65890cddfb..51c6ae4426 100644 --- a/medusa/providers/generic_provider.py +++ b/medusa/providers/generic_provider.py @@ -334,8 +334,9 @@ def find_search_results(self, series, episodes, search_mode, forced_search=False search_result.result_wanted = True try: - search_result.parsed_result = NameParser(parse_method=('normal', 'anime')[series.is_anime] - ).parse(search_result.name) + search_result.parsed_result = NameParser( + parse_method=('normal', 'anime')[series.is_anime]).parse( + search_result.name) except (InvalidNameException, InvalidShowException) as error: log.debug('Error during parsing of release name: {release_name}, with error: {error}', {'release_name': search_result.name, 'error': error}) diff --git a/medusa/providers/nzb/anizb.py b/medusa/providers/nzb/anizb.py index a5d7fc8f53..51130f3fc6 100644 --- a/medusa/providers/nzb/anizb.py +++ b/medusa/providers/nzb/anizb.py @@ -31,8 +31,7 @@ def __init__(self): # URLs self.url = 'https://anizb.org/' self.urls = { - 'rss': self.url, - 'api': urljoin(self.url, 'api/?q=') + 'search': urljoin(self.url, 'api'), } # Proper Strings @@ -46,59 +45,81 @@ def __init__(self): self.cache = tv.Cache(self) def search(self, search_strings, age=0, ep_obj=None, **kwargs): - """Start searching for anime using the provided search_strings. Used for backlog and daily.""" + """ + Search a provider and parse the results. + + :param search_strings: A dict with mode (key) and the search value (value) + :param age: Not used + :param ep_obj: Not used + :returns: A list of search results (structure) + """ results = [] + # Search Params + search_params = { + 'q': '', + } + for mode in search_strings: - items = [] log.debug('Search mode: {0}', mode) for search_string in search_strings[mode]: - if mode != 'RSS': log.debug('Search string: {search}', {'search': search_string}) + search_params['q'] = search_string - search_url = (self.urls['rss'], self.urls['api'] + search_string)[mode != 'RSS'] - response = self.session.get(search_url) - if not response or not response.text: - log.debug('No data returned from provider') - continue + response = self.session.get(self.urls['search'], params=search_params) + if not response or not response.text: + log.debug('No data returned from provider') + continue + elif not response.text.startswith(' 9 else 0 # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/bjshare.py b/medusa/providers/torrent/html/bjshare.py index 04875e4439..4775704e79 100644 --- a/medusa/providers/torrent/html/bjshare.py +++ b/medusa/providers/torrent/html/bjshare.py @@ -37,10 +37,6 @@ def __init__(self): self.cookies = '' self.required_cookies = ['session'] - # Torrent Stats - self.minseed = None - self.minleech = None - # Miscellaneous Options self.supports_absolute_numbering = True self.max_back_pages = 2 @@ -208,7 +204,7 @@ def process_column_header(td): leechers = try_int(cells[labels.index('Leechers') + group_index].get_text(strip=True)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/btdb.py b/medusa/providers/torrent/html/btdb.py deleted file mode 100644 index 259bc6cfcc..0000000000 --- a/medusa/providers/torrent/html/btdb.py +++ /dev/null @@ -1,157 +0,0 @@ -# coding=utf-8 - -"""Provider code for BTDB.""" - -from __future__ import unicode_literals - -import logging - -from medusa import tv -from medusa.bs4_parser import BS4Parser -from medusa.helper.common import convert_size -from medusa.logger.adapters.style import BraceAdapter -from medusa.providers.torrent.torrent_provider import TorrentProvider - -from requests.compat import urljoin - -log = BraceAdapter(logging.getLogger(__name__)) -log.logger.addHandler(logging.NullHandler()) - - -class BTDBProvider(TorrentProvider): - """BTDB Torrent provider.""" - - def __init__(self): - """Initialize the class.""" - super(BTDBProvider, self).__init__('BTDB') - - # Credentials - self.public = True - - # URLs - self.url = 'https://btdb.to' - self.urls = { - 'daily': urljoin(self.url, '/q/x264/?sort=time'), - 'search': urljoin(self.url, '/q/{query}/{page}?sort=popular'), - } - - # Miscellaneous Options - self.max_pages = 3 - - # Cache - self.cache = tv.Cache(self, min_time=20) - - def search(self, search_strings, age=0, ep_obj=None, **kwargs): - """ - Search a provider and parse the results. - - :param search_strings: A dict with mode (key) and the search value (value) - :param age: Not used - :param ep_obj: Not used - :returns: A list of search results (structure) - """ - results = [] - - for mode in search_strings: - log.debug('Search mode: {0}', mode) - - for search_string in search_strings[mode]: - - if mode != 'RSS': - log.debug('Search string: {search}', - {'search': search_string}) - - for page in range(1, self.max_pages + 1): - search_url = self.urls['search'].format(query=search_string, page=page) - - response = self.session.get(search_url) - if not response or not response.text: - log.debug('No data returned from provider') - break - - page_results = self.parse(response.text, mode) - results += page_results - if len(page_results) < 10: - break - - else: - response = self.session.get(self.urls['daily']) - if not response or not response.text: - log.debug('No data returned from provider') - continue - - results += self.parse(response.text, mode) - - # We don't have the real seeds but we can sort results by popularity and - # normalize seeds numbers so results can be sort in manual search - results = self.calc_seeds(results) - - return results - - def parse(self, data, mode): - """ - Parse search results for items. - - :param data: The raw response from a search - :param mode: The current mode used to search, e.g. RSS - - :return: A list of items found - """ - items = [] - - with BS4Parser(data, 'html5lib') as html: - table_body = html.find('ul', class_='search-ret-list') - - # Continue only if at least one release is found - if not table_body: - log.debug('Data returned from provider does not contain any torrents') - return items - - torrent_rows = table_body.find_all('li', class_='search-ret-item') - for row in torrent_rows: - try: - - title = row.find('h2').find('a').get('title') - download_url = row.find('div').find('a').get('href') + self._custom_trackers - if not all([title, download_url]): - continue - - spans = row.find('div').find_all('span') - - seeders = leechers = 0 - - torrent_size = spans[0].get_text() - size = convert_size(torrent_size, default=-1) - - torrent_pubdate = spans[2].get_text() - pubdate = self.parse_pubdate(torrent_pubdate) - - item = { - 'title': title, - 'link': download_url, - 'size': size, - 'seeders': seeders, - 'leechers': leechers, - 'pubdate': pubdate, - } - - if mode != 'RSS': - log.debug('Found result: {0} with {1} seeders and {2} leechers', - title, seeders, leechers) - - items.append(item) - except (AttributeError, TypeError, KeyError, ValueError, IndexError): - log.exception('Failed parsing provider.') - - return items - - def calc_seeds(self, results): - """Normalize seeds numbers so results can be sort in manual search.""" - seeds = len(results) - for result in results: - result['seeders'] = seeds - seeds -= 1 - return results - - -provider = BTDBProvider() diff --git a/medusa/providers/torrent/html/cinemaz.py b/medusa/providers/torrent/html/cinemaz.py index cd66d5b6b4..f0e3de3a0f 100644 --- a/medusa/providers/torrent/html/cinemaz.py +++ b/medusa/providers/torrent/html/cinemaz.py @@ -44,10 +44,8 @@ def __init__(self): # Miscellaneous Options self.freeleech = False - # Torrent Stats - # Cache - self.cache = tv.Cache(self) # only poll CinemaZ every 10 minutes max + self.cache = tv.Cache(self) def search(self, search_strings, age=0, ep_obj=None, **kwargs): """ diff --git a/medusa/providers/torrent/html/elitetracker.py b/medusa/providers/torrent/html/elitetracker.py index 3de9f9765c..2cbb078f30 100644 --- a/medusa/providers/torrent/html/elitetracker.py +++ b/medusa/providers/torrent/html/elitetracker.py @@ -53,10 +53,6 @@ def __init__(self): 'années': 'years' } - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self, min_time=30) @@ -150,7 +146,7 @@ def parse(self, data, mode, **kwargs): leechers = try_int(torrent.find(title='Leechers').get_text(strip=True)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/hdspace.py b/medusa/providers/torrent/html/hdspace.py index d7178fcecd..0e645b33e2 100644 --- a/medusa/providers/torrent/html/hdspace.py +++ b/medusa/providers/torrent/html/hdspace.py @@ -45,12 +45,8 @@ def __init__(self): # Miscellaneous Options - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache - self.cache = tv.Cache(self, min_time=10) # only poll HDSpace every 10 minutes max + self.cache = tv.Cache(self) def search(self, search_strings, age=0, ep_obj=None, **kwargs): """ @@ -145,7 +141,7 @@ def parse(self, data, mode): leechers = try_int(row.find('span', class_='leechy').find('a').get_text()) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/hdtorrents.py b/medusa/providers/torrent/html/hdtorrents.py index 809a5f1deb..3c4bc57d7d 100644 --- a/medusa/providers/torrent/html/hdtorrents.py +++ b/medusa/providers/torrent/html/hdtorrents.py @@ -48,10 +48,6 @@ def __init__(self): # Miscellaneous Options self.freeleech = None - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self, min_time=30) @@ -153,7 +149,7 @@ def parse(self, data, mode): leechers = try_int(cells[labels.index('L')].get_text(strip=True)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/hebits.py b/medusa/providers/torrent/html/hebits.py index df22538c3f..d1c33c1ec6 100644 --- a/medusa/providers/torrent/html/hebits.py +++ b/medusa/providers/torrent/html/hebits.py @@ -47,10 +47,6 @@ def __init__(self): # Miscellaneous Options self.freeleech = False - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self) @@ -141,7 +137,7 @@ def parse(self, data, mode): leechers = try_int(row.find('div', class_='bDowning').get_text(strip=True)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/horriblesubs.py b/medusa/providers/torrent/html/horriblesubs.py deleted file mode 100644 index 1b37e1e489..0000000000 --- a/medusa/providers/torrent/html/horriblesubs.py +++ /dev/null @@ -1,144 +0,0 @@ -# coding=utf-8 - -"""Provider code for HorribleSubs.""" - -from __future__ import unicode_literals - -import logging - -from medusa import tv -from medusa.bs4_parser import BS4Parser -from medusa.logger.adapters.style import BraceAdapter -from medusa.providers.torrent.torrent_provider import TorrentProvider - -from requests.compat import urljoin - -log = BraceAdapter(logging.getLogger(__name__)) -log.logger.addHandler(logging.NullHandler()) - - -class HorribleSubsProvider(TorrentProvider): - """HorribleSubs Torrent provider.""" - - def __init__(self): - """Initialize the class.""" - super(HorribleSubsProvider, self).__init__('HorribleSubs') - - # Credentials - self.public = True - - # URLs - self.url = 'http://horriblesubs.info' - self.urls = { - 'daily': urljoin(self.url, '/lib/latest.php'), - 'search': urljoin(self.url, '/lib/search.php'), - } - - # Miscellaneous Options - self.supports_absolute_numbering = True - self.anime_only = True - - # Cache - self.cache = tv.Cache(self, min_time=20) - - def search(self, search_strings, age=0, ep_obj=None, **kwargs): - """ - Search a provider and parse the results. - - :param search_strings: A dict with mode (key) and the search value (value) - :param age: Not used - :param ep_obj: Not used - :returns: A list of search results (structure) - """ - results = [] - - for mode in search_strings: - log.debug('Search mode: {0}', mode) - - search_params = {} - search_url = self.urls['daily'] - - for search_string in search_strings[mode]: - - if mode != 'RSS': - log.debug('Search string: {search}', - {'search': search_string}) - - search_params = {'value': '{0}'.format(search_string)} - search_url = self.urls['search'] - - response = self.session.get(search_url, params=search_params) - if not response or not response.text: - log.debug('No data returned from provider') - continue - - results += self.parse(response.text, mode) - - return results - - def parse(self, data, mode): - """ - Parse search results for items. - - :param data: The raw response from a search - :param mode: The current mode used to search, e.g. RSS - - :return: A list of items found - """ - items = [] - - with BS4Parser(data, 'html5lib') as html: - torrent_rows = html.find_all(class_=['release-info', 'release-links']) - - # Continue only if at least one release is found - if not torrent_rows: - log.debug('Data returned from provider does not contain any torrents') - return items - - for row in torrent_rows: - try: - if row['class'] == ['release-info']: - pubdate = None - # pubdate is only supported for non-daily searches - if mode != 'RSS': - # keep the date and strip the rest - pubdate_raw = row.find('td', class_='rls-label').get_text()[1:9] - pubdate = self.parse_pubdate(pubdate_raw, timezone='America/Los_Angeles') - continue - - title = row.find('td', class_='dl-label').get_text() - magnet = row.find('td', class_='dl-type hs-magnet-link') - download_url = magnet or row.find('td', class_='dl-type hs-torrent-link') - if not all([title, download_url]): - continue - - download_url = download_url.span.a.get('href') - - # Add HorribleSubs group to the title - title = '{group} {title}'.format(group='[HorribleSubs]', title=title) - - # HorribleSubs doesn't provide this information - seeders = 1 - leechers = 0 - size = -1 - - item = { - 'title': title, - 'link': download_url, - 'size': size, - 'seeders': seeders, - 'leechers': leechers, - 'pubdate': pubdate, - } - if mode != 'RSS': - log.debug('Found result: {0} with {1} seeders and {2} leechers', - title, seeders, leechers) - - items.append(item) - except (AttributeError, TypeError, KeyError, ValueError, IndexError): - log.exception('Failed parsing provider.') - - return items - - -provider = HorribleSubsProvider() diff --git a/medusa/providers/torrent/html/iptorrents.py b/medusa/providers/torrent/html/iptorrents.py index 35233249d8..2d57611538 100644 --- a/medusa/providers/torrent/html/iptorrents.py +++ b/medusa/providers/torrent/html/iptorrents.py @@ -43,12 +43,8 @@ def __init__(self): self.required_cookies = ('uid', 'pass') self.categories = '73=&60=' - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache - self.cache = tv.Cache(self, min_time=10) # Only poll IPTorrents every 10 minutes max + self.cache = tv.Cache(self) def search(self, search_strings, age=0, ep_obj=None, **kwargs): """ @@ -121,7 +117,7 @@ def parse(self, data, mode): leechers = int(row.find('td', attrs={'class': 'ac t_leechers'}).text) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/limetorrents.py b/medusa/providers/torrent/html/limetorrents.py index d7382bfff1..f4eb3fde12 100644 --- a/medusa/providers/torrent/html/limetorrents.py +++ b/medusa/providers/torrent/html/limetorrents.py @@ -51,10 +51,6 @@ def __init__(self): # Miscellaneous Options self.confirmed = False - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self, min_time=15) @@ -153,7 +149,7 @@ def process_column_header(th): seeders = try_int(cells[labels.index('Seed')].get_text(strip=True).replace(',', '')) leechers = try_int(cells[labels.index('Leech')].get_text(strip=True).replace(',', '')) - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/morethantv.py b/medusa/providers/torrent/html/morethantv.py index 3dc55266c6..b406858ba5 100644 --- a/medusa/providers/torrent/html/morethantv.py +++ b/medusa/providers/torrent/html/morethantv.py @@ -37,8 +37,6 @@ def __init__(self): # Credentials self.username = None self.password = None - self._uid = None - self._hash = None # URLs self.url = 'https://www.morethan.tv/' @@ -52,10 +50,6 @@ def __init__(self): # Miscellaneous Options - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self) @@ -158,7 +152,7 @@ def process_column_header(td): leechers = try_int(cells[labels.index('Leechers')].get_text(strip=True).replace(',', '')) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/nebulance.py b/medusa/providers/torrent/html/nebulance.py index 810d794c8b..20037ecfe6 100644 --- a/medusa/providers/torrent/html/nebulance.py +++ b/medusa/providers/torrent/html/nebulance.py @@ -47,10 +47,6 @@ def __init__(self): # Miscellaneous Options self.freeleech = None - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self) @@ -149,7 +145,7 @@ def parse(self, data, mode): leechers = try_int(cells[6].text.strip()) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/newpct.py b/medusa/providers/torrent/html/newpct.py deleted file mode 100644 index a746599ef3..0000000000 --- a/medusa/providers/torrent/html/newpct.py +++ /dev/null @@ -1,238 +0,0 @@ -# coding=utf-8 - -"""Provider code for Newpct.""" - -from __future__ import unicode_literals - -import logging -import re -from collections import OrderedDict - -from medusa import tv -from medusa.bs4_parser import BS4Parser -from medusa.helper.common import convert_size, try_int -from medusa.logger.adapters.style import BraceAdapter -from medusa.providers.torrent.torrent_provider import TorrentProvider - -from requests.compat import urljoin - -log = BraceAdapter(logging.getLogger(__name__)) -log.logger.addHandler(logging.NullHandler()) - - -class NewpctProvider(TorrentProvider): - """Newpct Torrent provider.""" - - search_regex = re.compile(r'(.*) S0?(\d+)E0?(\d+)') - anime_search_regex = re.compile(r'(.*) (\d+)') - torrent_id = re.compile(r'\/(\d{6,7})_') - - def __init__(self): - """Initialize the class.""" - super(NewpctProvider, self).__init__('Newpct') - - # Credentials - self.public = True - - # URLs - self.url = 'http://www.tvsinpagar.com' - self.urls = OrderedDict([ - ('daily', urljoin(self.url, 'ultimas-descargas')), - ('torrent_url', urljoin(self.url, 'descargar-torrent/{0}_{1}.html')), - ('download_series', urljoin(self.url, 'descargar-serie/{0}/capitulo-{1}/hdtv/')), - ('download_series_hd', urljoin(self.url, 'descargar-seriehd/{0}/capitulo-{1}/hdtv-720p-ac3-5-1/')), - ('download_series_vo', urljoin(self.url, 'descargar-serievo/{0}/capitulo-{1}/')), - ]) - - # Proper Strings - - # Miscellaneous Options - self.supports_absolute_numbering = True - self.onlyspasearch = None - self.torrent_id_counter = None - - # Torrent Stats - - # Cache - self.cache = tv.Cache(self, min_time=20) - - def search(self, search_strings, age=0, ep_obj=None, **kwargs): - """ - Search a provider and parse the results. - - :param search_strings: A dict with mode (key) and the search value (value) - :param age: Not used - :param ep_obj: Not used - :returns: A list of search results (structure) - """ - results = [] - lang_info = '' if not ep_obj or not ep_obj.series else ep_obj.series.lang - - for mode in search_strings: - log.debug('Search mode: {0}', mode) - - if self.series and (self.series.air_by_date or self.series.is_sports): - log.debug("Provider doesn't support air by date or sports search") - continue - - # Only search if user conditions are true - if self.onlyspasearch and lang_info != 'es' and mode != 'RSS': - log.debug('Show info is not Spanish, skipping provider search') - continue - - for search_string in search_strings[mode]: - - search_urls = [self.urls['daily']] - - if mode != 'RSS': - log.debug('Search string: {search}', - {'search': search_string}) - - name, chapter = self._parse_title(search_string) - search_urls = [self.urls[url].format(name, chapter) for url in self.urls - if url.startswith('download')] - - for url in search_urls: - response = self.session.get(url) - if not response or not response.text: - log.debug('No data returned from provider') - continue - - results += self.parse(response.text, mode) - - return results - - def parse(self, data, mode): - """ - Parse search results for items. - - :param data: The raw response from a search - :param mode: The current mode used to search, e.g. RSS - - :return: A list of items found - """ - items = [] - self.torrent_id_counter = 0 - - with BS4Parser(data, 'html5lib') as html: - torrent_table = html.find('div', class_='content') - - torrent_rows = [] - if torrent_table: - torrent_rows = torrent_table('div', class_='info') if mode == 'RSS' else [torrent_table] - - # Continue only if at least one release is found - if not torrent_rows or not torrent_rows[0]: - log.debug('Data returned from provider does not contain any torrents') - return items - - for row in torrent_rows: - try: - if mode == 'RSS': - quality = row.find('span', id='deco') - if not quality.get_text(strip=True).startswith('HDTV'): - if self.torrent_id_counter: - self.torrent_id_counter -= 1 - continue - - anchor = row.find('a') - if not self.torrent_id_counter: - torrent_content = self._get_content(anchor.get('href'), mode) - if not torrent_content: - continue - title, torrent_id, torrent_size, pubdate_raw = torrent_content - else: - self.torrent_id_counter -= 1 - h2 = anchor.h2.get_text(strip=True).replace(' ', ' ') - title = '{0} {1}'.format(h2, quality.contents[0].strip()) - torrent_id = self.torrent_id_counter - torrent_size = quality.contents[1].text.replace('Tamaño', '').strip() - else: - torrent_info = self._parse_download(row, mode) - if not torrent_info: - continue - title, torrent_id, torrent_size, pubdate_raw = torrent_info - - if not all([title, torrent_id]): - continue - - download_url = self.urls['torrent_url'].format(torrent_id, title) - - seeders = 1 # Provider does not provide seeders - leechers = 0 # Provider does not provide leechers - - size = convert_size(torrent_size) or -1 - - pubdate = self.parse_pubdate(pubdate_raw, dayfirst=True) - - item = { - 'title': title, - 'link': download_url, - 'size': size, - 'seeders': seeders, - 'leechers': leechers, - 'pubdate': pubdate, - } - if mode != 'RSS': - log.debug('Found result: {0} with {1} seeders and {2} leechers', - title, seeders, leechers) - - items.append(item) - except (AttributeError, TypeError, KeyError, ValueError, IndexError): - log.exception('Failed parsing provider.') - - return items - - def _parse_title(self, search_string): - if self.series and self.series.is_anime: - search_matches = NewpctProvider.anime_search_regex.match(search_string) - name = search_matches.group(1) - chapter = '1{0}'.format(search_matches.group(2)) - else: - search_matches = NewpctProvider.search_regex.match(search_string) - name = search_matches.group(1) - chapter = '{0}{1}'.format(search_matches.group(2), search_matches.group(3)) - - norm_name = re.sub(r'\W', '-', name) - title = norm_name.replace('--', '-').strip('-').lower() - - return title, chapter - - def _get_content(self, torrent_url, mode): - response = self.session.get(torrent_url) - if not response or not response.text: - log.debug('No data returned for first item') - return - - with BS4Parser(response.text, 'html5lib') as html: - torrent_content = html.find('div', class_='content') - if not torrent_content: - log.debug('Wrong data returned for first item') - return - - return self._parse_download(torrent_content, mode) - - def _parse_download(self, torrent_content, mode): - torrent_dl = torrent_content.find('div', id='tabs_content_container') - if not torrent_dl: - log.debug('No data returned for searched item') - return - - torrent_h1 = torrent_content.find('h1') - title = torrent_h1.get_text(' ', strip=True).split('/')[-1].strip() - - torrent_info = torrent_content.find('div', class_='entry-left') - spans = torrent_info('span', class_='imp') - size = spans[0].contents[1].strip() - pubdate_raw = spans[1].contents[1].strip() - - dl_script = torrent_dl.find('script', type='text/javascript').get_text(strip=True) - item_id = try_int(NewpctProvider.torrent_id.search(dl_script).group(1)) - - if mode == 'RSS' and not self.torrent_id_counter: - self.torrent_id_counter = item_id - - return title, item_id, size, pubdate_raw - - -provider = NewpctProvider() diff --git a/medusa/providers/torrent/html/nordicbits.py b/medusa/providers/torrent/html/nordicbits.py index 002c1e2237..97ce987a61 100644 --- a/medusa/providers/torrent/html/nordicbits.py +++ b/medusa/providers/torrent/html/nordicbits.py @@ -46,10 +46,6 @@ def __init__(self): # Miscellaneous Options self.freeleech = False - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self) @@ -146,7 +142,7 @@ def get_label_title(label): leechers = try_int(cells[labels.index('Leechers')].get_text(strip=True)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/pretome.py b/medusa/providers/torrent/html/pretome.py index 63c98e8af2..bfa0d3cc13 100644 --- a/medusa/providers/torrent/html/pretome.py +++ b/medusa/providers/torrent/html/pretome.py @@ -45,10 +45,6 @@ def __init__(self): # Proper Strings self.proper_strings = ['PROPER', 'REPACK', 'REAL'] - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self) @@ -126,7 +122,7 @@ def parse(self, data, mode): leechers = try_int(cells[10].get_text()) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/scenetime.py b/medusa/providers/torrent/html/scenetime.py index ac53d1c0eb..ad3c44c657 100644 --- a/medusa/providers/torrent/html/scenetime.py +++ b/medusa/providers/torrent/html/scenetime.py @@ -46,10 +46,6 @@ def __init__(self): self.cookies = '' self.required_cookies = ('uid', 'pass') - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self) @@ -146,7 +142,7 @@ def parse(self, data, mode): leechers = try_int(cells[labels.index('Leechers')].get_text(strip=True)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/sdbits.py b/medusa/providers/torrent/html/sdbits.py index 951cdc7536..177291f956 100644 --- a/medusa/providers/torrent/html/sdbits.py +++ b/medusa/providers/torrent/html/sdbits.py @@ -47,10 +47,6 @@ def __init__(self): # Miscellaneous Options - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self, min_time=30) @@ -140,7 +136,7 @@ def parse(self, data, mode): leechers = try_int(cells[8].get_text(strip=True)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/shanaproject.py b/medusa/providers/torrent/html/shanaproject.py index 4019c0f587..bf535b0d50 100644 --- a/medusa/providers/torrent/html/shanaproject.py +++ b/medusa/providers/torrent/html/shanaproject.py @@ -42,10 +42,6 @@ def __init__(self): self.supports_absolute_numbering = True self.anime_only = True - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self, min_time=20) diff --git a/medusa/providers/torrent/html/speedcd.py b/medusa/providers/torrent/html/speedcd.py index 968771ceb0..951ca37ff0 100644 --- a/medusa/providers/torrent/html/speedcd.py +++ b/medusa/providers/torrent/html/speedcd.py @@ -47,10 +47,6 @@ def __init__(self): # Miscellaneous Options self.freeleech = False - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self) @@ -136,7 +132,7 @@ def parse(self, data, mode): leechers = try_int(cells[7].get_text(strip=True)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/thepiratebay.py b/medusa/providers/torrent/html/thepiratebay.py index f7b6caccfc..690c379dda 100644 --- a/medusa/providers/torrent/html/thepiratebay.py +++ b/medusa/providers/torrent/html/thepiratebay.py @@ -43,10 +43,6 @@ def __init__(self): # Miscellaneous Options self.confirmed = True - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self, min_time=20) @@ -150,7 +146,7 @@ def process_column_header(th): leechers = try_int(cells[labels.index('LE')].get_text(strip=True)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/tntvillage.py b/medusa/providers/torrent/html/tntvillage.py index 2292f3c44d..dc73102a1a 100644 --- a/medusa/providers/torrent/html/tntvillage.py +++ b/medusa/providers/torrent/html/tntvillage.py @@ -5,22 +5,13 @@ from __future__ import unicode_literals import logging -import re from medusa import tv from medusa.bs4_parser import BS4Parser -from medusa.helper.common import ( - convert_size, - try_int, -) -from medusa.helper.exceptions import AuthException from medusa.logger.adapters.style import BraceAdapter from medusa.providers.torrent.torrent_provider import TorrentProvider from requests.compat import urljoin -from requests.utils import dict_from_cookiejar - -from six.moves.urllib_parse import parse_qs log = BraceAdapter(logging.getLogger(__name__)) log.logger.addHandler(logging.NullHandler()) @@ -34,31 +25,23 @@ def __init__(self): super(TNTVillageProvider, self).__init__('TNTVillage') # Credentials - self.username = None - self.password = None - self._uid = None - self._hash = None + self.public = True # URLs - self.url = 'http://forum.tntvillage.scambioetico.org/' + self.url = 'http://tntvillage.scambioetico.org' self.urls = { - 'login': urljoin(self.url, 'index.php?act=Login&CODE=01'), - 'download': urljoin(self.url, 'index.php?act=Attach&type=post&id={0}'), + 'search': urljoin(self.url, 'src/releaselist.php'), } # Proper Strings self.proper_strings = ['PROPER', 'REPACK'] # Miscellaneous Options - self.engrelease = None + self.engrelease = None # Currently unused self.subtitle = None - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache - self.cache = tv.Cache(self, min_time=30) # only poll TNTVillage every 30 minutes max + self.cache = tv.Cache(self, min_time=20) def search(self, search_strings, age=0, ep_obj=None, **kwargs): """ @@ -75,9 +58,9 @@ def search(self, search_strings, age=0, ep_obj=None, **kwargs): # Search Params search_params = { - 'act': 'allreleases', - 'filter': 'eng ' if self.engrelease else '', 'cat': 29, + 'page': 1, + 'srcrel': '', } for mode in search_strings: @@ -88,10 +71,11 @@ def search(self, search_strings, age=0, ep_obj=None, **kwargs): if mode != 'RSS': log.debug('Search string: {search}', {'search': search_string}) - search_params['filter'] += search_string - search_params['cat'] = None - response = self.session.get(self.url, params=search_params) + search_params['cat'] = 0 + search_params['srcrel'] = search_string + + response = self.session.post(self.urls['search'], data=search_params) if not response or not response.text: log.debug('No data returned from provider') continue @@ -112,40 +96,33 @@ def parse(self, data, mode): items = [] with BS4Parser(data, 'html5lib') as html: - torrent_table = html.find('table', class_='copyright') + torrent_table = html.find('div', class_='showrelease_tb') torrent_rows = torrent_table('tr') if torrent_table else [] # Continue only if at least one release is found - if len(torrent_rows) < 3: + if len(torrent_rows) < 2: log.debug('Data returned from provider does not contain any torrents') return items + # T M Cat L S C Titolo + labels = [label.get_text() for label in torrent_rows[0]('td')] + # Skip column headers - for row in torrent_table('tr')[1:]: + for row in torrent_rows[1:]: cells = row('td') try: - if not cells: - continue - - last_cell_anchor = cells[-1].find('a') - if not last_cell_anchor: - continue - params = parse_qs(last_cell_anchor.get('href', '')) - download_url = self.urls['download'].format(params['pid'][0]) if \ - params.get('pid') else None - title = self._process_title(cells[0], cells[1], mode) + title_cell = cells[labels.index('Titolo')] + title = title_cell.get_text() + download_url = cells[labels.index('T')].a.get('href') if not all([title, download_url]): continue - info_cell = cells[3]('td') - leechers = info_cell[0].find('span').get_text(strip=True) - leechers = try_int(leechers) - seeders = info_cell[1].find('span').get_text() - seeders = try_int(seeders, 1) + seeders = int(cells[labels.index('S')].get_text()) + leechers = int(cells[labels.index('L')].get_text()) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', @@ -157,16 +134,13 @@ def parse(self, data, mode): title) continue - torrent_size = info_cell[3].find('span').get_text() + ' GB' - size = convert_size(torrent_size) or -1 - item = { 'title': title, 'link': download_url, - 'size': size, + 'size': -1, # Provider doesn't have size information 'seeders': seeders, 'leechers': leechers, - 'pubdate': None, + 'pubdate': None, # Provider doesn't have pubdate information } if mode != 'RSS': log.debug('Found result: {0} with {1} seeders and {2} leechers', @@ -178,42 +152,8 @@ def parse(self, data, mode): return items - def login(self): - """Login method used for logging in before doing search and torrent downloads.""" - if len(self.session.cookies) > 1: - cookies_dict = dict_from_cookiejar(self.session.cookies) - if cookies_dict['pass_hash'] != '0' and cookies_dict['member_id'] != '0': - return True - - login_params = { - 'UserName': self.username, - 'PassWord': self.password, - 'CookieDate': 1, - 'submit': 'Connettiti al Forum', - } - - response = self.session.post(self.urls['login'], data=login_params) - if not response or not response.text: - log.warning('Unable to connect to provider') - return False - - if any([re.search('Sono stati riscontrati i seguenti errori', response.text), - re.search('Connettiti', response.text), ]): - log.warning('Invalid username or password. Check your settings') - return False - - return True - - def _check_auth(self): - - if not self.username or not self.password: - raise AuthException('Your authentication credentials for {0} are missing,' - ' check your config.'.format(self.name)) - - return True - @staticmethod - def _process_title(title, info, mode): + def _process_title(title, info, mode): # Currently unused result_title = title.find('a').get_text() result_info = info.find('span') diff --git a/medusa/providers/torrent/html/tokyotoshokan.py b/medusa/providers/torrent/html/tokyotoshokan.py index df1afb17aa..84a832351b 100644 --- a/medusa/providers/torrent/html/tokyotoshokan.py +++ b/medusa/providers/torrent/html/tokyotoshokan.py @@ -46,10 +46,6 @@ def __init__(self): self.supports_absolute_numbering = True self.anime_only = True - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self, min_time=15) # only poll TokyoToshokan every 15 minutes max @@ -125,7 +121,7 @@ def parse(self, data, mode): leechers = try_int(sl.group('leechers')) if sl else 0 # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/torrent9.py b/medusa/providers/torrent/html/torrent9.py deleted file mode 100644 index f69ecd3cf7..0000000000 --- a/medusa/providers/torrent/html/torrent9.py +++ /dev/null @@ -1,162 +0,0 @@ -# coding=utf-8 - -"""Provider code for Torrent9.""" - -from __future__ import unicode_literals - -import logging -import re - -from medusa import tv -from medusa.bs4_parser import BS4Parser -from medusa.helper.common import ( - convert_size, - try_int, -) -from medusa.logger.adapters.style import BraceAdapter -from medusa.providers.torrent.torrent_provider import TorrentProvider - -from requests.compat import urljoin - -log = BraceAdapter(logging.getLogger(__name__)) -log.logger.addHandler(logging.NullHandler()) - - -class Torrent9Provider(TorrentProvider): - """Torrent9 Torrent provider.""" - - non_words = re.compile(r'\W') - - def __init__(self): - """Initialize the class.""" - super(Torrent9Provider, self).__init__('Torrent9') - - # Credentials - self.public = True - - # URLs - self.url = 'http://www.torrent9.red' - self.urls = { - 'search': urljoin(self.url, '/search_torrent/{query}.html'), - 'daily': urljoin(self.url, '/torrents_series.html,trie-date-d'), - 'download': urljoin(self.url, '/get_torrent/{name}.torrent'), - } - - # Proper Strings - self.proper_strings = ['PROPER', 'REPACK'] - - # Miscellaneous Options - - # Torrent Stats - self.minseed = None - self.minleech = None - - # Cache - self.cache = tv.Cache(self, min_time=20) - - def search(self, search_strings, age=0, ep_obj=None, **kwargs): - """ - Search a provider and parse the results. - - :param search_strings: A dict with mode (key) and the search value (value) - :param age: Not used - :param ep_obj: Not used - :returns: A list of search results (structure) - """ - results = [] - - for mode in search_strings: - log.debug('Search mode: {0}', mode) - - for search_string in search_strings[mode]: - - if mode != 'RSS': - log.debug('Search string: {search}', - {'search': search_string}) - search_query = Torrent9Provider.non_words.sub('-', search_string) - search_url = self.urls['search'].format(query=search_query) - else: - search_url = self.urls['daily'] - - response = self.session.get(search_url) - if not response or not response.text: - log.debug('No data returned from provider') - continue - - results += self.parse(response.text, mode) - - return results - - def parse(self, data, mode): - """ - Parse search results for items. - - :param data: The raw response from a search - :param mode: The current mode used to search, e.g. RSS - - :return: A list of items found - """ - # Units - units = ['O', 'KO', 'MO', 'GO', 'TO', 'PO'] - - items = [] - - with BS4Parser(data, 'html5lib') as html: - table_body = html.find('tbody') - - # Continue only if at least one release is found - if not table_body: - log.debug('Data returned from provider does not contain any torrents') - return items - - for row in table_body('tr'): - cells = row('td') - if len(cells) < 4: - continue - - try: - info_cell = cells[0].a - title = info_cell.get_text() - download_url = info_cell.get('href') - if not all([title, download_url]): - continue - - title = '{name} {codec}'.format(name=title, codec='x264') - - download_name = download_url.rsplit('/', 1)[1] - download_url = self.urls['download'].format(name=download_name) - - seeders = try_int(cells[2].get_text(strip=True)) - leechers = try_int(cells[3].get_text(strip=True)) - - # Filter unseeded torrent - if seeders < min(self.minseed, 1): - if mode != 'RSS': - log.debug("Discarding torrent because it doesn't meet the" - ' minimum seeders: {0}. Seeders: {1}', - title, seeders) - continue - - torrent_size = cells[1].get_text() - size = convert_size(torrent_size, units=units) or -1 - - item = { - 'title': title, - 'link': download_url, - 'size': size, - 'seeders': seeders, - 'leechers': leechers, - 'pubdate': None, - } - if mode != 'RSS': - log.debug('Found result: {0} with {1} seeders and {2} leechers', - title, seeders, leechers) - - items.append(item) - except (AttributeError, TypeError, KeyError, ValueError, IndexError): - log.exception('Failed parsing provider.') - - return items - - -provider = Torrent9Provider() diff --git a/medusa/providers/torrent/html/torrentbytes.py b/medusa/providers/torrent/html/torrentbytes.py index 7b896a48d9..8536560fe1 100644 --- a/medusa/providers/torrent/html/torrentbytes.py +++ b/medusa/providers/torrent/html/torrentbytes.py @@ -47,10 +47,6 @@ def __init__(self): # Miscellaneous Options self.freeleech = False - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self) @@ -147,7 +143,7 @@ def parse(self, data, mode): leechers = try_int(cells[labels.index('Leechers')].get_text(strip=True)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/torrenting.py b/medusa/providers/torrent/html/torrenting.py index 1c0cee4b3f..ec41a424b9 100644 --- a/medusa/providers/torrent/html/torrenting.py +++ b/medusa/providers/torrent/html/torrenting.py @@ -43,10 +43,6 @@ def __init__(self): self.cookies = '' self.required_cookies = ('uid', 'pass') - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self) @@ -107,53 +103,53 @@ def parse(self, data, mode): if torrent_table: torrent_rows = torrent_table.find_all('tr') - # Continue only if at least one release is found - if len(torrent_rows) < 1: - log.debug('Data returned from provider does not contain any torrents') - return items - - # Skip column headers - for row in torrent_rows[1:]: - try: - torrent_items = row.find_all('td') - title = torrent_items[1].find('a').get_text(strip=True) - download_url = torrent_items[2].find('a')['href'] - if not all([title, download_url]): - continue - download_url = urljoin(self.url, download_url) - - seeders = try_int(torrent_items[5].get_text(strip=True)) - leechers = try_int(torrent_items[6].get_text(strip=True)) - - # Filter unseeded torrent - if seeders < min(self.minseed, 1): - if mode != 'RSS': - log.debug("Discarding torrent because it doesn't meet the" - ' minimum seeders: {0}. Seeders: {1}', - title, seeders) - continue - - torrent_size = torrent_items[4].get_text() - size = convert_size(torrent_size) or -1 - - pubdate_raw = torrent_items[1].find('div').get_text() - pubdate = self.parse_pubdate(pubdate_raw, human_time=True) - - item = { - 'title': title, - 'link': download_url, - 'size': size, - 'seeders': seeders, - 'leechers': leechers, - 'pubdate': pubdate, - } + # Continue only if at least one release is found + if len(torrent_rows) < 2: + log.debug('Data returned from provider does not contain any torrents') + return items + + # Skip column headers + for row in torrent_rows[1:]: + try: + torrent_items = row.find_all('td') + title = torrent_items[1].find('a').get_text(strip=True) + download_url = torrent_items[2].find('a')['href'] + if not all([title, download_url]): + continue + download_url = urljoin(self.url, download_url) + + seeders = try_int(torrent_items[5].get_text(strip=True)) + leechers = try_int(torrent_items[6].get_text(strip=True)) + + # Filter unseeded torrent + if seeders < self.minseed: if mode != 'RSS': - log.debug('Found result: {0} with {1} seeders and {2} leechers', - title, seeders, leechers) - - items.append(item) - except (AttributeError, TypeError, KeyError, ValueError, IndexError): - log.exception('Failed parsing provider') + log.debug("Discarding torrent because it doesn't meet the" + ' minimum seeders: {0}. Seeders: {1}', + title, seeders) + continue + + torrent_size = torrent_items[4].get_text() + size = convert_size(torrent_size) or -1 + + pubdate_raw = torrent_items[1].find('div').get_text() + pubdate = self.parse_pubdate(pubdate_raw, human_time=True) + + item = { + 'title': title, + 'link': download_url, + 'size': size, + 'seeders': seeders, + 'leechers': leechers, + 'pubdate': pubdate, + } + if mode != 'RSS': + log.debug('Found result: {0} with {1} seeders and {2} leechers', + title, seeders, leechers) + + items.append(item) + except (AttributeError, TypeError, KeyError, ValueError, IndexError): + log.exception('Failed parsing provider') return items diff --git a/medusa/providers/torrent/html/tvchaosuk.py b/medusa/providers/torrent/html/tvchaosuk.py index ada16ecdac..dc90568d81 100644 --- a/medusa/providers/torrent/html/tvchaosuk.py +++ b/medusa/providers/torrent/html/tvchaosuk.py @@ -50,10 +50,6 @@ def __init__(self): # Miscellaneous Options self.freeleech = None - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self) @@ -153,7 +149,7 @@ def parse(self, data, mode, **kwargs): leechers = try_int(row.find(title='Leechers').get_text(strip=True)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/html/yggtorrent.py b/medusa/providers/torrent/html/yggtorrent.py index b50df0a45b..460bc2a163 100644 --- a/medusa/providers/torrent/html/yggtorrent.py +++ b/medusa/providers/torrent/html/yggtorrent.py @@ -47,10 +47,6 @@ def __init__(self): # Proper Strings self.proper_strings = ['PROPER', 'REPACK', 'REAL', 'RERIP'] - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self, min_time=20) @@ -136,7 +132,7 @@ def parse(self, data, mode): leechers = try_int(cells[8].get_text(strip=True), 0) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', @@ -177,7 +173,11 @@ def login(self): if not self._is_authenticated(): login_url = self.get_redirect_url(self.urls['login']) login_resp = self.session.post(login_url, data=login_params) - if not login_resp: + if login_resp is None: + log.warning('Unable to connect to provider') + return False + + if not login_resp.ok: log.warning('Invalid username or password. Check your settings') return False diff --git a/medusa/providers/torrent/html/zooqle.py b/medusa/providers/torrent/html/zooqle.py index 26f1f445f6..7b35214067 100644 --- a/medusa/providers/torrent/html/zooqle.py +++ b/medusa/providers/torrent/html/zooqle.py @@ -42,10 +42,6 @@ def __init__(self): # Miscellaneous Options - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self, min_time=15) @@ -99,8 +95,11 @@ def parse(self, data, mode): items = [] with BS4Parser(data, 'html5lib') as html: - torrent_table = html.find('div', class_='panel-body') - torrent_rows = torrent_table('tr') if torrent_table else [] + torrent_table = html('div', class_='panel-body', limit=2) + if mode != 'RSS': + torrent_rows = torrent_table[1]('tr') if torrent_table else [] + else: + torrent_rows = torrent_table[0]('tr') if torrent_table else [] # Continue only if at least one release is found if len(torrent_rows) < 2: @@ -131,7 +130,7 @@ def parse(self, data, mode): leechers = try_int(peers[1][10:]) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/json/animebytes.py b/medusa/providers/torrent/json/animebytes.py index 062f2ffb06..ede32e37e8 100644 --- a/medusa/providers/torrent/json/animebytes.py +++ b/medusa/providers/torrent/json/animebytes.py @@ -49,10 +49,6 @@ def __init__(self): self.freeleech = False self.anime_only = True - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self, min_time=30) @@ -240,7 +236,7 @@ def parse(self, data, mode): pubdate = self.parse_pubdate(row.get('UploadTime')) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/json/bitcannon.py b/medusa/providers/torrent/json/bitcannon.py index 5d663d3674..4763ccad85 100644 --- a/medusa/providers/torrent/json/bitcannon.py +++ b/medusa/providers/torrent/json/bitcannon.py @@ -40,10 +40,6 @@ def __init__(self): # Miscellaneous Options - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache cache_params = {'RSS': ['tv', 'anime']} self.cache = tv.Cache(self, search_params=cache_params) @@ -126,7 +122,7 @@ def parse(self, data, mode): leechers = try_int(swarm.pop('leechers', 0)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/json/btn.py b/medusa/providers/torrent/json/btn.py index 1a1efad61a..485b9e54e7 100644 --- a/medusa/providers/torrent/json/btn.py +++ b/medusa/providers/torrent/json/btn.py @@ -76,12 +76,8 @@ def __init__(self): # Miscellaneous Options self.supports_absolute_numbering = True - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache - self.cache = tv.Cache(self, min_time=10) # Only poll BTN every 15 minutes max + self.cache = tv.Cache(self, min_time=15) def search(self, search_strings, age=0, ep_obj=None, **kwargs): """ @@ -141,14 +137,15 @@ def parse(self, data, mode): if not all([title, download_url]): continue - seeders = row.get('Seeders', 1) - leechers = row.get('Leechers', 0) + seeders = int(row.get('Seeders', 1)) + leechers = int(row.get('Leechers', 0)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): - log.debug("Discarding torrent because it doesn't meet the" - ' minimum seeders: {0}. Seeders: {1}', - title, seeders) + if seeders < self.minseed: + if mode != 'RSS': + log.debug("Discarding torrent because it doesn't meet the" + ' minimum seeders: {0}. Seeders: {1}', + title, seeders) continue size = convert_size(row.get('Size'), default=-1) diff --git a/medusa/providers/torrent/json/danishbits.py b/medusa/providers/torrent/json/danishbits.py index 64e3ee837b..26c1d55dc7 100644 --- a/medusa/providers/torrent/json/danishbits.py +++ b/medusa/providers/torrent/json/danishbits.py @@ -42,10 +42,6 @@ def __init__(self): self.freeleech = True self.session.headers['User-Agent'] = USER_AGENT - # Torrent Stats - self.minseed = 0 - self.minleech = 0 - # Cache self.cache = tv.Cache(self) @@ -131,7 +127,7 @@ def parse(self, data, mode): leechers = row.get('leechers') # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/json/hdbits.py b/medusa/providers/torrent/json/hdbits.py index df290babaf..2314225771 100644 --- a/medusa/providers/torrent/json/hdbits.py +++ b/medusa/providers/torrent/json/hdbits.py @@ -40,10 +40,6 @@ def __init__(self): # Miscellaneous Options - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self) @@ -133,11 +129,11 @@ def parse(self, data, mode): leechers = row.get('leechers', 0) # Filter unseeded torrent - if seeders < min(self.minseed, 1): - log.debug( - "Discarding torrent because it doesn't meet the" - ' minimum seeders: {0}. Seeders: {1}', - title, seeders) + if seeders < self.minseed: + if mode != 'RSS': + log.debug("Discarding torrent because it doesn't meet the" + ' minimum seeders: {0}. Seeders: {1}', + title, seeders) continue size = convert_size(row.get('size'), default=-1) diff --git a/medusa/providers/torrent/json/norbits.py b/medusa/providers/torrent/json/norbits.py index 35e1ca14e2..cd273708b9 100644 --- a/medusa/providers/torrent/json/norbits.py +++ b/medusa/providers/torrent/json/norbits.py @@ -43,10 +43,6 @@ def __init__(self): # Miscellaneous Options - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self, min_time=20) @@ -122,7 +118,7 @@ def parse(self, data, mode): leechers = try_int(row.pop('leechers', 0)) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/json/rarbg.py b/medusa/providers/torrent/json/rarbg.py index a1d82cb615..f276ac3515 100644 --- a/medusa/providers/torrent/json/rarbg.py +++ b/medusa/providers/torrent/json/rarbg.py @@ -45,10 +45,6 @@ def __init__(self): self.ranked = None self.sorting = None - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self, min_time=15) @@ -69,8 +65,8 @@ def search(self, search_strings, age=0, ep_obj=None, **kwargs): search_params = { 'app_id': app.RARBG_APPID, 'category': 'tv', - 'min_seeders': try_int(self.minseed), - 'min_leechers': try_int(self.minleech), + 'min_seeders': self.minseed, + 'min_leechers': self.minleech, 'limit': 100, 'format': 'json_extended', 'ranked': try_int(self.ranked), @@ -168,7 +164,7 @@ def parse(self, data, mode): leechers = row.pop('leechers', 0) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/json/torrentday.py b/medusa/providers/torrent/json/torrentday.py index e9f04dcd56..35f87b0dcc 100644 --- a/medusa/providers/torrent/json/torrentday.py +++ b/medusa/providers/torrent/json/torrentday.py @@ -60,12 +60,8 @@ def __init__(self): 'RSS': {'2': 1, '26': 1, '7': 1, '24': 1, '34': 1, '14': 1} } - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache - self.cache = tv.Cache(self, min_time=10) + self.cache = tv.Cache(self) def search(self, search_strings, age=0, ep_obj=None, **kwargs): """ @@ -137,7 +133,7 @@ def parse(self, data, mode): leechers = int(row['leechers']) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/json/torrentleech.py b/medusa/providers/torrent/json/torrentleech.py index f8ab556858..1ed24c8b32 100644 --- a/medusa/providers/torrent/json/torrentleech.py +++ b/medusa/providers/torrent/json/torrentleech.py @@ -47,10 +47,6 @@ def __init__(self): # Miscellaneous Options self.max_torrents = 100 - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self) @@ -155,10 +151,11 @@ def parse(self, data, mode): leechers = int(torrent['leechers']) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" - ' minimum seeders: {0}. Seeders: {1}', title, seeders) + ' minimum seeders: {0}. Seeders: {1}', + title, seeders) continue size = convert_size(torrent['size']) or -1 diff --git a/medusa/providers/torrent/json/xthor.py b/medusa/providers/torrent/json/xthor.py index f32a7cc4c3..9d9578406c 100644 --- a/medusa/providers/torrent/json/xthor.py +++ b/medusa/providers/torrent/json/xthor.py @@ -37,13 +37,11 @@ def __init__(self): self.subcategories = [433, 637, 455, 639] # Torrent Stats - self.minseed = None - self.minleech = None self.confirmed = False - self.freeleech = None + self.freeleech = False # Cache - self.cache = tv.Cache(self, min_time=10) + self.cache = tv.Cache(self) def search(self, search_strings, age=0, ep_obj=None, **kwargs): """ @@ -132,9 +130,9 @@ def parse(self, data, mode): leechers = row.get('leechers') # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': - log.debug('Discarding torrent because it doesn\'t meet the' + log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', title, seeders) continue diff --git a/medusa/providers/torrent/rss/nyaa.py b/medusa/providers/torrent/rss/nyaa.py index 068ce39ba3..2f8739779b 100644 --- a/medusa/providers/torrent/rss/nyaa.py +++ b/medusa/providers/torrent/rss/nyaa.py @@ -34,10 +34,6 @@ def __init__(self): self.supports_absolute_numbering = True self.confirmed = False - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache self.cache = tv.Cache(self, min_time=20) @@ -116,10 +112,11 @@ def parse(self, data, mode): leechers = try_int(item['nyaa_leechers']) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" - ' minimum seeders: {0}. Seeders: {1}', title, seeders) + ' minimum seeders: {0}. Seeders: {1}', + title, seeders) continue size = convert_size(item['nyaa_size'], default=-1, units=units) diff --git a/medusa/providers/torrent/torrent_provider.py b/medusa/providers/torrent/torrent_provider.py index 8e618d4849..442b531351 100644 --- a/medusa/providers/torrent/torrent_provider.py +++ b/medusa/providers/torrent/torrent_provider.py @@ -35,6 +35,8 @@ def __init__(self, name): self.ratio = None self.provider_type = GenericProvider.TORRENT + self.minseed = 0 + self.minleech = 0 def is_active(self): """Check if provider is enabled.""" @@ -61,10 +63,6 @@ def _get_size(self, item): else: size = -1 - # Make sure we didn't select seeds/leechers by accident - if not size or size < 1024 * 1024: - size = -1 - return try_int(size, -1) def _get_storage_dir(self): diff --git a/medusa/providers/torrent/torznab/torznab.py b/medusa/providers/torrent/torznab/torznab.py index 0d35f39331..650c75b867 100644 --- a/medusa/providers/torrent/torznab/torznab.py +++ b/medusa/providers/torrent/torznab/torznab.py @@ -46,10 +46,6 @@ def __init__(self, name, url=None, api_key=None, cat_ids=None, cap_tv_search=Non self.cat_ids = cat_ids or ['5010', '5030', '5040'] self.cap_tv_search = cap_tv_search or [] - # Torrent Stats - self.minseed = None - self.minleech = None - # For now apply the additional season search string for all torznab providers. # If we want to limited this per provider, I suggest using a dict, with provider: [list of season templates] # construction. @@ -182,7 +178,7 @@ def parse(self, data, mode): leechers = int(peers_attr.get('value', 0)) if peers_attr else 0 # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/providers/torrent/xml/torrentz2.py b/medusa/providers/torrent/xml/torrentz2.py index 38f910fb42..66577ec39c 100644 --- a/medusa/providers/torrent/xml/torrentz2.py +++ b/medusa/providers/torrent/xml/torrentz2.py @@ -42,12 +42,8 @@ def __init__(self): # Miscellaneous Options # self.confirmed = True - # Torrent Stats - self.minseed = None - self.minleech = None - # Cache - self.cache = tv.Cache(self, min_time=15) # only poll Torrentz every 15 minutes max + self.cache = tv.Cache(self, min_time=15) def search(self, search_strings, age=0, ep_obj=None, **kwargs): """ @@ -122,7 +118,7 @@ def parse(self, data, mode): pubdate = self.parse_pubdate(pubdate_raw) # Filter unseeded torrent - if seeders < min(self.minseed, 1): + if seeders < self.minseed: if mode != 'RSS': log.debug("Discarding torrent because it doesn't meet the" ' minimum seeders: {0}. Seeders: {1}', diff --git a/medusa/sbdatetime.py b/medusa/sbdatetime.py index 7595c78407..989178358f 100644 --- a/medusa/sbdatetime.py +++ b/medusa/sbdatetime.py @@ -26,6 +26,9 @@ from medusa import app from medusa.network_timezones import app_timezone +import six + + date_presets = ( '%Y-%m-%d', '%a, %Y-%m-%d', @@ -104,7 +107,7 @@ def __get__(self, instance, owner): # subclass datetime.datetime to add function to display custom date and time formats class sbdatetime(datetime.datetime): has_locale = True - en_US_norm = locale.normalize('en_US.utf-8') + en_us_norm = locale.normalize('en_US.utf-8') @static_or_instance def convert_to_setting(self, dt=None): @@ -140,7 +143,7 @@ def sbftime(self, dt=None, show_seconds=False, t_preset=None): except Exception: try: if sbdatetime.has_locale: - locale.setlocale(locale.LC_TIME, sbdatetime.en_US_norm) + locale.setlocale(locale.LC_TIME, sbdatetime.en_us_norm) except Exception: sbdatetime.has_locale = False @@ -168,7 +171,10 @@ def sbftime(self, dt=None, show_seconds=False, t_preset=None): except Exception: sbdatetime.has_locale = False - return strt.decode(app.SYS_ENCODING) + if six.PY2: + strt = strt.decode(app.SYS_ENCODING) + + return strt # display Date in application Format @static_or_instance @@ -207,7 +213,10 @@ def sbfdate(self, dt=None, d_preset=None): except Exception: pass - return strd.decode(app.SYS_ENCODING) + if six.PY2: + strd = strd.decode(app.SYS_ENCODING) + + return strd # display Datetime in application Format @static_or_instance @@ -242,15 +251,17 @@ def sbfdatetime(self, dt=None, show_seconds=False, d_preset=None, t_preset=None) except Exception: try: if sbdatetime.has_locale: - locale.setlocale(locale.LC_TIME, sbdatetime.en_US_norm) + locale.setlocale(locale.LC_TIME, sbdatetime.en_us_norm) except Exception: sbdatetime.has_locale = False - if t_preset is not None: - strd += b', ' + dt.strftime(t_preset) - elif show_seconds: - strd += b', ' + dt.strftime(app.TIME_PRESET_W_SECONDS) - else: - strd += b', ' + dt.strftime(app.TIME_PRESET) + + if six.PY2: + strd = strd.decode(app.SYS_ENCODING) + + # Select format + fmt = t_preset or app.TIME_PRESET_W_SECONDS if show_seconds else app.TIME_PRESET + # Add formatted date + strd = ', '.join([strd, dt.strftime(fmt)]) else: if d_preset is not None: strd = self.strftime(d_preset) @@ -262,15 +273,17 @@ def sbfdatetime(self, dt=None, show_seconds=False, d_preset=None, t_preset=None) except Exception: try: if sbdatetime.has_locale: - locale.setlocale(locale.LC_TIME, sbdatetime.en_US_norm) + locale.setlocale(locale.LC_TIME, sbdatetime.en_us_norm) except Exception: sbdatetime.has_locale = False - if t_preset is not None: - strd += b', ' + self.strftime(t_preset) - elif show_seconds: - strd += b', ' + self.strftime(app.TIME_PRESET_W_SECONDS) - else: - strd += b', ' + self.strftime(app.TIME_PRESET) + + if six.PY2: + strd = strd.decode(app.SYS_ENCODING) + + # Select format + fmt = t_preset or app.TIME_PRESET_W_SECONDS if show_seconds else app.TIME_PRESET + # Add formatted date + strd = ', '.join([strd, self.strftime(fmt)]) finally: try: if sbdatetime.has_locale: @@ -278,4 +291,4 @@ def sbfdatetime(self, dt=None, show_seconds=False, d_preset=None, t_preset=None) except Exception: sbdatetime.has_locale = False - return strd.decode(app.SYS_ENCODING) + return strd diff --git a/medusa/scene_exceptions.py b/medusa/scene_exceptions.py index 95c06becb9..0ff145aabe 100644 --- a/medusa/scene_exceptions.py +++ b/medusa/scene_exceptions.py @@ -5,7 +5,6 @@ from __future__ import unicode_literals import logging -import threading import time from collections import defaultdict from os.path import join @@ -15,15 +14,15 @@ from medusa import app, db, helpers from medusa.indexers.indexer_api import indexerApi from medusa.indexers.indexer_config import INDEXER_TVDBV2 +from medusa.logger.adapters.style import BraceAdapter from medusa.session.core import MedusaSafeSession from six import iteritems -logger = logging.getLogger(__name__) +logger = BraceAdapter(logging.getLogger(__name__)) +logger.logger.addHandler(logging.NullHandler()) exceptions_cache = defaultdict(lambda: defaultdict(set)) -exceptionLock = threading.Lock() - VALID_XEM_ORIGINS = {'anidb', 'tvdb', } safe_session = MedusaSafeSession() @@ -179,7 +178,7 @@ def get_scene_exceptions_by_name(show_name): if show_name.lower() in show_names: logger.debug( 'Scene exception lookup got indexer ID {cur_indexer},' - ' using that', cur_indexer=indexer_id + ' using that', {'cur_indexer': indexer_id} ) result.append((indexer_id, season, indexer)) @@ -188,9 +187,11 @@ def get_scene_exceptions_by_name(show_name): def update_scene_exceptions(series_obj, scene_exceptions, season=-1): """Update database with all show scene exceptions by indexer_id.""" - logger.info('Updating scene exceptions for series {series.name} and ' - 'indexer {series.indexer} with id {series.series_id}', - {'series': series_obj}) + logger.info('Updating scene exceptions for series {series_name} and ' + 'indexer {series_indexer} with id {series_id}', + {'series_name': series_obj.name, + 'series_indexer': series_obj.indexer, + 'series_id': series_obj.series_id}) if not all([series_obj.indexer, series_obj.series_id]): return @@ -296,7 +297,7 @@ def _get_custom_exceptions(force): location = indexerApi(indexer).config['scene_loc'] logger.info( 'Checking for scene exception updates from {location}', - location=location + {'location': location} ) try: # When any Medusa Safe session exception, session returns None and then AttributeError when json() @@ -304,9 +305,8 @@ def _get_custom_exceptions(force): except (ValueError, AttributeError) as error: logger.debug( 'Check scene exceptions update failed. Unable to ' - 'update from {location}. Error: {error}'.format( - location=location, error=error - ) + 'update from {location}. Error: {error}', + {'location': location, 'error': error} ) # If unable to get scene exceptions, assume we can't connect to CDN so we don't `continue` return custom_exceptions @@ -349,7 +349,7 @@ def _get_xem_exceptions(force): # XEM origin for indexer is invalid logger.error( 'Error getting XEM scene exceptions for {indexer}:' - ' {error}'.format(indexer=indexer_api.name, error=error) + ' {error}', {'indexer': indexer_api.name, 'error': error} ) continue else: @@ -358,9 +358,7 @@ def _get_xem_exceptions(force): logger.info( 'Checking for XEM scene exceptions updates for' - ' {indexer_name}'.format( - indexer_name=indexer_api.name - ) + ' {indexer_name}', {'indexer_name': indexer_api.name} ) response = safe_session.get(url, params=params, timeout=60) @@ -369,18 +367,14 @@ def _get_xem_exceptions(force): except (ValueError, AttributeError) as error: logger.debug( 'Check scene exceptions update failed for {indexer}.' - ' Unable to get URL: {url} Error: {error}'.format( - indexer=indexer_api.name, url=url, error=error, - ) + ' Unable to get URL: {url} Error: {error}', {'indexer': indexer_api.name, 'url': url, 'error': error} ) continue if not jdata['data'] or jdata['result'] == 'failure': logger.debug( 'No data returned from XEM while checking for scene' - ' exceptions. Update failed for {indexer}'.format( - indexer=indexer_api.name - ) + ' exceptions. Update failed for {indexer}', {'indexer': indexer_api.name} ) continue @@ -390,12 +384,9 @@ def _get_xem_exceptions(force): except Exception as error: logger.warning( 'XEM: Rejected entry: Indexer ID: {indexer_id},' - ' Exceptions: {e}'.format( - indexer_id=indexer_id, e=exceptions - ) + ' Exceptions: {exceptions}', {'indexer_id': indexer_id, 'exceptions': exceptions} ) - logger.warning('XEM: Rejected entry error message:' - ' {error}'.format(error=error)) + logger.warning('XEM: Rejected entry error message: {error}', {'error': error}) set_last_refresh('xem') @@ -423,17 +414,13 @@ def _get_anidb_exceptions(force): except ValueError as error: logger.debug( "Couldn't update scene exceptions for {show}," - " AniDB doesn't have this show. Error: {msg}".format( - show=show.name, msg=error, - ) + " AniDB doesn't have this show. Error: {msg}", {'show': show.name, 'msg': error} ) continue except Exception as error: logger.error( 'Checking AniDB scene exceptions update failed' - ' for {show}. Error: {msg}'.format( - show=show.name, msg=error, - ) + ' for {show}. Error: {msg}', {'show': show.name, 'msg': error} ) continue diff --git a/medusa/scheduler.py b/medusa/scheduler.py index 1a83ba3879..1ce2acfaba 100644 --- a/medusa/scheduler.py +++ b/medusa/scheduler.py @@ -43,7 +43,7 @@ def timeLeft(self): :return: timedelta """ - if self.isAlive(): + if self.is_alive(): if self.start_time is None: return self.cycleTime - (datetime.datetime.now() - self.lastRun) else: diff --git a/medusa/search/core.py b/medusa/search/core.py index 69f8c84d1f..ffe86cdd4a 100644 --- a/medusa/search/core.py +++ b/medusa/search/core.py @@ -185,48 +185,48 @@ def snatch_episode(result): # don't notify when we re-download an episode sql_l = [] trakt_data = [] - for curEpObj in result.episodes: - with curEpObj.lock: + for cur_ep_obj in result.episodes: + with cur_ep_obj.lock: if is_first_best_match(result): - curEpObj.status = SNATCHED_BEST - curEpObj.quality = result.quality + cur_ep_obj.status = SNATCHED_BEST + cur_ep_obj.quality = result.quality else: - curEpObj.status = end_status - curEpObj.quality = result.quality + cur_ep_obj.status = end_status + cur_ep_obj.quality = result.quality # Reset all others fields to the snatched status # New snatch by default doesn't have nfo/tbn - curEpObj.hasnfo = False - curEpObj.hastbn = False + cur_ep_obj.hasnfo = False + cur_ep_obj.hastbn = False # We can't reset location because we need to know what we are replacing - # curEpObj.location = '' + # cur_ep_obj.location = '' # Release name and group are parsed in PP - curEpObj.release_name = '' - curEpObj.release_group = '' + cur_ep_obj.release_name = '' + cur_ep_obj.release_group = '' # Need to reset subtitle settings because it's a different file - curEpObj.subtitles = list() - curEpObj.subtitles_searchcount = 0 - curEpObj.subtitles_lastsearch = u'0001-01-01 00:00:00' + cur_ep_obj.subtitles = list() + cur_ep_obj.subtitles_searchcount = 0 + cur_ep_obj.subtitles_lastsearch = u'0001-01-01 00:00:00' # Need to store the correct is_proper. Not use the old one - curEpObj.is_proper = is_proper - curEpObj.version = 0 + cur_ep_obj.is_proper = is_proper + cur_ep_obj.version = 0 - curEpObj.manually_searched = result.manually_searched + cur_ep_obj.manually_searched = result.manually_searched - sql_l.append(curEpObj.get_sql()) + sql_l.append(cur_ep_obj.get_sql()) - if curEpObj.status != common.DOWNLOADED: - notifiers.notify_snatch(curEpObj, result) + if cur_ep_obj.status != common.DOWNLOADED: + notifiers.notify_snatch(cur_ep_obj, result) if app.USE_TRAKT and app.TRAKT_SYNC_WATCHLIST: - trakt_data.append((curEpObj.season, curEpObj.episode)) + trakt_data.append((cur_ep_obj.season, cur_ep_obj.episode)) log.info( u'Adding {0} {1} to Trakt watchlist', result.series.name, - episode_num(curEpObj.season, curEpObj.episode), + episode_num(cur_ep_obj.season, cur_ep_obj.episode), ) if trakt_data: @@ -446,7 +446,7 @@ def wanted_episodes(series_obj, from_date): 'WHERE indexer = ? ' ' AND showid = ?' ' AND season > 0' - ' and airdate > ?', + ' AND airdate > ?', [series_obj.indexer, series_obj.series_id, from_date.toordinal()] ) @@ -648,8 +648,6 @@ def search_providers(series_obj, episodes, forced_search=False, down_cur_quality manual_search_results = [] multi_results = [] single_results = [] - cache_multi_results = [] - cache_single_results = [] # build name cache for show name_cache.build_name_cache(series_obj) @@ -707,17 +705,10 @@ def search_providers(series_obj, episodes, forced_search=False, down_cur_quality cache_search_results = cur_provider.search_results_in_cache(episodes) if cache_search_results: # From our provider multi_episode and single_episode results, collect candidates. - found_cache_results = list_results_for_provider(cache_search_results, found_results, cur_provider) + cache_found_results = list_results_for_provider(cache_search_results, found_results, cur_provider) # We're passing the empty lists, because we don't want to include previous candidates - cache_multi, cache_single = collect_candidates(found_cache_results, cur_provider, cache_multi, - cache_single, series_obj, down_cur_quality) - - # Check if we got any candidates from cache add add them to the list. - # If we found candidates in cache, we don't need to search the provider. - if cache_multi: - cache_multi_results += cache_multi - if cache_single: - cache_single_results += cache_single + cache_multi, cache_single = collect_candidates(cache_found_results, cur_provider, [], + [], series_obj, down_cur_quality) # For now we only search if we didn't get any results back from cache, # but we might wanna check if there was something useful in cache. @@ -727,6 +718,8 @@ def search_providers(series_obj, episodes, forced_search=False, down_cur_quality down_cur_quality, manual_search, manual_search_type) # Update the list found_results found_results = list_results_for_provider(search_results, found_results, cur_provider) + else: + found_results = cache_found_results except AuthException as error: log.error(u'Authentication error: {0!r}', error) @@ -768,13 +761,8 @@ def search_providers(series_obj, episodes, forced_search=False, down_cur_quality # Continue because we don't want to pick best results as we are running a manual search by user continue - # From our providers multi_episode and single_episode results, collect candidates. - # Only collect the candidates if we didn't get any from cache. - if not (cache_multi_results or cache_single_results): - multi_results, single_results = collect_candidates(found_results, cur_provider, multi_results, - single_results, series_obj, down_cur_quality) - else: - multi_results, single_results = cache_multi_results, cache_single_results + multi_results, single_results = collect_candidates(found_results, cur_provider, multi_results, + single_results, series_obj, down_cur_quality) # Remove provider from thread name before return results threading.currentThread().name = original_thread_name @@ -824,7 +812,13 @@ def list_results_for_provider(search_results, found_results, provider): def collect_single_candidates(candidates, results): - """Collect single-episode result candidates.""" + """ + Collect single-episode result candidates. + + :param candidates: A list of SearchResult objects we just parsed, which we want to evaluate against the already + collected list of results. + :param results: The existing list of valid results. + """ single_candidates = list(results) new_candidates = [] @@ -934,12 +928,13 @@ def combine_results(multi_results, single_results): log.debug(u'Adding {0} to multi-episode result candidates', candidate.name) result_candidates.append(candidate) + return_multi_results = [] for multi_result in result_candidates: # see how many of the eps that this result covers aren't covered by single results needed_eps = [] not_needed_eps = [] for result in single_results: - if result in multi_result.episodes: + if result.episodes[0] in multi_result.episodes: not_needed_eps.append(result.actual_episode) else: needed_eps.append(result.actual_episode) @@ -947,7 +942,9 @@ def combine_results(multi_results, single_results): log.debug(u'Single-ep check result is needed_eps: {0}, not_needed_eps: {1}', needed_eps, not_needed_eps) - if not needed_eps: + if needed_eps: + return_multi_results.append(multi_result) + else: log.debug(u'All of these episodes were covered by single-episode results,' u' ignoring this multi-episode result') continue @@ -963,4 +960,4 @@ def combine_results(multi_results, single_results): ) del single_results[i] - return single_results + result_candidates + return single_results + return_multi_results diff --git a/medusa/search/daily.py b/medusa/search/daily.py index 1978cc93ab..de40d82313 100644 --- a/medusa/search/daily.py +++ b/medusa/search/daily.py @@ -8,6 +8,7 @@ import threading from builtins import object from datetime import date, datetime, timedelta +from math import ceil from time import time from medusa import app, common @@ -29,7 +30,7 @@ log.logger.addHandler(logging.NullHandler()) -class DailySearcher(object): # pylint:disable=too-few-public-methods +class DailySearcher(object): """Daily search class.""" def __init__(self): @@ -37,7 +38,7 @@ def __init__(self): self.lock = threading.Lock() self.amActive = False - def run(self, force=False): # pylint:disable=too-many-branches + def run(self, force=False): """ Run the daily searcher, queuing selected episodes for search. @@ -58,12 +59,26 @@ def run(self, force=False): # pylint:disable=too-many-branches if not network_dict: update_network_dict() + # The tvshows airdate_offset field is used to configure a search offset for specific shows. + # This way we can search/accept results early or late, depending on the value. + main_db_con = DBConnection() + min_offset_show = main_db_con.select( + 'SELECT COUNT(*) as offsets, MIN(airdate_offset) AS min_offset ' + 'FROM tv_shows ' + 'WHERE paused = 0 AND airdate_offset < 0' + ) + additional_search_offset = 0 + if min_offset_show and min_offset_show[0]['offsets'] > 0: + additional_search_offset = int(ceil(abs(min_offset_show[0]['min_offset']) / 24.0)) + log.debug('Using an airdate offset of {min_offset_show} as we found show(s) with an airdate' + ' offset configured.', {'min_offset_show': min_offset_show[0]['min_offset']}) + cur_time = datetime.now(app_timezone) + cur_date = ( - date.today() + timedelta(days=1 if network_dict else 2) + date.today() + timedelta(days=1 if network_dict else 2) + timedelta(days=additional_search_offset) ).toordinal() - main_db_con = DBConnection() episodes_from_db = main_db_con.select( 'SELECT indexer, showid, airdate, season, episode ' 'FROM tv_episodes ' @@ -90,16 +105,22 @@ def run(self, force=False): # pylint:disable=too-many-branches {'id': series_id}) continue + cur_ep = series_obj.get_episode(db_episode['season'], db_episode['episode']) + if series_obj.airs and series_obj.network: # This is how you assure it is always converted to local time show_air_time = parse_date_time(db_episode['airdate'], series_obj.airs, series_obj.network) end_time = show_air_time.astimezone(app_timezone) + timedelta(minutes=try_int(series_obj.runtime, 60)) - # filter out any episodes that haven't finished airing yet, - if end_time > cur_time: + if series_obj.airdate_offset != 0: + log.debug( + '{show}: Applying an airdate offset for the episode: {episode} of {offset} hours', + {'show': series_obj.name, 'episode': cur_ep.pretty_name(), 'offset': series_obj.airdate_offset}) + + # filter out any episodes that haven't finished airing yet + if end_time + timedelta(hours=series_obj.airdate_offset) > cur_time: continue - cur_ep = series_obj.get_episode(db_episode['season'], db_episode['episode']) with cur_ep.lock: cur_ep.status = series_obj.default_ep_status if cur_ep.season else common.SKIPPED log.info( diff --git a/medusa/search/manual.py b/medusa/search/manual.py index 92bb912743..93aa6edc28 100644 --- a/medusa/search/manual.py +++ b/medusa/search/manual.py @@ -308,6 +308,7 @@ def get_provider_cache_results(series_obj, show_all_results=None, perform_search i['leechers'] = i['leechers'] if i['leechers'] >= 0 else '-' i['pubdate'] = parser.parse(i['pubdate']).astimezone(app_timezone) if i['pubdate'] else '' i['date_added'] = datetime.fromtimestamp(float(i['date_added']), tz=app_timezone) if i['date_added'] else '' + release_group = i['release_group'] if ignored_words and release_group in ignored_words: i['rg_highlight'] = 'ignored' @@ -329,8 +330,15 @@ def get_provider_cache_results(series_obj, show_all_results=None, perform_search i['name_highlight'] = 'preferred' else: i['name_highlight'] = '' - i['seed_highlight'] = 'ignored' if i.get('provider_minseed') > i.get('seeders', -1) >= 0 else '' - i['leech_highlight'] = 'ignored' if i.get('provider_minleech') > i.get('leechers', -1) >= 0 else '' + + i['seed_highlight'] = 'ignored' + if i['seeders'] == '-' or i['provider_minseed'] <= i['seeders']: + i['seed_highlight'] = '' + + i['leech_highlight'] = 'ignored' + if i['leechers'] == '-' or i['provider_minleech'] <= i['leechers']: + i['leech_highlight'] = '' + provider_results['found_items'] = cached_results_total # Remove provider from thread name before return results diff --git a/medusa/server/api/v1/core.py b/medusa/server/api/v1/core.py index 65375fa12b..811cdfbd1a 100644 --- a/medusa/server/api/v1/core.py +++ b/medusa/server/api/v1/core.py @@ -59,7 +59,7 @@ from medusa.show.show import Show from medusa.system.restart import Restart from medusa.system.shutdown import Shutdown -from medusa.version_checker import CheckVersion +from medusa.updater.version_checker import CheckVersion from requests.compat import unquote_plus @@ -103,7 +103,7 @@ class ApiHandler(RequestHandler): """Api class that returns json results.""" - version = 6 # use an int since float-point is unpredictable + version = 7 # use an int since float-point is unpredictable def __init__(self, *args, **kwargs): super(ApiHandler, self).__init__(*args, **kwargs) @@ -112,7 +112,7 @@ def __init__(self, *args, **kwargs): # self.set_header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0') def get(self, *args, **kwargs): - kwargs = self.request.arguments + kwargs = {k: self.get_arguments(k) for k in self.request.arguments} for arg, value in iteritems(kwargs): if len(value) == 1: kwargs[arg] = value[0] @@ -141,9 +141,9 @@ def get(self, *args, **kwargs): try: out_dict = _call_dispatcher(args, kwargs) except Exception as error: # real internal error oohhh nooo :( - log.exception(u'API :: {0!r}', error.message) + log.exception(u'API :: {0!r}', error) error_data = { - 'error_msg': error.message, + 'error_msg': text_type(error), 'args': args, 'kwargs': kwargs } @@ -174,7 +174,7 @@ def _out_as_json(self, _dict): except Exception as error: # if we fail to generate the output fake an error log.exception(u'API :: Traceback') out = '{{"result": "{0}", "message": "error while composing output: {1!r}"}}'.format( - result_type_map[RESULT_ERROR], error.message + result_type_map[RESULT_ERROR], error ) return out @@ -215,7 +215,7 @@ def call_dispatcher(self, args, kwargs): # pylint:disable=too-many-branches else: cur_out_dict = _responds(RESULT_ERROR, 'No such cmd: {0!r}'.format(cmd)) except ApiError as error: # Api errors that we raised, they are harmless - cur_out_dict = _responds(RESULT_ERROR, msg=error.message) + cur_out_dict = _responds(RESULT_ERROR, msg=text_type(error)) else: # if someone chained one of the forbidden commands they will get an error for this one cmd cur_out_dict = _responds(RESULT_ERROR, msg='The cmd {0!r} is not supported while chaining'.format(cmd)) @@ -734,7 +734,7 @@ def run(self): # absolute vs relative vs broken show_path = None try: - show_path = show_obj.location + show_path = show_obj.validate_location except ShowDirectoryNotFoundException: pass @@ -1078,7 +1078,7 @@ def convert_date(history_date): return { 'date': convert_date(cur_item.date), 'episode': cur_item.episode, - 'indexerid': cur_item.show_id, + 'indexer': cur_item.indexer_id, 'provider': cur_item.provider, 'quality': get_quality_string(cur_item.quality), 'resource': os.path.basename(cur_item.resource), @@ -1086,9 +1086,7 @@ def convert_date(history_date): 'season': cur_item.season, 'show_name': cur_item.show_name, 'status': statusStrings[cur_item.action], - # Add tvdbid for backward compatibility - # TODO: Make this actual tvdb id for other indexers - 'tvdbid': cur_item.show_id, + 'show_id': cur_item.show_id, } results = [make_result(x, self.type) for x in history if x] @@ -1413,15 +1411,15 @@ def run(self): data = { 'current_version': { 'branch': check_version.get_branch(), - 'commit': check_version.updater.get_cur_commit_hash(), - 'version': check_version.updater.get_cur_version(), + 'commit': check_version.updater.current_commit_hash, + 'version': check_version.updater.current_version, }, 'latest_version': { 'branch': check_version.get_branch(), - 'commit': check_version.updater.get_newest_commit_hash(), - 'version': check_version.updater.get_newest_version(), + 'commit': check_version.updater.newest_commit_hash, + 'version': check_version.updater.newest_version, }, - 'commits_offset': check_version.updater.get_num_commits_behind(), + 'commits_offset': check_version.updater.commits_behind, 'needs_update': needs_update, } @@ -1442,9 +1440,9 @@ def run(self): main_db_con = db.DBConnection() sql_results = main_db_con.select('SELECT last_backlog FROM info') - backlog_paused = app.search_queue_scheduler.action.is_backlog_paused() # @UndefinedVariable - backlog_running = app.search_queue_scheduler.action.is_backlog_in_progress() # @UndefinedVariable - next_backlog = app.backlog_search_scheduler.next_run().strftime(dateFormat).decode(app.SYS_ENCODING) + backlog_paused = app.search_queue_scheduler.action.is_backlog_paused() + backlog_running = app.search_queue_scheduler.action.is_backlog_in_progress() + next_backlog = app.backlog_search_scheduler.next_run().strftime(dateFormat) data = {'backlog_is_paused': int(backlog_paused), 'backlog_is_running': int(backlog_running), 'last_backlog': _ordinal_to_date_form(sql_results[0]['last_backlog']), @@ -1903,7 +1901,7 @@ def run(self): show_dict['quality_details'] = {'initial': any_qualities, 'archive': best_qualities} try: - show_dict['location'] = show_obj.location + show_dict['location'] = show_obj.validate_location except ShowDirectoryNotFoundException: show_dict['location'] = '' @@ -2770,7 +2768,7 @@ def run(self): app.show_queue_scheduler.action.updateShow(show_obj) return _responds(RESULT_SUCCESS, msg='{0} has queued to be updated'.format(show_obj.name)) except CantUpdateShowException as error: - log.debug(u'API::Unable to update show: {0}', error.message) + log.debug(u'API::Unable to update show: {0!r}', error) return _responds(RESULT_FAILURE, msg='Unable to update {0}'.format(show_obj.name)) diff --git a/medusa/server/api/v2/base.py b/medusa/server/api/v2/base.py index 2af8ce71f0..aa60e33ae9 100644 --- a/medusa/server/api/v2/base.py +++ b/medusa/server/api/v2/base.py @@ -7,12 +7,13 @@ import collections import json import logging -import operator +import sys import traceback from builtins import object from collections import OrderedDict from concurrent.futures import ThreadPoolExecutor from datetime import date, datetime +from functools import partial from babelfish.language import Language @@ -32,7 +33,11 @@ log = BraceAdapter(logging.getLogger(__name__)) log.logger.addHandler(logging.NullHandler()) -executor = ThreadPoolExecutor(thread_name_prefix='APIv2-Thread') +# Python 3.5 doesn't support thread_name_prefix +if sys.version_info[:2] == (3, 5): + executor = ThreadPoolExecutor() +else: + executor = ThreadPoolExecutor(thread_name_prefix='APIv2-Thread') class BaseRequestHandler(RequestHandler): @@ -319,7 +324,7 @@ def _get_page(self): except ValueError: self._raise_bad_request_error('Invalid page parameter') - def _get_limit(self, default=20, maximum=10000): + def _get_limit(self, default=20, maximum=1000): try: limit = self._parse(self.get_argument('limit', default=default)) if limit < 1 or limit > maximum: @@ -330,8 +335,11 @@ def _get_limit(self, default=20, maximum=10000): self._raise_bad_request_error('Invalid limit parameter') def _paginate(self, data=None, data_generator=None, sort=None): - arg_page = self._get_page() - arg_limit = self._get_limit() + try: + arg_page = self._get_page() + arg_limit = self._get_limit() + except HTTPError as error: + return self._bad_request(error.message) headers = { 'X-Pagination-Page': arg_page, @@ -350,9 +358,15 @@ def _paginate(self, data=None, data_generator=None, sort=None): end = start + arg_limit results = data if arg_sort: + # Compare to earliest datetime instead of None + def safe_compare(field, results): + if field == 'airDate' and results[field] is None: + return text_type(datetime.min) + return results[field] + try: for field, reverse in reversed(arg_sort): - results = sorted(results, key=operator.itemgetter(field), reverse=reverse) + results = sorted(results, key=partial(safe_compare, field), reverse=reverse) except KeyError: return self._bad_request('Invalid sort query parameter') @@ -361,6 +375,7 @@ def _paginate(self, data=None, data_generator=None, sort=None): results = results[start:end] next_page = None if end > count else arg_page + 1 last_page = ((count - 1) // arg_limit) + 1 + headers['X-Pagination-Total'] = last_page if last_page <= arg_page: last_page = None diff --git a/medusa/server/api/v2/config.py b/medusa/server/api/v2/config.py index be170440df..0d4226adf6 100644 --- a/medusa/server/api/v2/config.py +++ b/medusa/server/api/v2/config.py @@ -83,7 +83,7 @@ class ConfigHandler(BaseRequestHandler): 'clients.torrents.password': StringField(app, 'TORRENT_PASSWORD'), 'clients.torrents.path': StringField(app, 'TORRENT_PATH'), 'clients.torrents.paused': BooleanField(app, 'TORRENT_PAUSED'), - 'clients.torrents.rpcurl': StringField(app, 'TORRENT_RPCURL'), + 'clients.torrents.rpcUrl': StringField(app, 'TORRENT_RPCURL'), 'clients.torrents.seedLocation': StringField(app, 'TORRENT_SEED_LOCATION'), 'clients.torrents.seedTime': IntegerField(app, 'TORRENT_SEED_TIME'), 'clients.torrents.username': StringField(app, 'TORRENT_USERNAME'), @@ -928,7 +928,7 @@ def data_clients(): section_data['torrents']['method'] = app.TORRENT_METHOD section_data['torrents']['path'] = app.TORRENT_PATH section_data['torrents']['paused'] = bool(app.TORRENT_PAUSED) - section_data['torrents']['rpcurl'] = app.TORRENT_RPCURL + section_data['torrents']['rpcUrl'] = app.TORRENT_RPCURL section_data['torrents']['seedLocation'] = app.TORRENT_SEED_LOCATION section_data['torrents']['seedTime'] = app.TORRENT_SEED_TIME section_data['torrents']['username'] = app.TORRENT_USERNAME diff --git a/medusa/server/api/v2/internal.py b/medusa/server/api/v2/internal.py index 31c4188f31..374b4d8665 100644 --- a/medusa/server/api/v2/internal.py +++ b/medusa/server/api/v2/internal.py @@ -172,9 +172,9 @@ def resource_search_indexers_for_show_name(self): if matches: search_terms.append('{0}({1})'.format(matches.group(1), matches.group(2))) - for searchTerm in search_terms: + for search_term in search_terms: # If search term begins with an article, let's also search for it without - matches = re.match(r'^(?:a|an|the) (.+)$', searchTerm, re.I) + matches = re.match(r'^(?:a|an|the) (.+)$', search_term, re.I) if matches: search_terms.append(matches.group(1)) @@ -203,7 +203,11 @@ def resource_search_indexers_for_show_name(self): # add search results results.setdefault(indexer, []).extend(indexer_results) except IndexerException as error: - log.info('Error searching for show: {error}', {'error': error}) + log.info('Error searching for show. term(s): {terms} indexer: {indexer} error: {error}', + {'terms': search_terms, 'indexer': indexer_api.name, 'error': error}) + except Exception as error: + log.error('Internal Error searching for show. term(s): {terms} indexer: {indexer} error: {error}', + {'terms': search_terms, 'indexer': indexer_api.name, 'error': error}) # Get all possible show ids all_show_ids = {} @@ -225,10 +229,10 @@ def resource_search_indexers_for_show_name(self): indexer, indexer_api.config['show_url'], show_id, - show['seriesname'].encode('utf-8'), + show['seriesname'], show['firstaired'] or 'N/A', - show.get('network', '').encode('utf-8') or 'N/A', - sanitize_filename(show['seriesname']).encode('utf-8'), + show.get('network', '') or 'N/A', + sanitize_filename(show['seriesname']), all_show_ids.get((indexer, show_id), False) ) ) diff --git a/medusa/server/api/v2/series.py b/medusa/server/api/v2/series.py index 7e3ae4ef6a..822d117468 100644 --- a/medusa/server/api/v2/series.py +++ b/medusa/server/api/v2/series.py @@ -130,17 +130,20 @@ def http_patch(self, series_slug, path_param=None): 'config.scene': BooleanField(series, 'scene'), 'config.sports': BooleanField(series, 'sports'), 'config.paused': BooleanField(series, 'paused'), - 'config.location': StringField(series, '_location'), + 'config.location': StringField(series, 'location'), 'config.airByDate': BooleanField(series, 'air_by_date'), 'config.subtitlesEnabled': BooleanField(series, 'subtitles'), 'config.release.requiredWords': ListField(series, 'release_required_words'), 'config.release.ignoredWords': ListField(series, 'release_ignore_words'), 'config.release.blacklist': ListField(series, 'blacklist'), 'config.release.whitelist': ListField(series, 'whitelist'), + 'config.release.requiredWordsExclude': BooleanField(series, 'rls_require_exclude'), + 'config.release.ignoredWordsExclude': BooleanField(series, 'rls_ignore_exclude'), 'language': StringField(series, 'lang'), 'config.qualities.allowed': ListField(series, 'qualities_allowed'), 'config.qualities.preferred': ListField(series, 'qualities_preferred'), 'config.qualities.combined': IntegerField(series, 'quality'), + 'config.airdateOffset': IntegerField(series, 'airdate_offset'), } for key, value in iter_nested_items(data): diff --git a/medusa/server/core.py b/medusa/server/core.py index 96afc8b23f..c6f46e7fe9 100644 --- a/medusa/server/core.py +++ b/medusa/server/core.py @@ -40,6 +40,8 @@ from medusa.server.web.core.base import AuthenticatedStaticFileHandler from medusa.ws.handler import WebSocketUIHandler +import six + from tornado.httpserver import HTTPServer from tornado.ioloop import IOLoop from tornado.web import ( @@ -51,6 +53,7 @@ from tornroutes import route + log = BraceAdapter(logging.getLogger(__name__)) log.logger.addHandler(logging.NullHandler()) @@ -271,6 +274,11 @@ def _get_webui_routes(self): return route.get_routes() def run(self): + # Start event loop in python3 + if six.PY3: + import asyncio + asyncio.set_event_loop(asyncio.new_event_loop()) + if self.enable_https: protocol = 'https' self.server = HTTPServer(self.app, ssl_options={'certfile': self.https_cert, 'keyfile': self.https_key}) @@ -285,25 +293,26 @@ def run(self): try: self.server.listen(self.options['port'], self.options['host']) - except Exception: + except Exception as ex: if app.LAUNCH_BROWSER and not self.daemon: app.instance.launch_browser('https' if app.ENABLE_HTTPS else 'http', self.options['port'], app.WEB_ROOT) log.info('Launching browser and exiting') - log.info('Could not start the web server on port {port}, already in use!', { - 'port': self.options['port'] + log.info('Could not start the web server on port {port}. Exception: {ex}', { + 'port': self.options['port'], + 'ex': ex }) os._exit(1) # pylint: disable=protected-access try: self.io_loop = IOLoop.current() - IOLoop.current().start() + self.io_loop.start() except (IOError, ValueError): # Ignore errors like 'ValueError: I/O operation on closed kqueue fd'. These might be thrown during a reload. pass def shutDown(self): self.alive = False - IOLoop.current().stop() + self.io_loop.stop() def log_request(self, handler): """ diff --git a/medusa/server/web/config/general.py b/medusa/server/web/config/general.py index 8f5db63505..232e71dd19 100644 --- a/medusa/server/web/config/general.py +++ b/medusa/server/web/config/general.py @@ -106,7 +106,8 @@ def saveGeneral(self, log_dir=None, log_nr=5, log_size=1, web_port=None, notify_ app.GIT_PASSWORD = git_password app.GIT_TOKEN = git_token app.GIT_RESET = config.checkbox_to_value(git_reset) - app.GIT_RESET_BRANCHES = helpers.ensure_list(git_reset_branches) + app.GIT_RESET_BRANCHES = [helpers.to_text(branch) for branch in + helpers.ensure_list(git_reset_branches)] if app.GIT_PATH != git_path: app.GIT_PATH = git_path config.change_GIT_PATH() diff --git a/medusa/server/web/config/providers.py b/medusa/server/web/config/providers.py index c59d77b601..026fe75a1f 100644 --- a/medusa/server/web/config/providers.py +++ b/medusa/server/web/config/providers.py @@ -365,11 +365,11 @@ def _set_common_settings(provider, **kwargs): provider.enable_manualsearch = 0 # these exceptions are actually catching unselected checkboxes if hasattr(provider, 'enable_search_delay'): - try: - provider.enable_search_delay = config.checkbox_to_value( - kwargs['{id}_enable_search_delay'.format(id=provider.get_id())]) - except (AttributeError, KeyError): - provider.enable_search_delay = 0 # these exceptions are actually catching unselected checkboxes + try: + provider.enable_search_delay = config.checkbox_to_value( + kwargs['{id}_enable_search_delay'.format(id=provider.get_id())]) + except (AttributeError, KeyError): + provider.enable_search_delay = 0 # these exceptions are actually catching unselected checkboxes if hasattr(provider, 'search_delay'): try: diff --git a/medusa/server/web/config/subtitles.py b/medusa/server/web/config/subtitles.py index eba0c739c2..fdf22e4128 100644 --- a/medusa/server/web/config/subtitles.py +++ b/medusa/server/web/config/subtitles.py @@ -66,8 +66,8 @@ def saveSubtitles(self, use_subtitles=None, subtitles_plugins=None, subtitles_la services_str_list = service_order.split() subtitles_services_list = [] subtitles_services_enabled = [] - for curServiceStr in services_str_list: - cur_service, cur_enabled = curServiceStr.split(':') + for cur_service_str in services_str_list: + cur_service, cur_enabled = cur_service_str.split(':') subtitles_services_list.append(cur_service) subtitles_services_enabled.append(int(cur_enabled)) diff --git a/medusa/server/web/core/base.py b/medusa/server/web/core/base.py index 1a5a93ad16..ba951b016c 100644 --- a/medusa/server/web/core/base.py +++ b/medusa/server/web/core/base.py @@ -4,6 +4,7 @@ import os import re +import sys import time import traceback from builtins import str @@ -43,7 +44,6 @@ from tornroutes import route - mako_lookup = None mako_cache = None mako_path = None @@ -210,7 +210,11 @@ def get_current_user(self): class WebHandler(BaseHandler): """Base Handler for the web server.""" - executor = ThreadPoolExecutor(thread_name_prefix='Thread') + # Python 3.5 doesn't support thread_name_prefix + if sys.version_info[:2] == (3, 5): + executor = ThreadPoolExecutor() + else: + executor = ThreadPoolExecutor(thread_name_prefix='Thread') def __init__(self, *args, **kwargs): super(WebHandler, self).__init__(*args, **kwargs) diff --git a/medusa/server/web/core/error_logs.py b/medusa/server/web/core/error_logs.py index 9148951745..5fdba4c778 100644 --- a/medusa/server/web/core/error_logs.py +++ b/medusa/server/web/core/error_logs.py @@ -13,7 +13,7 @@ from medusa.issue_submitter import IssueSubmitter from medusa.logger import filter_logline, read_loglines from medusa.server.web.core.base import PageTemplate, WebRoot -from medusa.version_checker import CheckVersion +from medusa.updater.version_checker import CheckVersion from six import text_type @@ -22,7 +22,7 @@ log = logging.getLogger(__name__) log_name_filters = { - None: html_escape(''), + '': html_escape(''), 'DAILYSEARCHER': 'Daily Searcher', 'BACKLOG': 'Backlog', 'SHOWUPDATER': 'Show Updater', @@ -140,17 +140,17 @@ def viewlog(self, min_level=logging.INFO, log_filter=None, log_search=None, max_ period = log_periods.get(log_period) modification_time = datetime.now() - period if period else None - data = [line for line in read_loglines(modification_time=modification_time, formatter=text_type, max_lines=max_lines, - predicate=lambda l: filter_logline(l, min_level=min_level, - thread_name=thread_names.get(log_filter, log_filter), - search_query=log_search))] + data = (html_escape(line) for line in read_loglines(modification_time=modification_time, formatter=text_type, max_lines=max_lines, + predicate=lambda l: filter_logline(l, min_level=min_level, + thread_name=thread_names.get(log_filter, log_filter), + search_query=log_search))) if not text_view: - return t.render(log_lines='\n'.join([html_escape(line) for line in data]), + return t.render(log_lines='\n'.join(data), min_level=min_level, log_name_filters=log_name_filters, log_filter=log_filter, log_search=log_search, log_period=log_period, controller='errorlogs', action='viewlogs') else: - return '
'.join([html_escape(line) for line in data]) + return '
'.join(data) def submit_errors(self): """Create an issue in medusa issue tracker.""" diff --git a/medusa/server/web/home/add_shows.py b/medusa/server/web/home/add_shows.py index 7032f9be06..7bf8aad5e8 100644 --- a/medusa/server/web/home/add_shows.py +++ b/medusa/server/web/home/add_shows.py @@ -53,6 +53,14 @@ def json_response(result=True, message=None, redirect=None, params=None): }) +def decode_shows(names): + """Decode show names to UTF-8.""" + return [ + name.decode('utf-8') if not isinstance(name, text_type) else name + for name in names + ] + + @route('/addShows(/?.*)') class HomeAddShows(Home): def __init__(self, *args, **kwargs): @@ -96,9 +104,9 @@ def newShow(self, show_to_add=None, other_shows=None, search_string=None): elif not isinstance(other_shows, list): other_shows = [other_shows] + other_shows = decode_shows(other_shows) provided_indexer_id = int(indexer_id or 0) provided_indexer_name = show_name - provided_indexer = int(indexer or app.INDEXER_DEFAULT) return t.render( @@ -151,8 +159,12 @@ def getTrendingShows(self, traktList=None): Display the new show page which collects a tvdb id, folder, and extra options and posts them to addNewShow """ - e = None + error = None t = PageTemplate(rh=self, filename='addShows_recommended.mako') + trakt_blacklist = False + recommended_shows = None + removed_from_medusa = None + if traktList is None: traktList = '' @@ -182,28 +194,26 @@ def getTrendingShows(self, traktList=None): try: (trakt_blacklist, recommended_shows, removed_from_medusa) = TraktPopular().fetch_popular_shows(page_url=page_url, trakt_list=traktList) except Exception as e: - # print traceback.format_exc() - trakt_blacklist = False - recommended_shows = None - removed_from_medusa = None + error = e return t.render(trakt_blacklist=trakt_blacklist, recommended_shows=recommended_shows, removed_from_medusa=removed_from_medusa, - exception=e, enable_anime_options=False, blacklist=[], whitelist=[], realpage='getTrendingShows') + exception=error, enable_anime_options=False, blacklist=[], whitelist=[], realpage='getTrendingShows') def popularShows(self): """ Fetches data from IMDB to show a list of popular shows. """ t = PageTemplate(rh=self, filename='addShows_recommended.mako') - e = None + recommended_shows = None + error = None try: recommended_shows = ImdbPopular().fetch_popular_shows() except (RequestException, Exception) as e: - recommended_shows = None + error = e return t.render(title='Popular Shows', header='Popular Shows', - recommended_shows=recommended_shows, exception=e, groups=[], + recommended_shows=recommended_shows, exception=error, groups=[], enable_anime_options=True, blacklist=[], whitelist=[], controller='addShows', action='recommendedShows', realpage='popularShows') @@ -212,16 +222,16 @@ def popularAnime(self, list_type=REQUEST_HOT): Fetches list recommeded shows from anidb.info. """ t = PageTemplate(rh=self, filename='addShows_recommended.mako') - e = None + recommended_shows = None + error = None try: recommended_shows = AnidbPopular().fetch_popular_shows(list_type) except Exception as e: - # print traceback.format_exc() - recommended_shows = None + error = e return t.render(title='Popular Anime Shows', header='Popular Anime Shows', - recommended_shows=recommended_shows, exception=e, groups=[], + recommended_shows=recommended_shows, exception=error, groups=[], enable_anime_options=True, blacklist=[], whitelist=[], controller='addShows', action='recommendedShows', realpage='popularAnime') @@ -272,12 +282,12 @@ def addShowByID(self, indexername=None, seriesid=None, show_name=None, which_ser if not series_id: log.info('Unable to find tvdb ID to add {name}', {'name': show_name}) ui.notifications.error( - 'Unable to add %s' % show_name, - 'Could not add %s. We were unable to locate the tvdb id at this time.' % show_name + 'Unable to add {0}'.format(show_name), + 'Could not add {0}. We were unable to locate the tvdb id at this time.'.format(show_name) ) return json_response( result=False, - message='Unable to find tvdb ID to add {0}'.format(show=show_name) + message='Unable to find tvdb ID to add {show}'.format(show=show_name) ) if Show.find_by_id(app.showList, INDEXER_TVDBV2, series_id): @@ -384,6 +394,8 @@ def addNewShow(self, whichSeries=None, indexer_lang=None, rootDir=None, defaultS elif not isinstance(other_shows, list): other_shows = [other_shows] + other_shows = decode_shows(other_shows) + def finishAddShow(): # if there are no extra shows then go home if not other_shows: @@ -535,8 +547,7 @@ def addExistingShows(self, shows_to_add=None, promptForSettings=None): elif not isinstance(shows_to_add, list): shows_to_add = [shows_to_add] - shows_to_add = [text_type(x, 'utf-8') if not isinstance(x, text_type) else x for x in shows_to_add] - + shows_to_add = decode_shows(shows_to_add) prompt_for_settings = config.checkbox_to_value(prompt_for_settings) indexer_id_given = [] diff --git a/medusa/server/web/home/handler.py b/medusa/server/web/home/handler.py index b8ba3599c7..b3184813a6 100644 --- a/medusa/server/web/home/handler.py +++ b/medusa/server/web/home/handler.py @@ -33,7 +33,6 @@ DOWNLOADED, FAILED, IGNORED, - Overview, Quality, SKIPPED, SNATCHED, @@ -105,7 +104,7 @@ from medusa.system.restart import Restart from medusa.system.shutdown import Shutdown from medusa.tv.series import Series, SeriesIdentifier -from medusa.version_checker import CheckVersion +from medusa.updater.version_checker import CheckVersion from requests.compat import ( quote_plus, @@ -796,17 +795,9 @@ def displayShow(self, indexername=None, seriesid=None, ): if series_obj is None: return self._genericMessage('Error', 'Show not in show list') - main_db_con = db.DBConnection() - season_results = main_db_con.select( - 'SELECT DISTINCT season ' - 'FROM tv_episodes ' - 'WHERE indexer = ? AND showid = ? AND season IS NOT NULL ' - 'ORDER BY season DESC', - [series_obj.indexer, series_obj.series_id] - ) - min_season = 0 if app.DISPLAY_SHOW_SPECIALS else 1 + main_db_con = db.DBConnection() sql_results = main_db_con.select( 'SELECT * ' 'FROM tv_episodes ' @@ -822,34 +813,6 @@ def displayShow(self, indexername=None, seriesid=None, ): 'icon': 'ui-icon ui-icon-pencil', }] - try: - show_loc = (series_obj.location, True) - except ShowDirectoryNotFoundException: - show_loc = (series_obj._location, False) # pylint: disable=protected-access - - show_message = '' - - if app.show_queue_scheduler.action.isBeingAdded(series_obj): - show_message = 'This show is in the process of being downloaded - the info below is incomplete.' - - elif app.show_queue_scheduler.action.isBeingUpdated(series_obj): - show_message = 'The information on this page is in the process of being updated.' - - elif app.show_queue_scheduler.action.isBeingRefreshed(series_obj): - show_message = 'The episodes below are currently being refreshed from disk' - - elif app.show_queue_scheduler.action.isBeingSubtitled(series_obj): - show_message = 'Currently downloading subtitles for this show' - - elif app.show_queue_scheduler.action.isInRefreshQueue(series_obj): - show_message = 'This show is queued to be refreshed.' - - elif app.show_queue_scheduler.action.isInUpdateQueue(series_obj): - show_message = 'This show is queued and awaiting an update.' - - elif app.show_queue_scheduler.action.isInSubtitleQueue(series_obj): - show_message = 'This show is queued and awaiting subtitles download.' - if not app.show_queue_scheduler.action.isBeingAdded(series_obj): if not app.show_queue_scheduler.action.isBeingUpdated(series_obj): submenu.append({ @@ -900,27 +863,12 @@ def displayShow(self, indexername=None, seriesid=None, ): 'icon': 'menu-icon-backlog', }) - ep_counts = { - Overview.SKIPPED: 0, - Overview.WANTED: 0, - Overview.QUAL: 0, - Overview.GOOD: 0, - Overview.UNAIRED: 0, - Overview.SNATCHED: 0, - Overview.SNATCHED_PROPER: 0, - Overview.SNATCHED_BEST: 0 - } ep_cats = {} for cur_result in sql_results: cur_ep_cat = series_obj.get_overview(cur_result['status'], cur_result['quality'], manually_searched=cur_result['manually_searched']) if cur_ep_cat: ep_cats['s{season}e{episode}'.format(season=cur_result['season'], episode=cur_result['episode'])] = cur_ep_cat - ep_counts[cur_ep_cat] += 1 - - bwl = None - if series_obj.is_anime: - bwl = series_obj.release_groups series_obj.exceptions = get_scene_exceptions(series_obj) @@ -944,15 +892,13 @@ def displayShow(self, indexername=None, seriesid=None, ): }) return t.render( - submenu=submenu[::-1], showLoc=show_loc, show_message=show_message, - show=series_obj, sql_results=sql_results, season_results=season_results, - bwl=bwl, ep_counts=ep_counts, - ep_cats=ep_cats, all_scene_exceptions=' | '.join(series_obj.exceptions), + submenu=submenu[::-1], + show=series_obj, sql_results=sql_results, ep_cats=ep_cats, scene_numbering=get_scene_numbering_for_show(series_obj), xem_numbering=get_xem_numbering_for_show(series_obj, refresh_data=False), scene_absolute_numbering=get_scene_absolute_numbering_for_show(series_obj), xem_absolute_numbering=get_xem_absolute_numbering_for_show(series_obj), - title=series_obj.name, controller='home', action='displayShow', + controller='home', action='displayShow', ) def pickManualSearch(self, provider=None, rowid=None): @@ -1145,13 +1091,6 @@ def snatchSelection(self, indexername, seriesid, season=None, episode=None, manu 'icon': 'ui-icon ui-icon-pencil' }] - try: - show_loc = (series_obj.location, True) - except ShowDirectoryNotFoundException: - show_loc = (series_obj._location, False) # pylint: disable=protected-access - - show_message = app.show_queue_scheduler.action.getQueueActionMessage(series_obj) - if not app.show_queue_scheduler.action.isBeingAdded(series_obj): if not app.show_queue_scheduler.action.isBeingUpdated(series_obj): submenu.append({ @@ -1202,10 +1141,6 @@ def snatchSelection(self, indexername, seriesid, season=None, episode=None, manu 'icon': 'ui-icon ui-icon-comment', }) - bwl = None - if series_obj.is_anime: - bwl = series_obj.release_groups - series_obj.exceptions = get_scene_exceptions(series_obj) indexer_id = int(series_obj.indexer) @@ -1289,59 +1224,11 @@ def snatchSelection(self, indexername, seriesid, season=None, episode=None, manu except Exception as msg: logger.log("Couldn't read latest episode status. Error: {error}".format(error=msg)) - # There is some logic for this in the partials/showheader.mako page. - main_db_con = db.DBConnection() - season_results = main_db_con.select( - 'SELECT DISTINCT season ' - 'FROM tv_episodes ' - 'WHERE indexer = ? AND showid = ? AND season IS NOT NULL ' - 'ORDER BY season DESC', - [series_obj.indexer, series_obj.series_id] - ) - - min_season = 0 if app.DISPLAY_SHOW_SPECIALS else 1 - - sql_results = main_db_con.select( - 'SELECT * ' - 'FROM tv_episodes ' - 'WHERE indexer = ? AND showid = ? AND season >= ? ' - 'ORDER BY season DESC, episode DESC', - [series_obj.indexer, series_obj.series_id, min_season] - ) - - ep_counts = { - Overview.SKIPPED: 0, - Overview.WANTED: 0, - Overview.QUAL: 0, - Overview.GOOD: 0, - Overview.UNAIRED: 0, - Overview.SNATCHED: 0, - Overview.SNATCHED_PROPER: 0, - Overview.SNATCHED_BEST: 0 - } - - ep_cats = {} - - for cur_result in sql_results: - cur_ep_cat = series_obj.get_overview(cur_result['status'], cur_result['quality'], - manually_searched=cur_result['manually_searched']) - if cur_ep_cat: - ep_cats['s{season}e{episode}'.format(season=cur_result['season'], - episode=cur_result['episode'])] = cur_ep_cat - ep_counts[cur_ep_cat] += 1 - return t.render( - submenu=submenu[::-1], showLoc=show_loc, show_message=show_message, - show=series_obj, provider_results=provider_results, episode=episode, - bwl=bwl, season=season, manual_search_type=manual_search_type, - all_scene_exceptions=' | '.join(series_obj.exceptions), - scene_numbering=get_scene_numbering_for_show(series_obj), - xem_numbering=get_xem_numbering_for_show(series_obj, refresh_data=False), - scene_absolute_numbering=get_scene_absolute_numbering_for_show(series_obj), - xem_absolute_numbering=get_xem_absolute_numbering_for_show(series_obj), - title=series_obj.name, controller='home', action='snatchSelection', - episode_history=episode_history, season_results=season_results, sql_results=sql_results, - ep_counts=ep_counts, ep_cats=ep_cats + submenu=submenu[::-1], show=series_obj, + provider_results=provider_results, episode_history=episode_history, + season=season, episode=episode, manual_search_type=manual_search_type, + controller='home', action='snatchSelection' ) @staticmethod @@ -1466,11 +1353,11 @@ def editShow(self, indexername=None, seriesid=None, location=None, allowed_quali except IndexerShowNotFoundInLanguage: errors += 1 status = 'Could not change language to' - except IndexerException as e: + except IndexerException as error: errors += 1 status = u'Failed getting show in' - msg += u' Please try again later. Error: {error}'.format( - error=e.message, + msg += u' Please try again later. Error: {error!r}'.format( + error=error, ) else: language = indexer_lang @@ -1535,10 +1422,10 @@ def editShow(self, indexername=None, seriesid=None, location=None, allowed_quali series_obj.season_folders = season_folders try: app.show_queue_scheduler.action.refreshShow(series_obj) - except CantRefreshShowException as e: + except CantRefreshShowException as error: errors += 1 - logger.log("Unable to refresh show '{show}': {error}".format - (show=series_obj.name, error=e.message), logger.WARNING) + logger.log("Unable to refresh show '{show}': {error!r}".format + (show=series_obj.name, error=error), logger.WARNING) # Check if we should erase parsed cached results for that show do_erase_parsed_cache = False @@ -1595,10 +1482,10 @@ def editShow(self, indexername=None, seriesid=None, location=None, allowed_quali if (do_update or changed_location) and os.path.isdir(new_location): try: app.show_queue_scheduler.action.refreshShow(series_obj) - except CantRefreshShowException as e: + except CantRefreshShowException as error: errors += 1 - logger.log("Unable to refresh show '{show}'. Error: {error}".format - (show=series_obj.name, error=e.message), logger.WARNING) + logger.log("Unable to refresh show '{show}'. Error: {error!r}".format + (show=series_obj.name, error=error), logger.WARNING) # Save all settings changed while in series_obj.lock series_obj.save_to_db() @@ -1608,29 +1495,29 @@ def editShow(self, indexername=None, seriesid=None, location=None, allowed_quali try: app.show_queue_scheduler.action.updateShow(series_obj) time.sleep(cpu_presets[app.CPU_PRESET]) - except CantUpdateShowException as e: + except CantUpdateShowException as error: errors += 1 - logger.log("Unable to update show '{show}': {error}".format - (show=series_obj.name, error=e.message), logger.WARNING) + logger.log("Unable to update show '{show}': {error!r}".format + (show=series_obj.name, error=error), logger.WARNING) if do_update_exceptions: try: update_scene_exceptions(series_obj, exceptions) time.sleep(cpu_presets[app.CPU_PRESET]) name_cache.build_name_cache(series_obj) - except CantUpdateShowException: + except CantUpdateShowException as error: errors += 1 - logger.log("Unable to force an update on scene exceptions for show '{show}': {error}".format - (show=series_obj.name, error=e.message), logger.WARNING) + logger.log("Unable to force an update on scene exceptions for show '{show}': {error!r}".format + (show=series_obj.name, error=error), logger.WARNING) if do_update_scene_numbering or do_erase_parsed_cache: try: xem_refresh(series_obj) time.sleep(cpu_presets[app.CPU_PRESET]) - except CantUpdateShowException: + except CantUpdateShowException as error: errors += 1 - logger.log("Unable to force an update on scene numbering for show '{show}': {error}".format - (show=series_obj.name, error=e.message), logger.WARNING) + logger.log("Unable to force an update on scene numbering for show '{show}': {error!r}".format + (show=series_obj.name, error=error), logger.WARNING) # Must erase cached DB results when toggling scene numbering self.erase_cache(series_obj) @@ -1642,10 +1529,10 @@ def editShow(self, indexername=None, seriesid=None, location=None, allowed_quali # Need to refresh show as we updated scene numbering or changed show format try: app.show_queue_scheduler.action.refreshShow(series_obj) - except CantRefreshShowException as e: + except CantRefreshShowException as error: errors += 1 logger.log("Unable to refresh show '{show}'. Please manually trigger a full show refresh. " - 'Error: {error}'.format(show=series_obj.name, error=e.message), logger.WARNING) + 'Error: {error!r}'.format(show=series_obj.name, error=error), logger.WARNING) if directCall: return errors @@ -2016,7 +1903,7 @@ def testRename(self, indexername=None, seriesid=None): return self._genericMessage('Error', 'Show not in show list') try: - series_obj.location # @UnusedVariable + series_obj.validate_location # @UnusedVariable except ShowDirectoryNotFoundException: return self._genericMessage('Error', 'Can\'t rename episodes when the show dir is missing.') @@ -2051,7 +1938,7 @@ def doRename(self, indexername=None, seriesid=None, eps=None): return self._genericMessage('Error', error_message) try: - series_obj.location # @UnusedVariable + series_obj.validate_location # @UnusedVariable except ShowDirectoryNotFoundException: return self._genericMessage('Error', 'Can\'t rename episodes when the show dir is missing.') diff --git a/medusa/server/web/manage/handler.py b/medusa/server/web/manage/handler.py index c1c1927bfe..f99eccf004 100644 --- a/medusa/server/web/manage/handler.py +++ b/medusa/server/web/manage/handler.py @@ -303,8 +303,8 @@ def downloadSubtitleMissed(self, *args, **kwargs): to_download[(cur_indexer_id, cur_series_id)] = ['s' + str(x['season']) + 'e' + str(x['episode']) for x in all_eps_results] - for epResult in to_download[(cur_indexer_id, cur_series_id)]: - season, episode = epResult.lstrip('s').split('e') + for ep_result in to_download[(cur_indexer_id, cur_series_id)]: + season, episode = ep_result.lstrip('s').split('e') series_obj = Show.find_by_id(app.showList, cur_indexer_id, cur_series_id) series_obj.get_episode(season, episode).download_subtitles() diff --git a/medusa/session/core.py b/medusa/session/core.py index 64e28f7472..4d228fffd4 100644 --- a/medusa/session/core.py +++ b/medusa/session/core.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals +import collections import errno import logging import traceback @@ -161,7 +162,8 @@ def request(self, method, url, data=None, params=None, headers=None, timeout=30, log.debug(u'Error requesting url {url} Error: {err_msg}', url=url, err_msg=error) return resp or error.response except Exception as error: - if u'ECONNRESET' in error or (hasattr(error, u'errno') and error.errno == errno.ECONNRESET): + if ((isinstance(error, collections.Iterable) and u'ECONNRESET' in error) or + (hasattr(error, u'errno') and error.errno == errno.ECONNRESET)): log.warning( u'Connection reset by peer accessing url {url} Error: {err_msg}'.format(url=url, err_msg=error) ) diff --git a/medusa/session/handlers.py b/medusa/session/handlers.py index 1efc7f388d..cf7d120c25 100644 --- a/medusa/session/handlers.py +++ b/medusa/session/handlers.py @@ -80,6 +80,6 @@ def is_cloudflare_challenge(resp): return ( resp.status_code == 503 and resp.headers.get('Server', '').startswith('cloudflare') and - 'jschl_vc' in resp.content and - 'jschl_answer' in resp.content + b'jschl_vc' in resp.content and + b'jschl_answer' in resp.content ) diff --git a/medusa/session/hooks.py b/medusa/session/hooks.py index 5774f10cfc..bd3c3ada9a 100644 --- a/medusa/session/hooks.py +++ b/medusa/session/hooks.py @@ -6,7 +6,7 @@ from medusa.logger.adapters.style import BraceAdapter -from six import text_type +from six import ensure_text log = BraceAdapter(logging.getLogger(__name__)) log.logger.addHandler(logging.NullHandler()) @@ -26,28 +26,12 @@ def log_url(response, **kwargs): if request.method.upper() == 'POST': if request.body: + text_body = ensure_text(request.body, errors='replace') if 'multipart/form-data' not in request.headers.get('content-type', ''): - body = request.body + body = text_body + elif len(text_body) > 99: + body = text_body[0:99].replace('\n', ' ') + '...' else: - body = request.body[1:99].replace('\n', ' ') + '...' - else: - body = '' + body = text_body.replace('\n', ' ') - # try to log post data using various codecs to decode - if isinstance(body, text_type): log.debug('With post data: {0}', body) - return - - codecs = ('utf-8', 'latin1', 'cp1252') - for codec in codecs: - try: - data = body.decode(codec) - except UnicodeError as error: - log.debug('Failed to decode post data as {codec}: {msg}', - {'codec': codec, 'msg': error}) - else: - log.debug('With post data: {0}', data) - break - else: - log.warning('Failed to decode post data with {codecs}', - {'codecs': codecs}) diff --git a/medusa/show/naming.py b/medusa/show/naming.py index f5101b60b0..4942efd464 100644 --- a/medusa/show/naming.py +++ b/medusa/show/naming.py @@ -19,17 +19,17 @@ log.logger.addHandler(logging.NullHandler()) -resultFilters = [ +result_filters = [ '(sub|nfo)fix', '(?13s}:{1:<5s}] score = {2:3d}/{3:3d} for {4}'.format( - subtitle.provider_name, subtitle.language, score, min_score, get_subtitle_description(subtitle))) + subtitle.provider_name, text_type(subtitle.language), score, + min_score, get_subtitle_description(subtitle))) found_subtitles = pool.download_best_subtitles(subtitles_list, video, languages=languages, hearing_impaired=app.SUBTITLES_HEARING_IMPAIRED, @@ -473,8 +475,8 @@ def save_subs(tv_episode, video, found_subtitles, video_path=None): episode_name = tv_episode.name show_indexerid = tv_episode.series.indexerid subtitles_dir = get_subtitles_dir(video_path) - saved_subtitles = save_subtitles(video, found_subtitles, directory=_encode(subtitles_dir), - single=not app.SUBTITLES_MULTI) + saved_subtitles = save_subtitles(video, found_subtitles, directory=subtitles_dir, + single=not app.SUBTITLES_MULTI, encoding='utf-8') for subtitle in saved_subtitles: logger.info(u'Found subtitle for %s in %s provider with language %s', os.path.basename(video_path), @@ -713,15 +715,14 @@ def get_video(tv_episode, video_path, subtitles_dir=None, subtitles=True, embedd return cached_payload['video'] video_is_mkv = video_path.endswith('.mkv') - video_path = _encode(video_path) - subtitles_dir = _encode(subtitles_dir or get_subtitles_dir(video_path)) + subtitles_dir = subtitles_dir or get_subtitles_dir(video_path) logger.debug(u'Scanning video %s...', video_path) try: video = scan_video(video_path) - except ValueError as e: - logger.warning(u'Unable to scan video: %s. Error: %s', video_path, e.message) + except ValueError as error: + logger.warning(u'Unable to scan video: %s. Error: %r', video_path, error) else: # Add hash of our custom provider Itasa diff --git a/medusa/system/restart.py b/medusa/system/restart.py index 2e5352ebc4..30449f9892 100644 --- a/medusa/system/restart.py +++ b/medusa/system/restart.py @@ -2,12 +2,11 @@ from __future__ import unicode_literals -from builtins import object -from builtins import str - from medusa import app from medusa.event_queue import Events +from six import text_type + class Restart(object): def __init__(self): @@ -15,7 +14,7 @@ def __init__(self): @staticmethod def restart(pid): - if str(pid) != str(app.PID): + if text_type(pid) != text_type(app.PID): return False app.events.put(Events.SystemEvent.RESTART) diff --git a/medusa/themes/base.py b/medusa/themes/base.py index cbb9a74f94..9c581088ab 100644 --- a/medusa/themes/base.py +++ b/medusa/themes/base.py @@ -28,7 +28,8 @@ def read_themes(): """Read the theme folder and create a Theme object for every entry, if valid.""" themes = [] theme_root = os.path.join(app.PROG_DIR, 'themes') - themes_from_fs = [os.path.join(theme_root, theme_dir) for theme_dir in os.listdir(theme_root) if os.path.isdir(os.path.join(theme_root, theme_dir))] + themes_from_fs = [os.path.join(theme_root, theme_dir) for theme_dir in os.listdir(theme_root) + if os.path.isdir(os.path.join(theme_root, theme_dir))] for theme_path in themes_from_fs: # validate the directory structure try: @@ -70,7 +71,8 @@ def validate_theme(theme_path): 'Please refer to the medusa theming documentation.'.format(check_folder=check_folder)) try: - package_json = json.load(open(os.path.join(theme_path, 'package.json'))) + with open(os.path.join(theme_path, 'package.json')) as pj: + package_json = json.load(pj) except IOError: raise Exception('Cannot read package.json. Please refer to the medusa theming documentation.') @@ -79,7 +81,8 @@ def validate_theme(theme_path): raise Exception("As a bare minimum you'll need at least to provide the 'name' and and 'version' key. " 'Please refer to the medusa theming documentation.') - if not os.path.isdir(os.path.join(theme_path, 'templates')) and not os.path.isfile(os.path.join(theme_path, 'index.html')): + if (not os.path.isdir(os.path.join(theme_path, 'templates')) and + not os.path.isfile(os.path.join(theme_path, 'index.html'))): raise Exception('You need to have at least a templates folder with mako temnplates, ' "or an index.html in your [theme's] root. Please refer to the medusa theming documentation.") diff --git a/medusa/trakt_checker.py b/medusa/trakt_checker.py index f0c743e104..ca9eae7c2e 100644 --- a/medusa/trakt_checker.py +++ b/medusa/trakt_checker.py @@ -113,8 +113,8 @@ def find_show(self, indexerid, indexer): trakt_library = [] try: trakt_library = self._request('sync/collection/shows') - except (TraktException, AuthException, TokenExpiredException) as e: - log.info('Unable to retrieve shows from Trakt collection. Error: {error}', {'error': e.message}) + except (TraktException, AuthException, TokenExpiredException) as error: + log.info('Unable to retrieve shows from Trakt collection. Error: {error!r}', {'error': error}) if not trakt_library: log.info('No shows found in your Trakt library. Nothing to sync') @@ -152,18 +152,18 @@ def remove_show_trakt_library(self, show_obj): # Remove all episodes from the Trakt collection for this show try: self.remove_episode_trakt_collection(filter_show=show_obj) - except (TraktException, AuthException, TokenExpiredException) as e: - log.info("Unable to remove all episodes from show '{show}' from Trakt library. Error: {error}", { + except (TraktException, AuthException, TokenExpiredException) as error: + log.info("Unable to remove all episodes from show '{show}' from Trakt library. Error: {error!r}", { 'show': show_obj.name, - 'error': e.message + 'error': error }) try: self._request('sync/collection/remove', data, method='POST') - except (TraktException, AuthException, TokenExpiredException) as e: - log.info("Unable to remove show '{show}' from Trakt library. Error: {error}", { + except (TraktException, AuthException, TokenExpiredException) as error: + log.info("Unable to remove show '{show}' from Trakt library. Error: {error!r}", { 'show': show_obj.name, - 'error': e.message + 'error': error }) def add_show_trakt_library(self, show_obj): @@ -195,10 +195,10 @@ def add_show_trakt_library(self, show_obj): try: self._request('sync/collection', data, method='POST') - except (TraktException, AuthException, TokenExpiredException) as e: - log.info("Unable to add show '{show}' to Trakt library. Error: {error}", { + except (TraktException, AuthException, TokenExpiredException) as error: + log.info("Unable to add show '{show}' to Trakt library. Error: {error!r}", { 'show': show_obj.name, - 'error': e.message + 'error': error }) return @@ -260,9 +260,9 @@ def remove_episode_trakt_collection(self, filter_show=None): data = self.trakt_bulk_data_generate(trakt_data) self._request('sync/collection/remove', data, method='POST') self._get_show_collection() - except (TraktException, AuthException, TokenExpiredException) as e: - log.info('Unable to remove episodes from Trakt collection. Error: {error}', { - 'error': e.message + except (TraktException, AuthException, TokenExpiredException) as error: + log.info('Unable to remove episodes from Trakt collection. Error: {error!r}', { + 'error': error }) def add_episode_trakt_collection(self): @@ -307,8 +307,8 @@ def add_episode_trakt_collection(self): data = self.trakt_bulk_data_generate(trakt_data) self._request('sync/collection', data, method='POST') self._get_show_collection() - except (TraktException, AuthException, TokenExpiredException) as e: - log.info('Unable to add episodes to Trakt collection. Error: {error}', {'error': e.message}) + except (TraktException, AuthException, TokenExpiredException) as error: + log.info('Unable to add episodes to Trakt collection. Error: {error!r}', {'error': error}) def sync_watchlist(self): """Sync Trakt watchlist.""" @@ -369,9 +369,9 @@ def remove_episode_watchlist(self): data = self.trakt_bulk_data_generate(trakt_data) self._request('sync/watchlist/remove', data, method='POST') self._get_episode_watchlist() - except (TraktException, AuthException, TokenExpiredException) as e: - log.info('Unable to remove episodes from Trakt watchlist. Error: {error}', { - 'error': e.message + except (TraktException, AuthException, TokenExpiredException) as error: + log.info('Unable to remove episodes from Trakt watchlist. Error: {error!r}', { + 'error': error }) def add_episode_watchlist(self): @@ -411,9 +411,9 @@ def add_episode_watchlist(self): data = self.trakt_bulk_data_generate(trakt_data) self._request('sync/watchlist', data, method='POST') self._get_episode_watchlist() - except (TraktException, AuthException, TokenExpiredException) as e: - log.info('Unable to add episode to Trakt watchlist. Error: {error}', { - 'error': e.message + except (TraktException, AuthException, TokenExpiredException) as error: + log.info('Unable to add episode to Trakt watchlist. Error: {error!r}', { + 'error': error }) def add_show_watchlist(self): @@ -436,8 +436,8 @@ def add_show_watchlist(self): try: data = {'shows': trakt_data} self._request('sync/watchlist', data, method='POST') - except (TraktException, AuthException, TokenExpiredException) as e: - log.info('Unable to add shows to Trakt watchlist. Error: {error}', {'error': e.message}) + except (TraktException, AuthException, TokenExpiredException) as error: + log.info('Unable to add shows to Trakt watchlist. Error: {error!r}', {'error': error}) self._get_show_watchlist() def remove_from_library(self): @@ -456,10 +456,10 @@ def remove_from_library(self): try: progress = self._request('shows/{0}/progress/watched'.format(trakt_id or show.imdb_id)) - except (TraktException, AuthException, TokenExpiredException) as e: - log.info("Unable to check if show '{show}' is ended/completed. Error: {error}", { + except (TraktException, AuthException, TokenExpiredException) as error: + log.info("Unable to check if show '{show}' is ended/completed. Error: {error!r}", { 'show': show.name, - 'error': e.message + 'error': error }) continue else: @@ -655,8 +655,8 @@ def _get_show_watchlist(self): """Get shows watchlist.""" try: self.show_watchlist = self._request('sync/watchlist/shows') - except (TraktException, AuthException, TokenExpiredException) as e: - log.info(u'Unable to retrieve shows from Trakt watchlist. Error: {error}', {'error': e.message}) + except (TraktException, AuthException, TokenExpiredException) as error: + log.info(u'Unable to retrieve shows from Trakt watchlist. Error: {error!r}', {'error': error}) return False return True @@ -664,8 +664,8 @@ def _get_episode_watchlist(self): """Get episodes watchlist.""" try: self.episode_watchlist = self._request('sync/watchlist/episodes') - except (TraktException, AuthException, TokenExpiredException) as e: - log.info(u'Unable to retrieve episodes from Trakt watchlist. Error: {error}', {'error': e.message}) + except (TraktException, AuthException, TokenExpiredException) as error: + log.info(u'Unable to retrieve episodes from Trakt watchlist. Error: {error!r}', {'error': error}) return False return True @@ -673,8 +673,8 @@ def _get_show_collection(self): """Get show collection.""" try: self.collection_list = self._request('sync/collection/shows') - except (TraktException, AuthException, TokenExpiredException) as e: - log.info('Unable to retrieve shows from Trakt collection. Error: {error}', {'error': e.message}) + except (TraktException, AuthException, TokenExpiredException) as error: + log.info('Unable to retrieve shows from Trakt collection. Error: {error!r}', {'error': error}) return False return True diff --git a/medusa/tv/cache.py b/medusa/tv/cache.py index b2d97a5ddc..a166115fbb 100644 --- a/medusa/tv/cache.py +++ b/medusa/tv/cache.py @@ -419,7 +419,7 @@ def add_cache_entry(self, name, url, seeders, leechers, size, pubdate, parsed_re proper_tags = '|'.join(parse_result.proper_tags) if not self.item_in_cache(url): - log.debug('Added item: {0} to cache: {1} with url {2}', name, self.provider_id, url) + log.debug('Added item: {0} to cache: {1} with url: {2}', name, self.provider_id, url) return [ 'INSERT INTO [{name}] ' ' (name, season, episodes, indexerid, url, time, quality, ' diff --git a/medusa/tv/episode.py b/medusa/tv/episode.py index f08ed41b0b..a6138a5867 100644 --- a/medusa/tv/episode.py +++ b/medusa/tv/episode.py @@ -303,6 +303,12 @@ def __getattr__(self, item): ) return super(Episode, self).__getattribute__(refactor) + def __eq__(self, other): + """Override default equalize implementation.""" + return all([self.series.identifier == other.series.identifier, + self.season == other.season, + self.episode == other.episode]) + @classmethod def find_by_series_and_episode(cls, series, episode_number): """Find Episode based on series and episode number. @@ -404,13 +410,14 @@ def air_date(self): if self.airdate == date.min: return None - return sbdatetime.convert_to_setting( + date_parsed = sbdatetime.convert_to_setting( network_timezones.parse_date_time( date.toordinal(self.airdate), self.series.airs, - self.series.network - ) - ).isoformat(b'T') + self.series.network) + ) + + return date_parsed.isoformat() @property def status_name(self): @@ -645,6 +652,7 @@ def load_from_db(self, season, episode): self.indexerid = int(sql_results[0]['indexerid']) self.indexer = int(sql_results[0]['indexer']) + # FIXME: This shouldn't be part of a possible apiv2 episodes request xem_refresh(self.series) self.scene_season = try_int(sql_results[0]['scene_season'], 0) @@ -864,7 +872,7 @@ def load_from_indexer(self, season=None, episode=None, tvapi=None, cached_season '{id}: {series} episode statuses unchanged. Location is missing: {location}', { 'id': self.series.series_id, 'series': self.series.name, - 'location': self.series.raw_location, + 'location': self.series.location, } ) return diff --git a/medusa/tv/series.py b/medusa/tv/series.py index 7e992d942b..26653b10d6 100644 --- a/medusa/tv/series.py +++ b/medusa/tv/series.py @@ -16,7 +16,7 @@ from builtins import map from builtins import str from collections import ( - namedtuple, + OrderedDict, namedtuple ) from itertools import groupby @@ -55,6 +55,7 @@ ) from medusa.helper.exceptions import ( AnidbAdbaConnectionException, + CantRefreshShowException, CantRemoveShowException, EpisodeDeletedException, EpisodeNotFoundException, @@ -65,7 +66,7 @@ ) from medusa.helpers.anidb import get_release_groups_for_anime, short_group_names from medusa.helpers.externals import get_externals, load_externals_from_db -from medusa.helpers.utils import safe_get +from medusa.helpers.utils import safe_get, to_camel_case from medusa.imdb import Imdb from medusa.indexers.indexer_api import indexerApi from medusa.indexers.indexer_config import ( @@ -210,6 +211,8 @@ def __init__(self, indexer, indexerid, lang='', quality=None, self.season_folders = season_folders or int(app.SEASON_FOLDERS_DEFAULT) self.status = 'Unknown' self._airs = '' + # Amount of hours we want to start searching early (-1) or late (1) for new episodes + self.airdate_offset = 0 self.start_year = 0 self.paused = 0 self.air_by_date = 0 @@ -223,6 +226,8 @@ def __init__(self, indexer, indexerid, lang='', quality=None, self.scene = 0 self.rls_ignore_words = '' self.rls_require_words = '' + self.rls_ignore_exclude = 0 + self.rls_require_exclude = 0 self.default_ep_status = SKIPPED self._location = '' self.episodes = {} @@ -363,43 +368,77 @@ def network_logo_name(self): return self.network.replace(u'\u00C9', 'e').replace(u'\u00E9', 'e').replace(' ', '-').lower() @property - def raw_location(self): - """Get the raw show location, unvalidated.""" - return self._location - - @property - def location(self): - """Get the show location.""" - # no directory check needed if missing - # show directories are created during post-processing + def validate_location(self): + """Legacy call to location with a validation when ADD_SHOWS_WO_DIR is set.""" if app.CREATE_MISSING_SHOW_DIRS or self.is_location_valid(): return self._location raise ShowDirectoryNotFoundException(u'Show folder does not exist.') @property - def indexer_name(self): - """Return the indexer name identifier. Example: tvdb.""" - return indexerConfig[self.indexer].get('identifier') - - @property - def indexer_slug(self): - """Return the slug name of the series. Example: tvdb1234.""" - return indexer_id_to_slug(self.indexer, self.series_id) + def location(self): + """Get the show location.""" + return self._location @location.setter def location(self, value): + old_location = os.path.normpath(self._location) + new_location = os.path.normpath(value) + log.debug( u'{indexer} {id}: Setting location: {location}', { 'indexer': indexerApi(self.indexer).name, 'id': self.series_id, - 'location': value, + 'location': new_location, } ) + + if new_location == old_location: + return + # Don't validate directory if user wants to add shows without creating a dir if app.ADD_SHOWS_WO_DIR or self.is_location_valid(value): - self._location = value - else: - raise ShowDirectoryNotFoundException(u'Invalid show folder!') + self._location = new_location + return + + changed_location = True + log.info('Changing show location to: {new}', {'new': new_location}) + if not os.path.isdir(new_location): + if app.CREATE_MISSING_SHOW_DIRS: + log.info(u"Show directory doesn't exist, creating it") + try: + os.mkdir(new_location) + except OSError as error: + changed_location = False + log.warning(u"Unable to create the show directory '{location}'. Error: {msg}", + {'location': new_location, 'msg': error}) + else: + log.info(u'New show directory created') + helpers.chmod_as_parent(new_location) + else: + changed_location = False + log.warning("New location '{location}' does not exist. " + "Enable setting '(Config - Postprocessing) Create missing show dirs'", {'location': new_location}) + + # Save new location only if we changed it + if changed_location: + self._location = new_location + + if changed_location and os.path.isdir(new_location): + try: + app.show_queue_scheduler.action.refreshShow(self) + except CantRefreshShowException as error: + log.warning("Unable to refresh show '{show}'. Error: {error}", + {'show': self.name, 'error': error.message}) + + @property + def indexer_name(self): + """Return the indexer name identifier. Example: tvdb.""" + return indexerConfig[self.indexer].get('identifier') + + @property + def indexer_slug(self): + """Return the slug name of the series. Example: tvdb1234.""" + return indexer_id_to_slug(self.indexer, self.series_id) @property def current_qualities(self): @@ -430,7 +469,7 @@ def default_ep_status_name(self, status_name): @property def size(self): """Size of the show on disk.""" - return helpers.get_size(self.raw_location) + return helpers.get_size(self.location) def show_size(self, pretty=False): """ @@ -894,13 +933,21 @@ def show_words(self): # If word is in global ignore and also in show require, then remove it from global ignore # Join new global ignore with show ignore - final_ignore = show_ignore + [i for i in global_ignore if i.lower() not in [r.lower() for r in show_require]] - # If word is in global require and also in show ignore, then remove it from global require + if not self.rls_ignore_exclude: + final_ignore = show_ignore + [i for i in global_ignore if i.lower() not in [r.lower() for r in show_require]] + else: + final_ignore = [i for i in global_ignore if i.lower() not in [r.lower() for r in show_require] and + i.lower() not in [sh_i.lower() for sh_i in show_ignore]] + # If word is in global require and also in show ignore, then remove it from global requires # Join new global required with show require - final_require = show_require + [i for i in global_require if i.lower() not in [r.lower() for r in show_ignore]] + if not self.rls_require_exclude: + final_require = show_require + [i for i in global_require if i.lower() not in [r.lower() for r in show_ignore]] + else: + final_require = [gl_r for gl_r in global_require if gl_r.lower() not in [r.lower() for r in show_ignore] and + gl_r.lower() not in [sh_r.lower() for sh_r in show_require]] - ignored_words = final_ignore - required_words = final_require + ignored_words = list(OrderedDict.fromkeys(final_ignore)) + required_words = list(OrderedDict.fromkeys(final_require)) return words(preferred_words, undesired_words, ignored_words, required_words) @@ -1119,10 +1166,10 @@ def load_episodes_from_db(self, seasons=None): cached_seasons[cur_season] = cached_show[cur_season] except IndexerSeasonNotFound as error: log.debug( - u'{id}: {error_msg} (unaired/deleted) in the indexer {indexer} for {show}.' + u'{id}: {error_msg!r} (unaired/deleted) in the indexer {indexer} for {show}.' u' Removing existing records from database', { 'id': cur_show_id, - 'error_msg': error.message, + 'error_msg': error, 'indexer': indexerApi(self.indexer).name, 'show': cur_show_name, } @@ -1434,15 +1481,18 @@ def _load_from_db(self): self.rls_ignore_words = sql_results[0]['rls_ignore_words'] self.rls_require_words = sql_results[0]['rls_require_words'] + self.rls_ignore_exclude = sql_results[0]['rls_ignore_exclude'] + self.rls_require_exclude = sql_results[0]['rls_require_exclude'] self.default_ep_status = int(sql_results[0]['default_ep_status'] or SKIPPED) if not self.imdb_id: self.imdb_id = sql_results[0]['imdb_id'] - self.release_groups = BlackAndWhiteList(self) - self.plot = sql_results[0]['plot'] + self.airdate_offset = int(sql_results[0]['airdate_offset']) + + self.release_groups = BlackAndWhiteList(self) # Load external id's from indexer_mappings table. self.externals = load_externals_from_db(self.indexer, self.series_id) @@ -1681,6 +1731,7 @@ def delete_show(self, full=False): # remove entire show folder if full: try: + self.validate_location # Let's get the exception out of the way asap. log.info(u'{id}: Attempt to {action} show folder {location}', {'id': self.series_id, 'action': action, 'location': self.location}) # check first the read-only attribute @@ -1701,17 +1752,17 @@ def delete_show(self, full=False): shutil.rmtree(self.location) log.info(u'{id}: {action} show folder {location}', - {'id': self.series_id, 'action': action, 'location': self.raw_location}) + {'id': self.series_id, 'action': action, 'location': self.location}) except ShowDirectoryNotFoundException: log.warning(u'{id}: Show folder {location} does not exist. No need to {action}', - {'id': self.series_id, 'action': action, 'location': self.raw_location}) + {'id': self.series_id, 'action': action, 'location': self.location}) except OSError as error: log.warning( u'{id}: Unable to {action} {location}. Error: {error_msg}', { 'id': self.series_id, 'action': action, - 'location': self.raw_location, + 'location': self.location, 'error_msg': ex(error), } ) @@ -1873,6 +1924,33 @@ def download_subtitles(self): for episode in episodes: episode.download_subtitles() + @property + def show_queue_status(self): + """Return a status the show checking the queue scheduler if there is currently an action queued or active.""" + return [ + {'action': 'isBeingAdded', + 'active': app.show_queue_scheduler.action.isBeingAdded(self), + 'message': 'This show is in the process of being downloaded - the info below is incomplete'}, + {'action': 'isBeingUpdated', + 'active': app.show_queue_scheduler.action.isBeingUpdated(self), + 'message': 'The information on this page is in the process of being updated'}, + {'action': 'isBeingRefreshed', + 'active': app.show_queue_scheduler.action.isBeingRefreshed(self), + 'message': 'The episodes below are currently being refreshed from disk'}, + {'action': 'isBeingSubtitled', + 'active': app.show_queue_scheduler.action.isBeingSubtitled(self), + 'message': 'Currently downloading subtitles for this show'}, + {'action': 'isInRefreshQueue', + 'active': app.show_queue_scheduler.action.isInRefreshQueue(self), + 'message': 'This show is queued to be refreshed'}, + {'action': 'isInUpdateQueue', + 'active': app.show_queue_scheduler.action.isInUpdateQueue(self), + 'message': 'This show is queued and awaiting an update'}, + {'action': 'isInSubtitleQueue', + 'active': app.show_queue_scheduler.action.isInSubtitleQueue(self), + 'message': 'This show is queued and awaiting subtitles download'}, + ] + def save_to_db(self): """Save to database.""" if not self.dirty: @@ -1883,7 +1961,7 @@ def save_to_db(self): control_value_dict = {'indexer': self.indexer, 'indexer_id': self.series_id} new_value_dict = {'show_name': self.name, - 'location': self.raw_location, # skip location validation + 'location': self.location, # skip location validation 'network': self.network, 'genre': self.genre, 'classification': self.classification, @@ -1905,8 +1983,11 @@ def save_to_db(self): 'last_update_indexer': self.last_update_indexer, 'rls_ignore_words': self.rls_ignore_words, 'rls_require_words': self.rls_require_words, + 'rls_ignore_exclude': self.rls_ignore_exclude, + 'rls_require_exclude': self.rls_require_exclude, 'default_ep_status': self.default_ep_status, - 'plot': self.plot} + 'plot': self.plot, + 'airdate_offset': self.airdate_offset} main_db_con = db.DBConnection() main_db_con.upsert('tv_shows', new_value_dict, control_value_dict) @@ -1932,11 +2013,13 @@ def __str__(self): to_return += 'indexerid: ' + str(self.series_id) + '\n' to_return += 'indexer: ' + str(self.indexer) + '\n' to_return += 'name: ' + self.name + '\n' - to_return += 'location: ' + self.raw_location + '\n' # skip location validation + to_return += 'location: ' + self.location + '\n' # skip location validation if self.network: to_return += 'network: ' + self.network + '\n' if self.airs: to_return += 'airs: ' + self.airs + '\n' + if self.airdate_offset != 0: + to_return += 'airdate_offset: ' + str(self.airdate_offset) + '\n' to_return += 'status: ' + self.status + '\n' to_return += 'start_year: ' + str(self.start_year) + '\n' if self.genre: @@ -1959,11 +2042,13 @@ def __unicode__(self): to_return += u'indexerid: {0}\n'.format(self.series_id) to_return += u'indexer: {0}\n'.format(self.indexer) to_return += u'name: {0}\n'.format(self.name) - to_return += u'location: {0}\n'.format(self.raw_location) # skip location validation + to_return += u'location: {0}\n'.format(self.location) # skip location validation if self.network: to_return += u'network: {0}\n'.format(self.network) if self.airs: to_return += u'airs: {0}\n'.format(self.airs) + if self.airdate_offset != 0: + to_return += 'airdate_offset: {0}\n'.format(self.airdate_offset) to_return += u'status: {0}\n'.format(self.status) to_return += u'start_year: {0}\n'.format(self.start_year) if self.genre: @@ -1997,9 +2082,10 @@ def to_json(self, detailed=True, fetch=False): data['type'] = self.classification # e.g. Scripted data['status'] = self.status # e.g. Continuing data['airs'] = self.airs # e.g. Thursday 8:00 PM + data['airsFormatValid'] = network_timezones.test_timeformat(self.airs) data['language'] = self.lang data['showType'] = self.show_type # e.g. anime, sport, series - data['akas'] = self.imdb_akas + data['imdbInfo'] = {to_camel_case(k): v for k, v in viewitems(self.imdb_info)} data['year'] = {} data['year']['start'] = self.imdb_year or self.start_year data['nextAirDate'] = self.next_airdate.isoformat() if self.next_airdate else None @@ -2016,10 +2102,11 @@ def to_json(self, detailed=True, fetch=False): data['cache']['poster'] = self.poster data['cache']['banner'] = self.banner data['countries'] = self.countries # e.g. ['ITALY', 'FRANCE'] - data['country_codes'] = self.imdb_countries # e.g. ['it', 'fr'] + data['countryCodes'] = self.imdb_countries # e.g. ['it', 'fr'] data['plot'] = self.plot or self.imdb_plot data['config'] = {} - data['config']['location'] = self.raw_location + data['config']['location'] = self.location + data['config']['locationValid'] = self.is_location_valid() data['config']['qualities'] = {} data['config']['qualities']['allowed'] = self.qualities_allowed data['config']['qualities']['preferred'] = self.qualities_preferred @@ -2037,6 +2124,9 @@ def to_json(self, detailed=True, fetch=False): data['config']['release'] = {} data['config']['release']['ignoredWords'] = self.release_ignore_words data['config']['release']['requiredWords'] = self.release_required_words + data['config']['release']['ignoredWordsExclude'] = bool(self.rls_ignore_exclude) + data['config']['release']['requiredWordsExclude'] = bool(self.rls_require_exclude) + data['config']['airdateOffset'] = self.airdate_offset # These are for now considered anime-only options if self.is_anime: @@ -2059,12 +2149,18 @@ def to_json(self, detailed=True, fetch=False): if detailed: episodes = self.get_all_episodes() + data['size'] = self.size data['seasons'] = [list(v) for _, v in groupby([ep.to_json() for ep in episodes], lambda item: item['season'])] + data['episodeCount'] = len(episodes) last_episode = episodes[-1] if episodes else None if self.status == 'Ended' and last_episode and last_episode.airdate: data['year']['end'] = last_episode.airdate.year + data['showQueueStatus'] = self.show_queue_status + data['xemNumbering'] = [{'source': {'season': src[0], 'episode': src[1]}, + 'destination': {'season': dest[0], 'episode': dest[1]}} + for src, dest in viewitems(self.xem_numbering)] return data diff --git a/medusa/updater/__init__.py b/medusa/updater/__init__.py new file mode 100644 index 0000000000..9bad5790a5 --- /dev/null +++ b/medusa/updater/__init__.py @@ -0,0 +1 @@ +# coding=utf-8 diff --git a/medusa/updater/docker_updater.py b/medusa/updater/docker_updater.py new file mode 100644 index 0000000000..5aa9f19a0f --- /dev/null +++ b/medusa/updater/docker_updater.py @@ -0,0 +1,54 @@ +# coding=utf-8 + +from __future__ import unicode_literals + +import logging + +from medusa import app +from medusa.logger.adapters.style import BraceAdapter +from medusa.updater.source_updater import SourceUpdateManager + + +log = BraceAdapter(logging.getLogger(__name__)) +log.logger.addHandler(logging.NullHandler()) + + +class DockerUpdateManager(SourceUpdateManager): + def __init__(self): + super(DockerUpdateManager, self).__init__() + + def __str__(self): + return 'Docker Updater' + + def need_update(self): + if self.branch != self._find_installed_branch(): + log.debug(u'Branch checkout: {0}->{1}', self._find_installed_branch(), self.branch) + return True + + if self.branch == 'master' and not self.is_latest_version(): + self._set_update_text() + return True + + return False + + def can_update(self): + """Whether or not the update can be performed. + + :return: + :rtype: bool + """ + return False + + def _set_update_text(self): + """Set an update text, when running in a Docker container.""" + log.debug('There is an update available, Medusa is running in a Docker container,' + ' so auto updating is disabled.') + + url = 'http://github.com/' + self.github_org + '/' + self.github_repo + '/releases' + newest_text = 'There is a newer version available' + newest_text += ' (' + self.newest_version + ') — Pull the latest Docker image and rebuild your container to update' + app.NEWEST_VERSION_STRING = newest_text + + def update(self): + """Download the latest version.""" + return False diff --git a/medusa/updater/github_updater.py b/medusa/updater/github_updater.py new file mode 100644 index 0000000000..eafcb03b04 --- /dev/null +++ b/medusa/updater/github_updater.py @@ -0,0 +1,381 @@ +# coding=utf-8 + +from __future__ import unicode_literals + +import logging +import os +import platform +import re +import subprocess + +from medusa import app, notifiers +from medusa.logger.adapters.style import BraceAdapter +from medusa.updater.update_manager import UpdateManager + +from six import text_type + + +ERROR_MESSAGE = ('Unable to find your git executable. Set git executable path in Advanced Settings ' + 'OR shutdown application and delete your .git folder and run from source to enable updates.') + +log = BraceAdapter(logging.getLogger(__name__)) +log.logger.addHandler(logging.NullHandler()) + + +class GitUpdateManager(UpdateManager): + def __init__(self): + super(GitUpdateManager, self).__init__() + self._git_path = self._find_working_git() + self.github_org = self.get_github_org() + self.github_repo = self.get_github_repo() + self.branch = self._find_installed_branch() + + self._cur_commit_hash = None + self._newest_commit_hash = None + self._num_commits_behind = 0 + self._num_commits_ahead = 0 + + def __str__(self): + return 'GitHub Updater' + + @property + def current_commit_hash(self): + return self._cur_commit_hash + + @property + def newest_commit_hash(self): + return self._newest_commit_hash + + @property + def current_version(self): + self.update_commit_hash() + cur_version = self._run_git(self._git_path, 'describe --tags --abbrev=0 {0}'.format( + self._cur_commit_hash))[0] + return cur_version.lstrip('v') + + @property + def newest_version(self): + self.update_newest_commit_hash() + new_version = self._run_git(self._git_path, 'describe --tags --abbrev=0 {0}'.format( + self._newest_commit_hash))[0] + return new_version.lstrip('v') + + @property + def commits_behind(self): + return self._num_commits_behind + + @property + def commits_ahead(self): + return self._num_commits_ahead + + def _find_working_git(self): + test_cmd = 'version' + + if app.GIT_PATH: + main_git = '"' + app.GIT_PATH + '"' + else: + main_git = 'git' + + log.debug(u'Checking if we can use git commands: {0} {1}', main_git, test_cmd) + _, _, exit_status = self._run_git(main_git, test_cmd) + + if exit_status == 0: + log.debug(u'Using: {0}', main_git) + return main_git + else: + log.debug(u'Not using: {0}', main_git) + + # trying alternatives + alternative_git = [] + + # osx people who start sr from launchd have a broken path, so try a hail-mary attempt for them + if platform.system().lower() == 'darwin': + alternative_git.append('/usr/local/git/bin/git') + + if platform.system().lower() == 'windows': + if main_git != main_git.lower(): + alternative_git.append(main_git.lower()) + + if alternative_git: + log.debug(u'Trying known alternative git locations') + + for cur_git in alternative_git: + log.debug(u'Checking if we can use git commands: {0} {1}', cur_git, test_cmd) + _, _, exit_status = self._run_git(cur_git, test_cmd) + + if exit_status == 0: + log.debug(u'Using: {0}', cur_git) + return cur_git + else: + log.debug(u'Not using: {0}', cur_git) + + def _run_git(self, git_path, args): + output = err = exit_status = None + + if not git_path: + git_path = self._find_working_git() + if git_path: + self._git_path = git_path + else: + # Warn user only if he has version check enabled + if app.VERSION_NOTIFY: + log.warning(u"No git specified, can't use git commands") + app.NEWEST_VERSION_STRING = ERROR_MESSAGE + exit_status = 1 + return output, err, exit_status + + # If we have a valid git remove the git warning + # String will be updated as soon we check github + app.NEWEST_VERSION_STRING = None + cmd = git_path + ' ' + args + + try: + log.debug(u'Executing {cmd} with your shell in {dir}', {'cmd': cmd, 'dir': app.PROG_DIR}) + p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + shell=True, cwd=app.PROG_DIR) + output, err = p.communicate() + exit_status = p.returncode + + # Convert bytes to string in python3 + if isinstance(output, (bytes, bytearray)): + output = output.decode('utf-8') + + if output: + output = output.strip() + + except OSError: + log.info(u"Command {cmd} didn't work", {'cmd': cmd}) + exit_status = 1 + + if exit_status == 0: + log.debug(u'{cmd} : returned successful', {'cmd': cmd}) + exit_status = 0 + + elif exit_status == 1: + if output: + if 'stash' in output: + log.warning(u"Enable 'git reset' in settings or stash your changes in local files") + else: + log.warning(u'{cmd} returned : {output}', {'cmd': cmd, 'output': output}) + else: + log.warning(u'{cmd} returned no data', {'cmd': cmd}) + exit_status = 1 + + elif exit_status == 128 or 'fatal:' in output or err: + log.warning(u'{cmd} returned : {output}', {'cmd': cmd, 'output': output}) + exit_status = 128 + + else: + log.warning(u'{cmd} returned : {output}. Treat as error for now', {'cmd': cmd, 'output': output}) + exit_status = 1 + + return output, err, exit_status + + def update_commit_hash(self): + """Attempt to set the hash of the currently installed version of the application. + + Uses git to get commit version. + """ + output, _, exit_status = self._run_git(self._git_path, 'rev-parse HEAD') + + if exit_status == 0 and output: + cur_commit_hash = output.strip() + if not re.match('^[a-z0-9]+$', cur_commit_hash): + log.warning(u"Output doesn't look like a hash, not using it") + return False + + self._cur_commit_hash = cur_commit_hash + app.CUR_COMMIT_HASH = cur_commit_hash + return True + + return False + + def update_newest_commit_hash(self): + # update remote origin url + self.update_remote_origin() + + # get all new info from github + output, _, exit_status = self._run_git(self._git_path, 'fetch --prune %s' % app.GIT_REMOTE) + if not exit_status == 0: + log.warning(u"Unable to contact github, can't check for update") + return False + + # get latest commit_hash from remote + output, _, exit_status = self._run_git(self._git_path, 'rev-parse --verify --quiet "@{upstream}"') + + if exit_status == 0 and output: + cur_commit_hash = output.strip() + if not re.match('^[a-z0-9]+$', cur_commit_hash): + log.debug(u"Output doesn't look like a hash, not using it") + return False + else: + self._newest_commit_hash = cur_commit_hash + return True + else: + log.debug(u"git didn't return newest commit hash") + return False + + def _find_installed_branch(self): + branch_info, _, exit_status = self._run_git(self._git_path, 'symbolic-ref -q HEAD') + if exit_status == 0 and branch_info: + branch = branch_info.strip().replace('refs/heads/', '', 1) + if branch: + app.BRANCH = branch + return branch + return '' + + def check_for_update(self): + """Use git commands to check if there is a newer version that the provided commit hash.""" + self.update_commit_hash() + self.update_newest_commit_hash() + + # get number of commits behind and ahead (option --count not supported git < 1.7.2) + output, _, exit_status = self._run_git(self._git_path, 'rev-list --left-right "@{upstream}"...HEAD') + if exit_status == 0 and output: + try: + self._num_commits_behind = int(output.count('<')) + self._num_commits_ahead = int(output.count('>')) + except Exception: + log.debug(u"git didn't return numbers for behind and ahead, not using it") + return False + + log.debug(u'cur_commit = {0}, newest_commit = {1}, num_commits_behind = {2}, num_commits_ahead = {3}', + self._cur_commit_hash, self._newest_commit_hash, self._num_commits_behind, self._num_commits_ahead) + + def need_update(self): + if self.branch != self._find_installed_branch(): + log.debug(u'Branch checkout: {0}->{1}', self._find_installed_branch(), self.branch) + return True + + try: + self.check_for_update() + except Exception as e: + log.warning(u"Unable to contact github, can't check for update: {0!r}", e) + return False + + if self._num_commits_behind > 0 or self._num_commits_ahead > 0: + self._set_update_text() + return True + + return False + + def _set_update_text(self): + if self._num_commits_behind > 0 or self._is_hard_reset_allowed(): + base_url = 'http://github.com/' + self.github_org + '/' + self.github_repo + if self._newest_commit_hash: + url = base_url + '/compare/' + self._cur_commit_hash + '...' + self._newest_commit_hash + else: + url = base_url + '/commits/' + + newest_text = 'There is a newer version available ' + newest_text += " (you're " + text_type(self._num_commits_behind) + ' commit' + if self._num_commits_behind > 1: + newest_text += 's' + newest_text += ' behind' + if self._num_commits_ahead > 0: + newest_text += ' and {ahead} commit{s} ahead'.format(ahead=self._num_commits_ahead, + s='s' if self._num_commits_ahead > 1 else '') + newest_text += ') — Update Now' + + elif self._num_commits_ahead > 0: + newest_text = u'Local branch is ahead of {0}. Automatic update not possible'.format(self.branch) + log.warning(newest_text) + else: + return + + app.NEWEST_VERSION_STRING = newest_text + + def can_update(self): + """Return whether update can be executed. + + :return: + :rtype: bool + """ + return self._num_commits_ahead <= 0 or self._is_hard_reset_allowed() + + def update(self): + """Call git pull origin in order to update the application. + + Returns a bool depending on the call's success. + """ + # update remote origin url + self.update_remote_origin() + + # remove untracked files and performs a hard reset on git branch to avoid update issues + if self._is_hard_reset_allowed(): + self.reset() + + # Executing git clean before updating + self.clean() + + if self.branch == self._find_installed_branch(): + _, _, exit_status = self._run_git(self._git_path, 'pull -f %s %s' % (app.GIT_REMOTE, self.branch)) + else: + _, _, exit_status = self._run_git(self._git_path, 'checkout -f ' + self.branch) + + # Executing git clean after updating + self.clean() + + if exit_status == 0: + self.update_commit_hash() + # Notify update successful + if app.NOTIFY_ON_UPDATE: + try: + notifiers.notify_git_update(app.CUR_COMMIT_HASH or '') + except Exception: + log.debug(u'Unable to send update notification. Continuing the update process') + return True + + return False + + @staticmethod + def _is_hard_reset_allowed(): + """Return whether git hard reset is allowed or not. + + :return: + :rtype: bool + """ + return app.GIT_RESET and (not app.GIT_RESET_BRANCHES or + app.BRANCH in app.GIT_RESET_BRANCHES) + + def clean(self): + """Call git clean to remove all untracked files. + + It only affects source folders and libX and extX folders, + to prevent deleting untracked user data not known by .gitignore + + :return: + :rtype: int + """ + # Fixes: goo.gl/tr8Awf - to be removed in the next release + root_dir = os.path.basename(app.PROG_DIR) + helper_folder = os.path.join(root_dir, 'helper') + helpers_folder = os.path.join(root_dir, 'helpers') + + folders = (app.LIB_FOLDER, app.LIB2_FOLDER, app.LIB3_FOLDER, app.EXT_FOLDER, + app.EXT2_FOLDER, app.EXT3_FOLDER, app.SRC_FOLDER, app.STATIC_FOLDER, + helper_folder, helpers_folder) + app.LEGACY_SRC_FOLDERS + _, _, exit_status = self._run_git(self._git_path, 'clean -d -f -x {0}'.format(' '.join(folders))) + + return exit_status + + def reset(self): + """Call git reset --hard to perform a hard reset.""" + _, _, exit_status = self._run_git(self._git_path, 'reset --hard {0}/{1}'.format(app.GIT_REMOTE, app.BRANCH)) + if exit_status == 0: + return True + + def list_remote_branches(self): + # update remote origin url + self.update_remote_origin() + app.BRANCH = self._find_installed_branch() + + branches, _, exit_status = self._run_git(self._git_path, 'ls-remote --heads %s' % app.GIT_REMOTE) + if exit_status == 0 and branches: + if branches: + return re.findall(r'refs/heads/(.*)', branches) + return [] + + def update_remote_origin(self): + self._run_git(self._git_path, 'config remote.%s.url %s' % (app.GIT_REMOTE, app.GIT_REMOTE_URL)) + self._run_git(self._git_path, 'config remote.%s.pushurl %s' % (app.GIT_REMOTE, app.GIT_REMOTE_URL)) diff --git a/medusa/updater/source_updater.py b/medusa/updater/source_updater.py new file mode 100644 index 0000000000..12b1dc2ffd --- /dev/null +++ b/medusa/updater/source_updater.py @@ -0,0 +1,264 @@ +# coding=utf-8 + +from __future__ import unicode_literals + +import logging +import os +import shutil +import stat +import tarfile + +from github import GithubException + +from medusa import app, helpers, notifiers +from medusa.common import VERSION +from medusa.github_client import get_github_repo, get_latest_release +from medusa.logger.adapters.style import BraceAdapter +from medusa.session.core import MedusaSafeSession +from medusa.updater.update_manager import UpdateManager + +from six import text_type + + +log = BraceAdapter(logging.getLogger(__name__)) +log.logger.addHandler(logging.NullHandler()) + + +class SourceUpdateManager(UpdateManager): + def __init__(self): + super(SourceUpdateManager, self).__init__() + self.github_org = self.get_github_org() + self.github_repo = self.get_github_repo() + + self.branch = app.BRANCH + if app.BRANCH == '': + self.branch = self._find_installed_branch() + + self._cur_commit_hash = app.CUR_COMMIT_HASH + self._newest_commit_hash = None + self._num_commits_behind = 0 + self._num_commits_ahead = 0 + + self.session = MedusaSafeSession() + + def __str__(self): + return 'Source Updater' + + @staticmethod + def _find_installed_branch(): + return app.CUR_COMMIT_BRANCH if app.CUR_COMMIT_BRANCH else 'master' + + @property + def current_commit_hash(self): + return self._cur_commit_hash + + @property + def newest_commit_hash(self): + return self._newest_commit_hash + + @property + def current_version(self): + return VERSION + + @property + def newest_version(self): + latest_release = get_latest_release(self.github_org, self.github_repo) + return latest_release.tag_name.lstrip('v') + + @property + def commits_behind(self): + return self._num_commits_behind + + @property + def commits_ahead(self): + return self._num_commits_ahead + + def need_update(self): + if self.branch != self._find_installed_branch(): + log.debug(u'Branch checkout: {0}->{1}', self._find_installed_branch(), self.branch) + return True + + # need this to run first to set self._newest_commit_hash + try: + self.check_for_update() + except Exception as error: + log.warning(u"Unable to contact github, can't check for update: {0!r}", error) + return False + + # This will be used until the first update + if self.branch == 'master' and not self._cur_commit_hash: + if self.is_latest_version(): + app.CUR_COMMIT_HASH = self._newest_commit_hash + app.CUR_COMMIT_BRANCH = self.branch + return False + else: + self._set_update_text() + return True + + elif self._num_commits_behind > 0 or self._num_commits_ahead > 0: + self._set_update_text() + return True + + return False + + def can_update(self): + """Whether or not the update can be performed. + + :return: + :rtype: bool + """ + return True + + def check_for_update(self): + """Use pygithub to ask github if there is a newer version.. + + If there is a newer version it sets application's version text. + + commit_hash: hash that we're checking against + """ + gh = get_github_repo(app.GIT_ORG, app.GIT_REPO) + + # try to get the newest commit hash and commits by comparing branch and current commit + if self._cur_commit_hash: + try: + branch_compared = gh.compare(base=self.branch, head=self._cur_commit_hash) + self._newest_commit_hash = branch_compared.base_commit.sha + self._num_commits_behind = branch_compared.behind_by + self._num_commits_ahead = branch_compared.ahead_by + except Exception: + self._newest_commit_hash = None + self._num_commits_behind = 0 + self._num_commits_ahead = 0 + + # fall back and iterate over last 100 (items per page in gh_api) commits + if not self._newest_commit_hash: + for cur_commit in gh.get_commits(): + if not self._newest_commit_hash: + self._newest_commit_hash = cur_commit.sha + if not self._cur_commit_hash: + break + + if cur_commit.sha == self._cur_commit_hash: + break + + # when _cur_commit_hash doesn't match anything _num_commits_behind == 100 + self._num_commits_behind += 1 + + log.debug(u'cur_commit = {0}, newest_commit = {1}, num_commits_behind = {2}', + self._cur_commit_hash, self._newest_commit_hash, self._num_commits_behind) + + def _set_update_text(self): + if self._num_commits_behind > 0: + base_url = 'http://github.com/' + self.github_org + '/' + self.github_repo + if self._newest_commit_hash: + url = base_url + '/compare/' + self._cur_commit_hash + '...' + self._newest_commit_hash + else: + url = base_url + '/commits/' + + newest_text = 'There is a newer version available' + newest_text += " (you're " + text_type(self._num_commits_behind) + ' commit' + if self._num_commits_behind > 1: + newest_text += 's' + newest_text += ' behind) — Update Now' + else: + url = 'http://github.com/' + self.github_org + '/' + self.github_repo + '/releases' + newest_text = 'There is a newer version available' + newest_text += ' (' + self.newest_version + ') — Update Now' + + app.NEWEST_VERSION_STRING = newest_text + + def update(self): + """Download the latest source tarball from github and installs it over the existing version.""" + tar_download_url = 'http://github.com/' + self.github_org + '/' + self.github_repo + '/tarball/' + self.branch + + try: + # prepare the update dir + app_update_dir = os.path.join(app.PROG_DIR, u'medusa-update') + + if os.path.isdir(app_update_dir): + log.info(u'Clearing out update folder {0!r} before extracting', app_update_dir) + shutil.rmtree(app_update_dir) + + log.info(u'Clearing update folder {0!r} before extracting', app_update_dir) + os.makedirs(app_update_dir) + + # retrieve file + log.info(u'Downloading update from {0!r}', tar_download_url) + tar_download_path = os.path.join(app_update_dir, u'medusa-update.tar') + helpers.download_file(tar_download_url, tar_download_path, session=self.session) + + if not os.path.isfile(tar_download_path): + log.warning(u"Unable to retrieve new version from {0!r}, can't update", tar_download_url) + return False + + if not tarfile.is_tarfile(tar_download_path): + log.warning(u"Retrieved version from {0!r} is corrupt, can't update", tar_download_url) + return False + + # extract to medusa-update dir + log.info(u'Extracting file {0}', tar_download_path) + tar = tarfile.open(tar_download_path) + tar.extractall(app_update_dir) + tar.close() + + # delete .tar.gz + log.info(u'Deleting file {0}', tar_download_path) + os.remove(tar_download_path) + + # find update dir name + update_dir_contents = [x for x in os.listdir(app_update_dir) if + os.path.isdir(os.path.join(app_update_dir, x))] + if len(update_dir_contents) != 1: + log.warning(u'Invalid update data, update failed: {0}', update_dir_contents) + return False + content_dir = os.path.join(app_update_dir, update_dir_contents[0]) + + # walk temp folder and move files to main folder + log.info(u'Moving files from {0} to {1}', content_dir, app.PROG_DIR) + for dirname, _, filenames in os.walk(content_dir): # @UnusedVariable + dirname = dirname[len(content_dir) + 1:] + for curfile in filenames: + old_path = os.path.join(content_dir, dirname, curfile) + new_path = os.path.join(app.PROG_DIR, dirname, curfile) + + # Avoid DLL access problem on WIN32/64 + # These files needing to be updated manually + # or find a way to kill the access from memory + extension = os.path.splitext(curfile)[1] + if extension == '.dll': + try: + log.debug(u'Special handling for {0}', curfile) + os.chmod(new_path, stat.S_IWRITE) + os.remove(new_path) + os.renames(old_path, new_path) + except Exception as e: + log.debug(u'Unable to update {0}: {1!r}', new_path, e) + os.remove(old_path) # Trash the updated file without moving in new path + continue + + if os.path.isfile(new_path): + os.remove(new_path) + os.renames(old_path, new_path) + + app.CUR_COMMIT_HASH = self._newest_commit_hash + app.CUR_COMMIT_BRANCH = self.branch + + except Exception as e: + log.exception(u'Error while trying to update: {0}', e) + return False + + # Notify update successful + try: + notifiers.notify_git_update(app.CUR_COMMIT_HASH or '') + except Exception: + log.debug(u'Unable to send update notification. Continuing the update process') + return True + + @staticmethod + def list_remote_branches(): + try: + gh = get_github_repo(app.GIT_ORG, app.GIT_REPO) + return [x.name for x in gh.get_branches() if x] + except GithubException as error: + log.warning(u"Unable to contact github, can't check for update: {0!r}", error) + return [] diff --git a/medusa/updater/update_manager.py b/medusa/updater/update_manager.py new file mode 100644 index 0000000000..787ce2376c --- /dev/null +++ b/medusa/updater/update_manager.py @@ -0,0 +1,44 @@ +# coding=utf-8 + +from __future__ import unicode_literals + +import logging +from distutils.version import LooseVersion + +from medusa import app +from medusa.logger.adapters.style import BraceAdapter + +from six import text_type + + +log = BraceAdapter(logging.getLogger(__name__)) +log.logger.addHandler(logging.NullHandler()) + + +class UpdateManager(object): + + @staticmethod + def get_github_org(): + return app.GIT_ORG + + @staticmethod + def get_github_repo(): + return app.GIT_REPO + + @staticmethod + def get_update_url(): + return app.WEB_ROOT + '/home/update/?pid=' + text_type(app.PID) + + def current_version(self): + """Get the current verion of the app.""" + raise NotImplementedError + + def newest_version(self): + """Get the newest verion of the app.""" + raise NotImplementedError + + def is_latest_version(self): + """Compare the current installed version with the remote version.""" + if LooseVersion(self.newest_version) > LooseVersion(self.current_version): + return False + return True diff --git a/medusa/updater/version_checker.py b/medusa/updater/version_checker.py new file mode 100644 index 0000000000..68575b877c --- /dev/null +++ b/medusa/updater/version_checker.py @@ -0,0 +1,357 @@ +# coding=utf-8 + +from __future__ import unicode_literals + +import datetime +import logging +import os +import re +import time +from builtins import object +from builtins import str +from logging import DEBUG, WARNING + +from medusa import app, db, helpers, ui +from medusa.logger.adapters.style import BraceAdapter +from medusa.session.core import MedusaSafeSession +from medusa.updater.docker_updater import DockerUpdateManager +from medusa.updater.github_updater import GitUpdateManager +from medusa.updater.source_updater import SourceUpdateManager + + +log = BraceAdapter(logging.getLogger(__name__)) +log.logger.addHandler(logging.NullHandler()) + + +class CheckVersion(object): + """Version check class meant to run as a thread object with the sr scheduler.""" + + def __init__(self): + self.amActive = False + self.updater = self.find_install_type() + self.session = MedusaSafeSession() + + def run(self, force=False): + + self.amActive = True + + # Update remote branches and store in app.GIT_REMOTE_BRANCHES + self.list_remote_branches() + + if self.updater: + # set current branch version + app.BRANCH = self.get_branch() + + if self.check_for_new_version(force): + if app.AUTO_UPDATE: + log.info(u'New update found, starting auto-updater ...') + ui.notifications.message('New update found, starting auto-updater') + if self.run_backup_if_safe(): + if app.version_check_scheduler.action.update(): + log.info(u'Update was successful!') + ui.notifications.message('Update was successful') + app.events.put(app.events.SystemEvent.RESTART) + else: + log.info(u'Update failed!') + ui.notifications.message('Update failed!') + + self.check_for_new_news(force) + + self.amActive = False + + def run_backup_if_safe(self): + return self.safe_to_update() is True and self._runbackup() is True + + def _runbackup(self): + # Do a system backup before update + log.info(u'Config backup in progress...') + ui.notifications.message('Backup', 'Config backup in progress...') + try: + backupDir = os.path.join(app.DATA_DIR, app.BACKUP_DIR) + if not os.path.isdir(backupDir): + os.mkdir(backupDir) + + if self._keeplatestbackup(backupDir) and self._backup(backupDir): + log.info(u'Config backup successful, updating...') + ui.notifications.message('Backup', 'Config backup successful, updating...') + return True + else: + log.warning(u'Config backup failed, aborting update') + ui.notifications.message('Backup', 'Config backup failed, aborting update') + return False + except Exception as e: + log.error(u'Update: Config backup failed. Error: {0!r}', e) + ui.notifications.message('Backup', 'Config backup failed, aborting update') + return False + + @staticmethod + def _keeplatestbackup(backupDir=None): + if not backupDir: + return False + + import glob + files = glob.glob(os.path.join(backupDir, '*.zip')) + if not files: + return True + + now = time.time() + newest = files[0], now - os.path.getctime(files[0]) + for f in files[1:]: + age = now - os.path.getctime(f) + if age < newest[1]: + newest = f, age + files.remove(newest[0]) + + for f in files: + os.remove(f) + + return True + + # TODO: Merge with backup in helpers + @staticmethod + def _backup(backupDir=None): + if not backupDir: + return False + source = [ + os.path.join(app.DATA_DIR, app.APPLICATION_DB), + app.CONFIG_FILE, + os.path.join(app.DATA_DIR, app.FAILED_DB), + os.path.join(app.DATA_DIR, app.CACHE_DB) + ] + target = os.path.join(backupDir, app.BACKUP_FILENAME.format(timestamp=time.strftime('%Y%m%d%H%M%S'))) + + for (path, dirs, files) in os.walk(app.CACHE_DIR, topdown=True): + for dirname in dirs: + if path == app.CACHE_DIR and dirname not in ['images']: + dirs.remove(dirname) + for filename in files: + source.append(os.path.join(path, filename)) + + return helpers.backup_config_zip(source, target, app.DATA_DIR) + + def safe_to_update(self): + + def db_safe(self): + message = { + 'equal': { + 'type': DEBUG, + 'text': u'We can proceed with the update. New update has same DB version'}, + 'upgrade': { + 'type': WARNING, + 'text': u"We can't proceed with the update. New update has a new DB version. Please manually update"}, + 'downgrade': { + 'type': WARNING, + 'text': u"We can't proceed with the update. New update has a old DB version. It's not possible to downgrade"}, + } + try: + result = self.getDBcompare() + if result in message: + log.log(message[result]['type'], message[result]['text']) # unpack the result message into a log entry + else: + log.warning(u"We can't proceed with the update. Unable to check remote DB version. Error: {0}", result) + return result in ['equal'] # add future True results to the list + except Exception as error: + log.error(u"We can't proceed with the update. Unable to compare DB version. Error: {0!r}", error) + return False + + def postprocessor_safe(): + if not app.auto_post_processor_scheduler.action.amActive: + log.debug(u'We can proceed with the update. Post-Processor is not running') + return True + else: + log.debug(u"We can't proceed with the update. Post-Processor is running") + return False + + def showupdate_safe(): + if not app.show_update_scheduler.action.amActive: + log.debug(u'We can proceed with the update. Shows are not being updated') + return True + else: + log.debug(u"We can't proceed with the update. Shows are being updated") + return False + + db_safe = db_safe(self) + postprocessor_safe = postprocessor_safe() + showupdate_safe = showupdate_safe() + + if db_safe and postprocessor_safe and showupdate_safe: + log.debug(u'Proceeding with auto update') + return True + else: + log.debug(u'Auto update aborted') + return False + + def getDBcompare(self): + """ + Compare the current DB version with the new branch version. + + :return: 'upgrade', 'equal', or 'downgrade' + """ + try: + self.updater.need_update() + cur_hash = str(self.updater.newest_commit_hash) + assert len(cur_hash) == 40, 'Commit hash wrong length: {length} hash: {hash}'.format( + length=len(cur_hash), hash=cur_hash) + + check_url = 'http://rawcdn.githack.com/{org}/{repo}/{commit}/medusa/databases/main_db.py'.format( + org=app.GIT_ORG, repo=app.GIT_REPO, commit=cur_hash) + response = self.session.get(check_url) + + # Get remote DB version + match_max_db = re.search(r'MAX_DB_VERSION\s*=\s*(?P\d{2,3})', response.text) + new_branch_major_db_version = int(match_max_db.group('version')) if match_max_db else None + match_minor_db = re.search(r'CURRENT_MINOR_DB_VERSION\s*=\s*(?P\d{1,2})', response.text) + new_branch_min_db_version = int(match_minor_db.group('version')) if match_minor_db else None + + # Check local DB version + main_db_con = db.DBConnection() + cur_branch_major_db_version, cur_branch_minor_db_version = main_db_con.checkDBVersion() + + if any([cur_branch_major_db_version is None, cur_branch_minor_db_version is None, + new_branch_major_db_version is None, new_branch_min_db_version is None]): + return 'Could not compare database versions, aborting' + + if new_branch_major_db_version > cur_branch_major_db_version: + return 'upgrade' + elif new_branch_major_db_version == cur_branch_major_db_version: + if new_branch_min_db_version < cur_branch_minor_db_version: + return 'downgrade' + elif new_branch_min_db_version > cur_branch_minor_db_version: + return 'upgrade' + return 'equal' + else: + return 'downgrade' + except Exception as e: + return repr(e) + + def find_install_type(self): + """ + Determine how this copy of Medusa was installed. + + :return: type of installation. Possible values are: + 'docker': any docker build + 'git': running from source using git + 'source': running from source without git + """ + if self.runs_in_docker(): + return DockerUpdateManager() + elif os.path.isdir(os.path.join(app.PROG_DIR, u'.git')): + return GitUpdateManager() + + return SourceUpdateManager() + + def check_for_new_version(self, force=False): + """ + Check the internet for a newer version. + + :force: if true the VERSION_NOTIFY setting will be ignored and a check will be forced + :return: bool, True for new version or False for no new version. + """ + if not self.updater or (not app.VERSION_NOTIFY and not app.AUTO_UPDATE and not force): + log.info(u'Version checking is disabled, not checking for the newest version') + app.NEWEST_VERSION_STRING = None + return False + + # checking for updates + if not app.AUTO_UPDATE: + log.info(u'Checking for updates using {0}', self.updater) + + if not self.updater.need_update(): + app.NEWEST_VERSION_STRING = None + + if force: + ui.notifications.message('No update needed') + log.info(u'No update needed') + + # no updates needed + return False + + # found updates + return self.updater.can_update() + + def check_for_new_news(self, force=False): + """ + Check GitHub for the latest news. + + :return: unicode, a copy of the news + :force: ignored + """ + # Grab a copy of the news + log.debug(u'Checking GitHub for latest news.') + response = self.session.get(app.NEWS_URL) + if not response or not response.text: + log.debug(u'Could not load news from URL: {0}', app.NEWS_URL) + return + + try: + last_read = datetime.datetime.strptime(app.NEWS_LAST_READ, '%Y-%m-%d') + except ValueError: + log.warning(u'Invalid news last read date: {0}', app.NEWS_LAST_READ) + last_read = 0 + + news = response.text + app.NEWS_UNREAD = 0 + got_latest = False + for match in re.finditer(r'^####\s*(\d{4}-\d{2}-\d{2})\s*####', news, re.M): + if not got_latest: + got_latest = True + app.NEWS_LATEST = match.group(1) + + try: + if datetime.datetime.strptime(match.group(1), '%Y-%m-%d') > last_read: + app.NEWS_UNREAD += 1 + except ValueError: + log.warning(u'Unable to match latest news date. Repository news date: {0}', match.group(1)) + pass + + return news + + def need_update(self): + if self.updater: + return self.updater.need_update() + + def update(self): + if self.updater: + # update branch with current config branch value + self.updater.branch = app.BRANCH + + # check for updates + if self.updater.need_update(): + return self.updater.update() + + def list_remote_branches(self): + if self.updater: + app.GIT_REMOTE_BRANCHES = self.updater.list_remote_branches() + return app.GIT_REMOTE_BRANCHES + + def get_branch(self): + if self.updater: + return self.updater.branch + + @staticmethod + def runs_in_docker(): + """ + Check if Medusa is run in a docker container. + + If run in a container, we don't want to use the auto update feature, but just want to inform the user + there is an update available. The user can update through getting the latest docker tag. + """ + if app.RUNS_IN_DOCKER is not None: + return app.RUNS_IN_DOCKER + + path = '/proc/{pid}/cgroup'.format(pid=os.getpid()) + try: + if not os.path.isfile(path): + return False + + with open(path) as f: + for line in f: + if re.match(r'\d+:[\w=]+:/docker(-[ce]e)?/\w+', line): + log.debug(u'Running in a docker container') + app.RUNS_IN_DOCKER = True + return True + return False + except (EnvironmentError, OSError) as error: + log.info(u'Tried to check the path {path} if we are running in a docker container, ' + u'but an error occurred: {error}', {'path': path, 'error': error}) + return False diff --git a/medusa/version_checker.py b/medusa/version_checker.py deleted file mode 100644 index 45c5262ac7..0000000000 --- a/medusa/version_checker.py +++ /dev/null @@ -1,1044 +0,0 @@ -# coding=utf-8 -# Author: Nic Wolfe -# -# This file is part of Medusa. -# -# Medusa is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Medusa is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Medusa. If not, see . -from __future__ import unicode_literals - -import datetime -import logging -import os -import platform -import re -import shutil -import stat -import subprocess -import tarfile -import time -from builtins import object -from builtins import str -from logging import DEBUG, WARNING - -from github import GithubException - -from medusa import app, db, helpers, notifiers, ui -from medusa.github_client import get_github_repo -from medusa.logger.adapters.style import BraceAdapter -from medusa.session.core import MedusaSafeSession - - -ERROR_MESSAGE = ('Unable to find your git executable. Set git executable path in Advanced Settings ' - 'OR shutdown application and delete your .git folder and run from source to enable updates.') - -log = BraceAdapter(logging.getLogger(__name__)) -log.logger.addHandler(logging.NullHandler()) - - -class CheckVersion(object): - """Version check class meant to run as a thread object with the sr scheduler.""" - - def __init__(self): - self.updater = None - self.install_type = None - self.amActive = False - self.install_type = self.find_install_type() - if self.install_type == 'git': - self.updater = GitUpdateManager() - elif self.install_type == 'source': - self.updater = SourceUpdateManager() - - self.session = MedusaSafeSession() - - def run(self, force=False): - - self.amActive = True - - # Update remote branches and store in app.GIT_REMOTE_BRANCHES - self.list_remote_branches() - - if self.updater: - # set current branch version - app.BRANCH = self.get_branch() - - if self.check_for_new_version(force): - if app.AUTO_UPDATE: - log.info(u'New update found, starting auto-updater ...') - ui.notifications.message('New update found, starting auto-updater') - if self.run_backup_if_safe(): - if app.version_check_scheduler.action.update(): - log.info(u'Update was successful!') - ui.notifications.message('Update was successful') - app.events.put(app.events.SystemEvent.RESTART) - else: - log.info(u'Update failed!') - ui.notifications.message('Update failed!') - - self.check_for_new_news(force) - - self.amActive = False - - def run_backup_if_safe(self): - return self.safe_to_update() is True and self._runbackup() is True - - def _runbackup(self): - # Do a system backup before update - log.info(u'Config backup in progress...') - ui.notifications.message('Backup', 'Config backup in progress...') - try: - backupDir = os.path.join(app.DATA_DIR, app.BACKUP_DIR) - if not os.path.isdir(backupDir): - os.mkdir(backupDir) - - if self._keeplatestbackup(backupDir) and self._backup(backupDir): - log.info(u'Config backup successful, updating...') - ui.notifications.message('Backup', 'Config backup successful, updating...') - return True - else: - log.warning(u'Config backup failed, aborting update') - ui.notifications.message('Backup', 'Config backup failed, aborting update') - return False - except Exception as e: - log.error(u'Update: Config backup failed. Error: {0!r}', e) - ui.notifications.message('Backup', 'Config backup failed, aborting update') - return False - - @staticmethod - def _keeplatestbackup(backupDir=None): - if not backupDir: - return False - - import glob - files = glob.glob(os.path.join(backupDir, '*.zip')) - if not files: - return True - - now = time.time() - newest = files[0], now - os.path.getctime(files[0]) - for f in files[1:]: - age = now - os.path.getctime(f) - if age < newest[1]: - newest = f, age - files.remove(newest[0]) - - for f in files: - os.remove(f) - - return True - - # TODO: Merge with backup in helpers - @staticmethod - def _backup(backupDir=None): - if not backupDir: - return False - source = [ - os.path.join(app.DATA_DIR, app.APPLICATION_DB), - app.CONFIG_FILE, - os.path.join(app.DATA_DIR, app.FAILED_DB), - os.path.join(app.DATA_DIR, app.CACHE_DB) - ] - target = os.path.join(backupDir, app.BACKUP_FILENAME.format(timestamp=time.strftime('%Y%m%d%H%M%S'))) - - for (path, dirs, files) in os.walk(app.CACHE_DIR, topdown=True): - for dirname in dirs: - if path == app.CACHE_DIR and dirname not in ['images']: - dirs.remove(dirname) - for filename in files: - source.append(os.path.join(path, filename)) - - return helpers.backup_config_zip(source, target, app.DATA_DIR) - - def safe_to_update(self): - - def db_safe(self): - message = { - 'equal': { - 'type': DEBUG, - 'text': u'We can proceed with the update. New update has same DB version'}, - 'upgrade': { - 'type': WARNING, - 'text': u"We can't proceed with the update. New update has a new DB version. Please manually update"}, - 'downgrade': { - 'type': WARNING, - 'text': u"We can't proceed with the update. New update has a old DB version. It's not possible to downgrade"}, - } - try: - result = self.getDBcompare() - if result in message: - log.log(message[result]['type'], message[result]['text']) # unpack the result message into a log entry - else: - log.warning(u"We can't proceed with the update. Unable to check remote DB version. Error: {0}", result) - return result in ['equal'] # add future True results to the list - except Exception as error: - log.error(u"We can't proceed with the update. Unable to compare DB version. Error: {0!r}", error) - return False - - def postprocessor_safe(): - if not app.auto_post_processor_scheduler.action.amActive: - log.debug(u'We can proceed with the update. Post-Processor is not running') - return True - else: - log.debug(u"We can't proceed with the update. Post-Processor is running") - return False - - def showupdate_safe(): - if not app.show_update_scheduler.action.amActive: - log.debug(u'We can proceed with the update. Shows are not being updated') - return True - else: - log.debug(u"We can't proceed with the update. Shows are being updated") - return False - - db_safe = db_safe(self) - postprocessor_safe = postprocessor_safe() - showupdate_safe = showupdate_safe() - - if db_safe and postprocessor_safe and showupdate_safe: - log.debug(u'Proceeding with auto update') - return True - else: - log.debug(u'Auto update aborted') - return False - - def getDBcompare(self): - """ - Compare the current DB version with the new branch version. - - :return: 'upgrade', 'equal', or 'downgrade' - """ - try: - self.updater.need_update() - cur_hash = str(self.updater.get_newest_commit_hash()) - assert len(cur_hash) == 40, 'Commit hash wrong length: {length} hash: {hash}'.format( - length=len(cur_hash), hash=cur_hash) - - check_url = 'http://rawcdn.githack.com/{org}/{repo}/{commit}/medusa/databases/main_db.py'.format( - org=app.GIT_ORG, repo=app.GIT_REPO, commit=cur_hash) - response = self.session.get(check_url) - - # Get remote DB version - match_max_db = re.search(r'MAX_DB_VERSION\s*=\s*(?P\d{2,3})', response.text) - new_branch_major_db_version = int(match_max_db.group('version')) if match_max_db else None - match_minor_db = re.search(r'CURRENT_MINOR_DB_VERSION\s*=\s*(?P\d{1,2})', response.text) - new_branch_min_db_version = int(match_minor_db.group('version')) if match_minor_db else None - - # Check local DB version - main_db_con = db.DBConnection() - cur_branch_major_db_version, cur_branch_minor_db_version = main_db_con.checkDBVersion() - - if any([cur_branch_major_db_version is None, cur_branch_minor_db_version is None, - new_branch_major_db_version is None, new_branch_min_db_version is None]): - return 'Could not compare database versions, aborting' - - if new_branch_major_db_version > cur_branch_major_db_version: - return 'upgrade' - elif new_branch_major_db_version == cur_branch_major_db_version: - if new_branch_min_db_version < cur_branch_minor_db_version: - return 'downgrade' - elif new_branch_min_db_version > cur_branch_minor_db_version: - return 'upgrade' - return 'equal' - else: - return 'downgrade' - except Exception as e: - return repr(e) - - @staticmethod - def find_install_type(): - """ - Determines how this copy of sr was installed. - - :return: type of installation. Possible values are: - 'win': any compiled windows build - 'git': running from source using git - 'source': running from source without git - """ - # check if we're a windows build - if app.BRANCH.startswith('build '): - install_type = 'win' - elif os.path.isdir(os.path.join(app.PROG_DIR, u'.git')): - install_type = 'git' - else: - install_type = 'source' - - return install_type - - def check_for_new_version(self, force=False): - """ - Check the internet for a newer version. - - :force: if true the VERSION_NOTIFY setting will be ignored and a check will be forced - :return: bool, True for new version or False for no new version. - """ - if not self.updater or (not app.VERSION_NOTIFY and not app.AUTO_UPDATE and not force): - log.info(u'Version checking is disabled, not checking for the newest version') - app.NEWEST_VERSION_STRING = None - return False - - # checking for updates - if not app.AUTO_UPDATE: - log.info(u'Checking for updates using {0}', self.install_type.upper()) - - if not self.updater.need_update(): - app.NEWEST_VERSION_STRING = None - - if force: - ui.notifications.message('No update needed') - log.info(u'No update needed') - - # no updates needed - return False - - # found updates - self.updater.set_newest_text() - return self.updater.can_update() - - def check_for_new_news(self, force=False): - """ - Check GitHub for the latest news. - - :return: unicode, a copy of the news - :force: ignored - """ - # Grab a copy of the news - log.debug(u'Checking GitHub for latest news.') - response = self.session.get(app.NEWS_URL) - if not response or not response.text: - log.debug(u'Could not load news from URL: %s', app.NEWS_URL) - return - - try: - last_read = datetime.datetime.strptime(app.NEWS_LAST_READ, '%Y-%m-%d') - except ValueError: - log.warning(u'Invalid news last read date: %s', app.NEWS_LAST_READ) - last_read = 0 - - news = response.text - app.NEWS_UNREAD = 0 - got_latest = False - for match in re.finditer(r'^####\s*(\d{4}-\d{2}-\d{2})\s*####', news, re.M): - if not got_latest: - got_latest = True - app.NEWS_LATEST = match.group(1) - - try: - if datetime.datetime.strptime(match.group(1), '%Y-%m-%d') > last_read: - app.NEWS_UNREAD += 1 - except ValueError: - log.warning(u'Unable to match latest news date. Repository news date: %s', match.group(1)) - pass - - return news - - def need_update(self): - if self.updater: - return self.updater.need_update() - - def update(self): - if self.updater: - # update branch with current config branch value - self.updater.branch = app.BRANCH - - # check for updates - if self.updater.need_update(): - return self.updater.update() - - def list_remote_branches(self): - if self.updater: - app.GIT_REMOTE_BRANCHES = self.updater.list_remote_branches() - return app.GIT_REMOTE_BRANCHES - - def get_branch(self): - if self.updater: - return self.updater.branch - - -class UpdateManager(object): - def __init__(self): - """Update manager initialization.""" - # Initialize the app.RUNS_IN_DOCKER variable - self.runs_in_docker() - - @staticmethod - def get_github_org(): - return app.GIT_ORG - - @staticmethod - def get_github_repo(): - return app.GIT_REPO - - @staticmethod - def get_update_url(): - return app.WEB_ROOT + '/home/update/?pid=' + str(app.PID) - - @staticmethod - def runs_in_docker(): - """ - Check if Medusa is run in a docker container. - - If run in a container, we don't want to use the auto update feature, but just want to inform the user - there is an update available. The user can update through getting the latest docker tag. - """ - if app.RUNS_IN_DOCKER is not None: - return app.RUNS_IN_DOCKER - - path = '/proc/{pid}/cgroup'.format(pid=os.getpid()) - try: - if not os.path.isfile(path): - return False - - with open(path) as f: - for line in f: - if re.match(r'\d+:[\w=]+:/docker(-[ce]e)?/\w+', line): - log.debug(u'Running in a docker container') - app.RUNS_IN_DOCKER = True - return True - return False - except (EnvironmentError, OSError) as error: - log.info(u'Tried to check the path {path} if we are running in a docker container, ' - u'but an error occurred: {error}', {'path': path, 'error': error}) - return False - - def set_newest_text_docker(self): - """ - Set an alternative update text, when running in a docker container. - - This method is used by the GitUpdateMananager and the SourceUpdateManager. Both should not auto update from - within the container. - """ - if app.RUNS_IN_DOCKER and (not self._cur_commit_hash or self._num_commits_behind > 0): - log.debug(u'There is an update available, Medusa is running in a docker container, so auto updating is disabled.') - app.NEWEST_VERSION_STRING = 'There is an update available: please pull the latest docker image, ' \ - 'and rebuild your container to update' - return True - return False - - -class GitUpdateManager(UpdateManager): - def __init__(self): - super(GitUpdateManager, self).__init__() - self._git_path = self._find_working_git() - self.github_org = self.get_github_org() - self.github_repo = self.get_github_repo() - - self.branch = app.BRANCH = self._find_installed_branch() - - self._cur_commit_hash = None - self._newest_commit_hash = None - self._num_commits_behind = 0 - self._num_commits_ahead = 0 - self._cur_version = '' - - def get_cur_commit_hash(self): - return self._cur_commit_hash - - def get_newest_commit_hash(self): - return self._newest_commit_hash - - def get_cur_version(self): - if self._cur_commit_hash or self._find_installed_version(): - self._cur_version = self._run_git(self._git_path, 'describe --tags --abbrev=0 {0}'.format(self._cur_commit_hash))[0] - return self._cur_version - - def get_newest_version(self): - if self._newest_commit_hash: - self._cur_version = self._run_git(self._git_path, 'describe --tags --abbrev=0 ' + self._newest_commit_hash)[0] - else: - self._cur_version = self._run_git(self._git_path, 'describe --tags --abbrev=0 ' + self._cur_commit_hash)[0] - return self._cur_version - - def get_num_commits_behind(self): - return self._num_commits_behind - - def get_num_commits_ahead(self): - return self._num_commits_ahead - - def _find_working_git(self): - test_cmd = 'version' - - if app.GIT_PATH: - main_git = '"' + app.GIT_PATH + '"' - else: - main_git = 'git' - - log.debug(u'Checking if we can use git commands: {0} {1}', main_git, test_cmd) - _, _, exit_status = self._run_git(main_git, test_cmd) - - if exit_status == 0: - log.debug(u'Using: {0}', main_git) - return main_git - else: - log.debug(u'Not using: {0}', main_git) - - # trying alternatives - - alternative_git = [] - - # osx people who start sr from launchd have a broken path, so try a hail-mary attempt for them - if platform.system().lower() == 'darwin': - alternative_git.append('/usr/local/git/bin/git') - - if platform.system().lower() == 'windows': - if main_git != main_git.lower(): - alternative_git.append(main_git.lower()) - - if alternative_git: - log.debug(u'Trying known alternative git locations') - - for cur_git in alternative_git: - log.debug(u'Checking if we can use git commands: {0} {1}', cur_git, test_cmd) - _, _, exit_status = self._run_git(cur_git, test_cmd) - - if exit_status == 0: - log.debug(u'Using: {0}', cur_git) - return cur_git - else: - log.debug(u'Not using: {0}', cur_git) - - # Still haven't found a working git - # Warn user only if he has version check enabled - if app.VERSION_NOTIFY: - app.NEWEST_VERSION_STRING = ERROR_MESSAGE - - return None - - @staticmethod - def _run_git(git_path, args): - - output = err = exit_status = None - - if not git_path: - log.warning(u"No git specified, can't use git commands") - app.NEWEST_VERSION_STRING = ERROR_MESSAGE - exit_status = 1 - return output, err, exit_status - - # If we have a valid git remove the git warning - # String will be updated as soon we check github - app.NEWEST_VERSION_STRING = None - - cmd = git_path + ' ' + args - - try: - log.debug(u'Executing {cmd} with your shell in {dir}', {'cmd': cmd, 'dir': app.PROG_DIR}) - p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - shell=True, cwd=app.PROG_DIR) - output, err = p.communicate() - exit_status = p.returncode - - if output: - output = output.strip() - - except OSError: - log.info(u"Command {cmd} didn't work", {'cmd': cmd}) - exit_status = 1 - - if exit_status == 0: - log.debug(u'{cmd} : returned successful', {'cmd': cmd}) - exit_status = 0 - - elif exit_status == 1: - if output: - if 'stash' in output: - log.warning(u"Enable 'git reset' in settings or stash your changes in local files") - else: - log.warning(u'{cmd} returned : {output}', {'cmd': cmd, 'output': output}) - else: - log.warning(u'{cmd} returned no data', {'cmd': cmd}) - exit_status = 1 - - elif exit_status == 128 or 'fatal:' in output or err: - log.warning(u'{cmd} returned : {output}', {'cmd': cmd, 'output': output}) - exit_status = 128 - - else: - log.warning(u'{cmd} returned : {output}. Treat as error for now', {'cmd': cmd, 'output': output}) - exit_status = 1 - - return output, err, exit_status - - def _find_installed_version(self): - """Attempt to find the currently installed version of the application. - - Uses git show to get commit version. - - :return: True for success or False for failure - """ - output, _, exit_status = self._run_git(self._git_path, 'rev-parse HEAD') # @UnusedVariable - - if exit_status == 0 and output: - cur_commit_hash = output.strip() - if not re.match('^[a-z0-9]+$', cur_commit_hash): - log.warning(u"Output doesn't look like a hash, not using it") - return False - self._cur_commit_hash = cur_commit_hash - app.CUR_COMMIT_HASH = str(cur_commit_hash) - return True - else: - return False - - def _find_installed_branch(self): - branch_info, _, exit_status = self._run_git(self._git_path, 'symbolic-ref -q HEAD') # @UnusedVariable - if exit_status == 0 and branch_info: - branch = branch_info.strip().replace('refs/heads/', '', 1) - if branch: - app.BRANCH = branch - return branch - return '' - - def _check_github_for_update(self): - """ - Uses git commands to check if there is a newer version that the provided - commit hash. If there is a newer version it sets _num_commits_behind. - """ - - self._num_commits_behind = 0 - self._num_commits_ahead = 0 - - # update remote origin url - self.update_remote_origin() - - # get all new info from github - output, _, exit_status = self._run_git(self._git_path, 'fetch --prune %s' % app.GIT_REMOTE) - if not exit_status == 0: - log.warning(u"Unable to contact github, can't check for update") - return - - # get latest commit_hash from remote - output, _, exit_status = self._run_git(self._git_path, 'rev-parse --verify --quiet "@{upstream}"') - - if exit_status == 0 and output: - cur_commit_hash = output.strip() - - if not re.match('^[a-z0-9]+$', cur_commit_hash): - log.debug(u"Output doesn't look like a hash, not using it") - return - - else: - self._newest_commit_hash = cur_commit_hash - else: - log.debug(u"git didn't return newest commit hash") - return - - # get number of commits behind and ahead (option --count not supported git < 1.7.2) - output, _, exit_status = self._run_git(self._git_path, 'rev-list --left-right "@{upstream}"...HEAD') - if exit_status == 0 and output: - - try: - self._num_commits_behind = int(output.count('<')) - self._num_commits_ahead = int(output.count('>')) - - except Exception: - log.debug(u"git didn't return numbers for behind and ahead, not using it") - return - - log.debug(u'cur_commit = {0}, newest_commit = {1}, num_commits_behind = {2}, num_commits_ahead = {3}', - self._cur_commit_hash, self._newest_commit_hash, self._num_commits_behind, self._num_commits_ahead) - - def set_newest_text(self): - - # if we're up to date then don't set this - app.NEWEST_VERSION_STRING = None - - if self.set_newest_text_docker(): - return - - if self._num_commits_behind > 0 or self._is_hard_reset_allowed(): - - base_url = 'http://github.com/' + self.github_org + '/' + self.github_repo - if self._newest_commit_hash: - url = base_url + '/compare/' + self._cur_commit_hash + '...' + self._newest_commit_hash - else: - url = base_url + '/commits/' - - newest_text = 'There is a newer version available ' - newest_text += " (you're " + str(self._num_commits_behind) + ' commit' - if self._num_commits_behind > 1: - newest_text += 's' - newest_text += ' behind' - if self._num_commits_ahead > 0: - newest_text += ' and {ahead} commit{s} ahead'.format(ahead=self._num_commits_ahead, - s='s' if self._num_commits_ahead > 1 else '') - newest_text += ') — Update Now' - - elif self._num_commits_ahead > 0: - newest_text = u'Local branch is ahead of {0}. Automatic update not possible'.format(self.branch) - log.warning(newest_text) - - else: - return - - app.NEWEST_VERSION_STRING = newest_text - - def need_update(self): - - if self.branch != self._find_installed_branch(): - log.debug(u'Branch checkout: {0}->{1}', self._find_installed_branch(), self.branch) - return True - - self._find_installed_version() - if not self._cur_commit_hash: - return True - else: - try: - self._check_github_for_update() - except Exception as e: - log.warning(u"Unable to contact github, can't check for update: {0!r}", e) - return False - - if self._num_commits_behind > 0 or self._num_commits_ahead > 0: - return True - - return False - - def can_update(self): - """Return whether update can be executed. - - :return: - :rtype: bool - """ - return self._num_commits_ahead <= 0 or self._is_hard_reset_allowed() - - def update(self): - """Call git pull origin in order to update the application. - - Returns a bool depending on the call's success. - """ - # update remote origin url - self.update_remote_origin() - - # remove untracked files and performs a hard reset on git branch to avoid update issues - if self._is_hard_reset_allowed(): - self.reset() - - # Executing git clean before updating - self.clean() - - if self.branch == self._find_installed_branch(): - _, _, exit_status = self._run_git(self._git_path, 'pull -f %s %s' % (app.GIT_REMOTE, self.branch)) # @UnusedVariable - else: - _, _, exit_status = self._run_git(self._git_path, 'checkout -f ' + self.branch) # @UnusedVariable - - # Executing git clean after updating - self.clean() - - if exit_status == 0: - self._find_installed_version() - # Notify update successful - if app.NOTIFY_ON_UPDATE: - try: - notifiers.notify_git_update(app.CUR_COMMIT_HASH or '') - except Exception: - log.debug(u'Unable to send update notification. Continuing the update process') - return True - - else: - return False - - @staticmethod - def _is_hard_reset_allowed(): - """Return whether git hard reset is allowed or not. - - :return: - :rtype: bool - """ - return app.GIT_RESET and (not app.GIT_RESET_BRANCHES or - app.BRANCH in app.GIT_RESET_BRANCHES) - - def clean(self): - """Call git clean to remove all untracked files. - - It only affects source folders and libX and extX folders, - to prevent deleting untracked user data not known by .gitignore - - :return: - :rtype: int - """ - # Fixes: goo.gl/tr8Awf - to be removed in the next release - root_dir = os.path.basename(app.PROG_DIR) - helper_folder = os.path.join(root_dir, 'helper') - helpers_folder = os.path.join(root_dir, 'helpers') - - folders = (app.LIB_FOLDER, app.LIB2_FOLDER, app.LIB3_FOLDER, app.EXT_FOLDER, - app.EXT2_FOLDER, app.EXT3_FOLDER, app.SRC_FOLDER, app.STATIC_FOLDER, - helper_folder, helpers_folder) + app.LEGACY_SRC_FOLDERS - _, _, exit_status = self._run_git(self._git_path, 'clean -d -f -x {0}'.format(' '.join(folders))) - - return exit_status - - def reset(self): - """ - Calls git reset --hard to perform a hard reset. Returns a bool depending - on the call's success. - """ - _, _, exit_status = self._run_git(self._git_path, 'reset --hard {0}/{1}'.format - (app.GIT_REMOTE, app.BRANCH)) # @UnusedVariable - if exit_status == 0: - return True - - def list_remote_branches(self): - # update remote origin url - self.update_remote_origin() - app.BRANCH = self._find_installed_branch() - - branches, _, exit_status = self._run_git(self._git_path, 'ls-remote --heads %s' % app.GIT_REMOTE) # @UnusedVariable - if exit_status == 0 and branches: - if branches: - return re.findall(r'refs/heads/(.*)', branches) - return [] - - def update_remote_origin(self): - self._run_git(self._git_path, 'config remote.%s.url %s' % (app.GIT_REMOTE, app.GIT_REMOTE_URL)) - self._run_git(self._git_path, 'config remote.%s.pushurl %s' % (app.GIT_REMOTE, app.GIT_REMOTE_URL)) - - -class SourceUpdateManager(UpdateManager): - def __init__(self): - super(SourceUpdateManager, self).__init__() - self.github_org = self.get_github_org() - self.github_repo = self.get_github_repo() - - self.branch = app.BRANCH - if app.BRANCH == '': - self.branch = self._find_installed_branch() - - self._cur_commit_hash = app.CUR_COMMIT_HASH - self._newest_commit_hash = None - self._num_commits_behind = 0 - self._num_commits_ahead = 0 - - self.session = MedusaSafeSession() - - @staticmethod - def _find_installed_branch(): - return app.CUR_COMMIT_BRANCH if app.CUR_COMMIT_BRANCH else 'master' - - def get_cur_commit_hash(self): - return self._cur_commit_hash - - def get_newest_commit_hash(self): - return self._newest_commit_hash - - @staticmethod - def get_cur_version(): - return '' - - @staticmethod - def get_newest_version(): - return '' - - def get_num_commits_behind(self): - return self._num_commits_behind - - def get_num_commits_ahead(self): - return self._num_commits_ahead - - def need_update(self): - # need this to run first to set self._newest_commit_hash - try: - self._check_github_for_update() - except Exception as error: - log.warning(u"Unable to contact github, can't check for update: {0!r}", error) - return False - - if self.branch != self._find_installed_branch(): - log.debug(u'Branch checkout: {0}->{1}', self._find_installed_branch(), self.branch) - return True - - if not self._cur_commit_hash or self._num_commits_behind > 0 or self._num_commits_ahead > 0: - return True - - return False - - def can_update(self): - """Whether or not the update can be performed. - - :return: - :rtype: bool - """ - return True - - def _check_github_for_update(self): - """Use pygithub to ask github if there is a newer version.. - - If there is a newer version it sets application's version text. - - commit_hash: hash that we're checking against - """ - - self._num_commits_behind = 0 - self._newest_commit_hash = None - - gh = get_github_repo(app.GIT_ORG, app.GIT_REPO) - # try to get newest commit hash and commits behind directly by comparing branch and current commit - if self._cur_commit_hash: - try: - branch_compared = gh.compare(base=self.branch, head=self._cur_commit_hash) - self._newest_commit_hash = branch_compared.base_commit.sha - self._num_commits_behind = branch_compared.behind_by - self._num_commits_ahead = branch_compared.ahead_by - except Exception: # UnknownObjectException - self._newest_commit_hash = '' - self._num_commits_behind = 0 - self._num_commits_ahead = 0 - self._cur_commit_hash = '' - - # fall back and iterate over last 100 (items per page in gh_api) commits - if not self._newest_commit_hash: - - for curCommit in gh.get_commits(): - if not self._newest_commit_hash: - self._newest_commit_hash = curCommit.sha - if not self._cur_commit_hash: - break - - if curCommit.sha == self._cur_commit_hash: - break - - # when _cur_commit_hash doesn't match anything _num_commits_behind == 100 - self._num_commits_behind += 1 - - log.debug(u'cur_commit = {0}, newest_commit = {1}, num_commits_behind = {2}', - self._cur_commit_hash, self._newest_commit_hash, self._num_commits_behind) - - def set_newest_text(self): - - # if we're up to date then don't set this - app.NEWEST_VERSION_STRING = None - - if self.set_newest_text_docker(): - return - - if not self._cur_commit_hash: - log.debug(u"Unknown current version number, don't know if we should update or not") - - newest_text = "Unknown current version number: If you've never used the application " \ - 'upgrade system before then current version is not set. ' \ - '— Update Now' - - elif self._num_commits_behind > 0: - base_url = 'http://github.com/' + self.github_org + '/' + self.github_repo - if self._newest_commit_hash: - url = base_url + '/compare/' + self._cur_commit_hash + '...' + self._newest_commit_hash - else: - url = base_url + '/commits/' - - newest_text = 'There is a newer version available' - newest_text += " (you're " + str(self._num_commits_behind) + ' commit' - if self._num_commits_behind > 1: - newest_text += 's' - newest_text += ' behind) — Update Now' - else: - return - - app.NEWEST_VERSION_STRING = newest_text - - def update(self): - """ - Downloads the latest source tarball from github and installs it over the existing version. - """ - - tar_download_url = 'http://github.com/' + self.github_org + '/' + self.github_repo + '/tarball/' + self.branch - - try: - # prepare the update dir - app_update_dir = os.path.join(app.PROG_DIR, u'sr-update') - - if os.path.isdir(app_update_dir): - log.info(u'Clearing out update folder {0!r} before extracting', app_update_dir) - shutil.rmtree(app_update_dir) - - log.info(u'Clearing update folder {0!r} before extracting', app_update_dir) - os.makedirs(app_update_dir) - - # retrieve file - log.info(u'Downloading update from {0!r}', tar_download_url) - tar_download_path = os.path.join(app_update_dir, u'sr-update.tar') - helpers.download_file(tar_download_url, tar_download_path, session=self.session) - - if not os.path.isfile(tar_download_path): - log.warning(u"Unable to retrieve new version from {0!r}, can't update", tar_download_url) - return False - - if not tarfile.is_tarfile(tar_download_path): - log.warning(u"Retrieved version from {0!r} is corrupt, can't update", tar_download_url) - return False - - # extract to sr-update dir - log.info(u'Extracting file {0}', tar_download_path) - tar = tarfile.open(tar_download_path) - tar.extractall(app_update_dir) - tar.close() - - # delete .tar.gz - log.info(u'Deleting file {0}', tar_download_path) - os.remove(tar_download_path) - - # find update dir name - update_dir_contents = [x for x in os.listdir(app_update_dir) if - os.path.isdir(os.path.join(app_update_dir, x))] - if len(update_dir_contents) != 1: - log.warning(u'Invalid update data, update failed: {0}', update_dir_contents) - return False - content_dir = os.path.join(app_update_dir, update_dir_contents[0]) - - # walk temp folder and move files to main folder - log.info(u'Moving files from {0} to {1}', content_dir, app.PROG_DIR) - for dirname, _, filenames in os.walk(content_dir): # @UnusedVariable - dirname = dirname[len(content_dir) + 1:] - for curfile in filenames: - old_path = os.path.join(content_dir, dirname, curfile) - new_path = os.path.join(app.PROG_DIR, dirname, curfile) - - # Avoid DLL access problem on WIN32/64 - # These files needing to be updated manually - # or find a way to kill the access from memory - extension = os.path.splitext(curfile)[1] - if extension == '.dll': - try: - log.debug(u'Special handling for {0}', curfile) - os.chmod(new_path, stat.S_IWRITE) - os.remove(new_path) - os.renames(old_path, new_path) - except Exception as e: - log.debug(u'Unable to update {0}: {1!r}', new_path, e) - os.remove(old_path) # Trash the updated file without moving in new path - continue - - if os.path.isfile(new_path): - os.remove(new_path) - os.renames(old_path, new_path) - - app.CUR_COMMIT_HASH = self._newest_commit_hash - app.CUR_COMMIT_BRANCH = self.branch - - except Exception as e: - log.exception(u'Error while trying to update: {0}', e) - return False - - # Notify update successful - try: - notifiers.notify_git_update(app.CUR_COMMIT_HASH or '') - except Exception: - log.debug(u'Unable to send update notification. Continuing the update process') - return True - - @staticmethod - def list_remote_branches(): - try: - gh = get_github_repo(app.GIT_ORG, app.GIT_REPO) - return [x.name for x in gh.get_branches() if x] - except GithubException as error: - log.warning(u"Unable to contact github, can't check for update: {0!r}", error) - return [] diff --git a/package.json b/package.json index 74e5520366..4cd0720414 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,8 @@ "install": "yarn run lint" }, "devDependencies": { - "dredd": "5.2.0", + "dredd": "8.0.5", "execa": "1.0.0", - "yargs": "12.0.5" + "yargs": "13.2.2" } } diff --git a/readme.md b/readme.md index 2aec64b25c..0071c6704d 100644 --- a/readme.md +++ b/readme.md @@ -30,6 +30,7 @@ - Supports TVMaze and TMDB indexers - Manual search episodes (you choose what to snatch based on all kind of info: provider, seeds, release group) - Manual search for subtitles (useful when subtitle has low score because of typo in filename or alternative title) + - Support for Python 3 - Uses 'guessit' library to parse and enrich existing info (more precise than regexes) - Improved Anime shows support - Faster DailySearcher|Backlog|Find propers as we only process new items. Already processed items are discarded. @@ -61,7 +62,9 @@ - Real SSL certificate validation #### Dependencies - To run Medusa from source you will need Python 2.7.10 + To run Medusa from source you will need one of these Python versions: + * **Python 2** – 2.7.10 and above + * **Python 3** – 3.5.0 and above #### Installation - direct Start [here](https://github.com/pymedusa/Medusa/wiki/Installation-&-Configuration-Guides) to read the installation guides for different setups. diff --git a/renovate.json b/renovate.json index cd294ed595..049bc532df 100644 --- a/renovate.json +++ b/renovate.json @@ -23,7 +23,8 @@ "packageNames": [ "vue", "vue-template-compiler", - "@vue/test-utils" + "@vue/test-utils", + "vue-jest" ], "groupName": "vue-base" } diff --git a/requirements.txt b/requirements.txt index 88f9df863a..edcce4feba 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,43 +1,44 @@ # No setup.py, unable to install using pip -# git+https://github.com/pymedusa/adba.git@119b9d30a30feb97bcea5e1dc742c82340300091#egg=adba +# git+https://github.com/pymedusa/adba.git@6502307ae34286e44b28234cfbacee6df1eadf07#egg=adba git+https://github.com/Diaoul/babelfish.git@f403000dd63092cfaaae80be9f309fd85c7f20c9#egg=babelfish -beautifulsoup4==4.6.3 +beautifulsoup4==4.7.1 bencode.py==2.0.0 CacheControl==0.12.5 -certifi==2018.10.15 +certifi==2019.3.9 chardet==3.0.4 git+https://github.com/pymedusa/cloudflare-scrape.git@320456e8b28cedb807363a7a892b1379db843f66#egg=cfscrape configobj==5.0.6 -configparser==3.5.0 +configparser==3.7.3 contextlib2==0.5.5 ; python_version < '3.5' +deluge-client==1.7.0 dirtyjson==1.0.7 -dogpile.cache==0.6.7 +dogpile.cache==0.7.1 git+https://github.com/pymedusa/enzyme.git@665cf6948aab1c249dcc99bd9624a81d17b3302a#egg=enzyme git+https://github.com/kurtmckee/feedparser.git@2b11c8028321ed43cbaf313f83b0c94820143d66#egg=feedparser future==0.17.1 futures==3.2.0 ; python_version >= '2.6' and python_version < '3' gntp==1.0.3 -guessit==3.0.3 +git+https://github.com/guessit-io/guessit.git@74dbb0c7420cee18969926aba9cc06b8959daa0e#egg=guessit html5lib==1.0.1 imdbpie==5.6.3 -jsonrpclib-pelix==0.3.2 +jsonrpclib-pelix==0.4.0 knowit==0.2.4 lockfile==0.12.2 Mako==1.0.7 -markdown2==2.3.6 +markdown2==2.3.7 git+https://github.com/joestump/python-oauth2.git@6689960ca23f79eccf9a25a39e93f6540f44ca23#egg=oauth2 profilehooks==1.10.0 -PyGithub==1.43.3 -PyJWT==1.6.4 -python-dateutil==2.7.5 +PyGithub==1.43.5 +PyJWT==1.7.1 +python-dateutil==2.8.0 python-twitter==3.5 rarfile==3.0 rebulk==1.0.0 -requests==2.20.1 -requests-oauthlib==1.0.0 -six==1.11.0 -stevedore==1.30.0 -git+https://github.com/pymedusa/subliminal.git@78687f45d23b1bc47fae0a5493be0198dc1fd5b5#egg=subliminal +requests==2.21.0 +requests-oauthlib==1.2.0 +six==1.12.0 +stevedore==1.30.1 +git+https://github.com/Diaoul/subliminal.git@6ac2fa23ee5baa7d8452552edaa7c4a8a00d237a#egg=subliminal tornado==5.1.1 tornroutes==0.5.1 -validators==0.12.3 +validators==0.12.4 diff --git a/runscripts/init.systemd b/runscripts/init.systemd index 841fd8779f..e8ae7c1b01 100755 --- a/runscripts/init.systemd +++ b/runscripts/init.systemd @@ -50,9 +50,11 @@ After=network.target User=medusa Group=medusa -Type=forking -GuessMainPID=no -ExecStart=/usr/bin/python2.7 /opt/medusa/start.py -q --daemon --nolaunch --datadir=/opt/medusa +Type=simple +ExecStart=/usr/bin/python2.7 /opt/medusa/start.py -q --nolaunch --datadir=/opt/medusa +TimeoutStopSec=25 +KillMode=process +Restart=on-failure [Install] WantedBy=multi-user.target diff --git a/setup.cfg b/setup.cfg index 9cbeccdc5e..e069eb6c22 100644 --- a/setup.cfg +++ b/setup.cfg @@ -11,7 +11,9 @@ max-line-length = 160 ignore = ; Error codes reference: https://git.io/fNlTP ; Q002: Handled by flake8-docstrings - Q002 + Q002, + ; W503: Line break should be before binary operator + W503 [tool:pytest] filterwarnings = @@ -19,6 +21,7 @@ filterwarnings = ignore::PendingDeprecationWarning flake8-ignore = D107 + W503 W504 medusa/__init__.py D104 F401 medusa/bs4_parser.py D100 D101 D102 D105 @@ -32,7 +35,7 @@ flake8-ignore = medusa/clients/torrent/mlnet_client.py E305 medusa/clients/torrent/qbittorrent_client.py E305 medusa/clients/torrent/rtorrent_client.py E305 - medusa/common.py D101 D102 D105 + medusa/common.py D101 D102 D105 N815 N816 medusa/config.py D100 D101 D103 D200 D202 D205 D210 D400 D401 N802 N803 N806 medusa/databases/__init__.py D104 medusa/databases/cache_db.py D100 D101 D102 E501 @@ -43,7 +46,7 @@ flake8-ignore = medusa/failed_processor.py D100 D205 D400 N803 N806 medusa/generic_queue.py D100 D101 D102 D200 D202 D400 D401 medusa/helper/__init__.py D104 - medusa/helper/common.py D100 D200 D202 D205 D400 + medusa/helper/common.py D100 D200 D202 D205 D400 N816 medusa/helper/encoding.py D100 D202 D400 D401 medusa/helper/exceptions.py D100 D200 D202 D205 D400 medusa/helper/metadata.py D100 D103 @@ -57,7 +60,7 @@ flake8-ignore = medusa/indexers/__init__.py D104 medusa/indexers/indexer_api.py D100 D101 D102 D105 N801 medusa/indexers/indexer_base.py D102 D400 - medusa/indexers/indexer_config.py D100 D103 + medusa/indexers/indexer_config.py D100 D103 N816 medusa/indexers/tmdb/__init__.py D104 medusa/indexers/tmdb/tmdb.py D100 medusa/indexers/tmdb/tmdb_exceptions.py D200 D204 D205 D400 N801 @@ -74,15 +77,15 @@ flake8-ignore = medusa/media/network_logo.py D100 D102 medusa/media/poster.py D100 D102 medusa/metadata/__init__.py D104 N802 - medusa/metadata/generic.py D100 D102 D200 D202 D205 D400 D401 N802 N806 + medusa/metadata/generic.py D100 D102 D200 D202 D205 D400 D401 N802 N806 N813 medusa/metadata/helpers.py D100 D103 N802 N803 N806 medusa/metadata/kodi.py D100 D102 D202 D205 D400 D401 - medusa/metadata/kodi_12plus.py D100 D102 D202 D205 D400 D401 N801 - medusa/metadata/mede8er.py D100 D102 D202 D205 D400 D401 - medusa/metadata/media_browser.py D100 D102 D202 D205 D400 D401 N802 N806 + medusa/metadata/kodi_12plus.py D100 D102 D202 D205 D400 D401 N801 N813 + medusa/metadata/mede8er.py D100 D102 D202 D205 D400 D401 N813 + medusa/metadata/media_browser.py D100 D102 D202 D205 D400 D401 N802 N806 N813 medusa/metadata/ps3.py D100 D102 D205 D400 D401 N802 medusa/metadata/tivo.py D100 D102 D202 D205 D400 D401 N802 - medusa/metadata/wdtv.py D100 D102 D202 D205 D400 D401 N802 + medusa/metadata/wdtv.py D100 D102 D202 D205 D400 D401 N802 N813 medusa/name_cache.py D100 D200 D400 D401 N802 N806 medusa/naming.py D100 D101 D102 D103 D205 D400 D401 N806 medusa/network_timezones.py D100 D103 D200 D202 D400 @@ -90,9 +93,9 @@ flake8-ignore = medusa/notifiers/freemobile.py D100 D101 D102 D202 D400 D401 E225 N802 N803 N806 medusa/notifiers/growl.py D100 D101 D102 N802 N806 medusa/notifiers/libnotify.py D100 D101 D102 D205 D400 F401 - medusa/notifiers/nmj.py D100 D101 D102 D202 D400 D401 N802 N806 - medusa/notifiers/nmjv2.py D100 D101 D102 D202 D400 D401 E501 N802 N806 - medusa/notifiers/plex.py D100 D101 D102 D201 D202 D400 D401 E501 + medusa/notifiers/nmj.py D100 D101 D102 D202 D400 D401 N802 N806 N813 + medusa/notifiers/nmjv2.py D100 D101 D102 D202 D400 D401 E501 N802 N806 N813 + medusa/notifiers/plex.py D100 D101 D102 D201 D202 D400 D401 E501 N813 medusa/notifiers/prowl.py D100 D101 D102 E501 medusa/notifiers/pushalot.py D100 D101 D102 N802 medusa/notifiers/pushbullet.py D100 D101 D102 N802 @@ -113,8 +116,8 @@ flake8-ignore = medusa/server/__init__.py D104 medusa/server/api/__init__.py D104 medusa/server/api/v1/__init__.py D104 - medusa/server/api/v1/core.py D100 D101 D102 D200 D201 D202 D204 D205 D208 D210 D400 D401 D403 N801 - medusa/server/core.py D100 D101 D102 N802 + medusa/server/api/v1/core.py D100 D101 D102 D200 D201 D202 D204 D205 D208 D210 D400 D401 D403 N801 N806 + medusa/server/core.py D100 D101 D102 N802 N815 N816 medusa/server/web/__init__.py D104 F401 medusa/server/web/config/__init__.py D104 F401 medusa/server/web/config/anime.py D102 D200 D202 D204 D400 N802 @@ -128,7 +131,7 @@ flake8-ignore = medusa/server/web/config/subtitles.py D102 D200 D204 D400 E501 N802 medusa/server/web/core/__init__.py D104 F401 medusa/server/web/core/authentication.py D102 D200 D202 D204 D205 D400 - medusa/server/web/core/base.py D100 D101 D102 D103 D200 D204 D210 D400 D401 N802 + medusa/server/web/core/base.py D100 D101 D102 D103 D200 D204 D210 D400 D401 N802 N815 medusa/server/web/core/calendar.py D200 D204 D205 D400 D401 medusa/server/web/core/file_browser.py D100 D101 D102 N803 medusa/server/web/core/history.py D100 D101 D102 N802 @@ -159,11 +162,11 @@ flake8-ignore = medusa/show/recommendations/trakt.py D100 medusa/show/show.py D100 D101 D102 D202 D205 D400 medusa/show_name_helpers.py D100 D202 D205 D400 D401 N802 N806 - medusa/show_queue.py D100 D101 D102 D205 D400 D401 N802 N803 N806 + medusa/show_queue.py D100 D101 D102 D205 D400 D401 N802 N803 N806 N815 medusa/show_updater.py D100 D101 D102 D105 medusa/subtitle_providers/__init__.py D104 medusa/subtitle_providers/legendastv.py D100 D102 D103 D105 D204 - medusa/subtitle_providers/itasa.py D100 D101 D102 D105 D400 + medusa/subtitle_providers/itasa.py D100 D101 D102 D105 D400 N813 medusa/subtitle_providers/wizdom.py D100 D102 D204 medusa/system/__init__.py D104 medusa/system/restart.py D100 D101 D102 @@ -173,7 +176,12 @@ flake8-ignore = medusa/themes/__init__.py F401 medusa/tv/__init__.py D104 F401 medusa/ui.py D100 D101 D102 D200 D202 D204 D205 D400 D401 E305 N802 N803 N806 - medusa/version_checker.py D100 D101 D102 D200 D202 D205 D400 D401 N802 N803 N806 + medusa/updater/__init__.py D104 + medusa/updater/docker_updater.py D100 D101 D102 D105 + medusa/updater/github_updater.py D100 D101 D102 D105 + medusa/updater/source_updater.py D100 D101 D102 D105 + medusa/updater/update_manager.py D100 D101 D102 + medusa/updater/version_checker.py D100 D101 D102 N802 N803 N806 setup.py D200 D400 tests/__init__.py D104 tests/*.py D101 D102 D103 diff --git a/setup.py b/setup.py index b716d62b30..4c38940a45 100644 --- a/setup.py +++ b/setup.py @@ -44,12 +44,12 @@ def run_tests(self): 'flake8-quotes>=1.0.0', 'pep8-naming>=0.7.0', 'pycodestyle>=2.4.0', - 'pytest>=3.8.0', - 'pytest-cov>=2.6.0', + 'pytest>=4.1.0', + 'pytest-cov>=2.6.1', 'pytest-flake8>=1.0.2', - 'pytest-tornado>=0.5.0', + 'pytest-tornado5>=2.0.0', 'PyYAML>=3.13,<4', - 'vcrpy>=1.13.0', + 'vcrpy>=2.0.1', 'mock>=2.0.0', ], extras_require={ diff --git a/tests/__init__.py b/tests/__init__.py index 82433a4ef5..296f8fb441 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,4 +1,5 @@ # coding=utf-8 +from __future__ import unicode_literals import sys import medusa diff --git a/tests/apiv2/__init__.py b/tests/apiv2/__init__.py index 41388f4577..ce233ba128 100644 --- a/tests/apiv2/__init__.py +++ b/tests/apiv2/__init__.py @@ -1,5 +1,6 @@ # coding=utf-8 """Api v2 tests.""" +from __future__ import unicode_literals import os import sys diff --git a/tests/apiv2/conftest.py b/tests/apiv2/conftest.py index 1c543d4f4d..0f9ecbe4e3 100644 --- a/tests/apiv2/conftest.py +++ b/tests/apiv2/conftest.py @@ -6,6 +6,8 @@ import pytest import tornado.web +from six import iteritems + @pytest.fixture(scope='session') def app(): @@ -28,7 +30,7 @@ def create(url, **kwargs): api_key = app_config('API_KEY', 'myhiddenkey') params = dict(api_key=api_key) params.update(kwargs) - q = '?' + ('&'.join(['{0}={1}'.format(k, v) for k, v in params.items()])) if params else '' + q = '?' + ('&'.join(['{0}={1}'.format(k, v) for k, v in iteritems(params)])) if params else '' url = '{base}{url}{query}'.format(base=base_url, url=url, query=q) return url diff --git a/tests/apiv2/test_log.py b/tests/apiv2/test_log.py index 224ae1d34d..77894e873f 100644 --- a/tests/apiv2/test_log.py +++ b/tests/apiv2/test_log.py @@ -1,5 +1,6 @@ # coding=utf-8 """Test /log route.""" +from __future__ import unicode_literals import json from medusa.server.api.v2 import log diff --git a/tests/apiv2/test_series.py b/tests/apiv2/test_series.py index 089ab95356..3590f2815a 100644 --- a/tests/apiv2/test_series.py +++ b/tests/apiv2/test_series.py @@ -1,5 +1,6 @@ # coding=utf-8 """Test /show route.""" +from __future__ import unicode_literals import json import pytest diff --git a/tests/conftest.py b/tests/conftest.py index c1ccc20faf..d6e41f2fb1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,6 @@ # coding=utf-8 """Configuration for pytest.""" +from __future__ import unicode_literals import logging import os from logging.handlers import RotatingFileHandler @@ -19,11 +20,11 @@ from medusa.logger import read_loglines as logger_read_loglines from medusa.providers.generic_provider import GenericProvider from medusa.tv import Episode, Series -from medusa.version_checker import CheckVersion +from medusa.updater.version_checker import CheckVersion from mock.mock import Mock import pytest -from six import iteritems +from six import iteritems, text_type from subliminal.subtitle import Subtitle from subliminal.video import Video import yaml @@ -175,14 +176,14 @@ def create(provider, series, episodes, **kwargs): def create_file(tmpdir): def create(filename, lines=None, size=0, **kwargs): f = tmpdir.ensure(filename) - content = '\n'.join(lines or []) + content = b'\n'.join(lines or []) f.write_binary(content) if size: tmp_size = f.size() if tmp_size < size: - add_size = '\0' * (size - tmp_size) + add_size = b'\0' * (size - tmp_size) f.write_binary(content + add_size) - return str(f) + return text_type(f) return create @@ -191,7 +192,7 @@ def create(filename, lines=None, size=0, **kwargs): def create_dir(tmpdir): def create(dirname): f = tmpdir.ensure_dir(dirname) - return str(f) + return text_type(f) return create @@ -201,13 +202,13 @@ def create_structure(tmpdir, create_file, create_dir): def create(path, structure): for element in structure: if isinstance(element, dict): - for name, values in element.iteritems(): + for name, values in iteritems(element): path = os.path.join(path, name) create_dir(path) create(path, values) else: create_file(os.path.join(path, element)) - return str(tmpdir) + return text_type(tmpdir) return create @@ -228,7 +229,7 @@ def commit_hash(monkeypatch): @pytest.fixture def logfile(tmpdir): - target = str(tmpdir.ensure('logfile.log')) + target = text_type(tmpdir.ensure('logfile.log')) instance.log_file = target return target @@ -243,7 +244,7 @@ def rotating_file_handler(logfile): @pytest.fixture def logger(rotating_file_handler, commit_hash): - print('Using commit_hash {}'.format(commit_hash)) + print('Using commit_hash {0}'.format(commit_hash)) target = logging.getLogger('testing_logger') target.addFilter(ContextFilter()) target.addHandler(rotating_file_handler) @@ -307,7 +308,7 @@ def create(title, body=None, locked=False, number=1, **kwargs): } raw_data.update(kwargs) # Set url to a unique value, because that's how issues are compared - raw_data['url'] = str(hash(tuple(raw_data.values()))) + raw_data['url'] = text_type(hash(tuple(raw_data.values()))) return Issue(Mock(), Mock(), raw_data, True) return create diff --git a/tests/helper/__init__.py b/tests/helper/__init__.py index 38d2644a7e..41a9732cac 100644 --- a/tests/helper/__init__.py +++ b/tests/helper/__init__.py @@ -1,2 +1,3 @@ # coding=utf-8 """Tests for medusa.helper module.""" +from __future__ import unicode_literals diff --git a/tests/helper/test_common.py b/tests/helper/test_common.py index aa68820084..35d909418a 100644 --- a/tests/helper/test_common.py +++ b/tests/helper/test_common.py @@ -45,23 +45,10 @@ def test_http_code_description(p): @pytest.mark.parametrize('p', [ - { # p0 - bytes test cases + { # p0 - special test cases None: False, 42: False, b'': False, - b'filename': False, - b'.syncthingfilename': True, - b'.syncthing.filename': True, - b'.syncthing-filename': True, - b'.!sync': True, - b'file.!sync': True, - b'file.!sync.ext': False, - b'.lftp-pget-status': True, - b'file.lftp-pget-status': True, - b'file.lftp-pget-status.ext': False, - b'.part': True, - b'file.part': True, - b'file.part.ext': False, }, { # p1 - unicode test cases '': False, @@ -88,17 +75,9 @@ def test_is_sync_file(p, app_config): @pytest.mark.parametrize('p', [ - { # p0 - bytes test cases + { # p0 - special test cases None: False, 42: False, - b'': False, - b'filename': False, - b'.nzb': True, - b'file.nzb': True, - b'file.nzb.part': False, - b'.torrent': True, - b'file.torrent': True, - b'file.torrent.part': False, }, { # p1 - unicode test cases '': False, @@ -151,22 +130,9 @@ def test_pretty_file_size(p): @pytest.mark.parametrize('p', [ - { # p0 - bytes test cases + { # p0 - special test cases None: None, 42: 42, - b'': b'', - b'.': b'.', - b'filename': b'filename', - b'.bashrc': b'.bashrc', - b'.nzb': b'.nzb', - b'file.nzb': b'file', - b'file.name.nzb': b'file.name', - b'.torrent': b'.torrent', - b'file.torrent': b'file', - b'file.name.torrent': b'file.name', - b'.avi': b'.avi', - b'file.avi': b'file', - b'file.name.avi': b'file.name', }, { # p1 - unicode test cases '': '', @@ -190,7 +156,7 @@ def test_remove_extension(p): @pytest.mark.parametrize('p', [ - { # p0 - bytes test cases + { # p0 - special test cases (None, None): None, (None, b''): None, (42, None): 42, @@ -199,19 +165,6 @@ def test_remove_extension(p): (b'', b''): b'', (b'.', None): b'.', (b'.', b''): b'.', - (b'.', b'avi'): b'.', - (b'filename', None): b'filename', - (b'filename', b''): b'filename', - (b'filename', b'avi'): b'filename', - (b'.bashrc', None): b'.bashrc', - (b'.bashrc', b''): b'.bashrc', - (b'.bashrc', b'avi'): b'.bashrc', - (b'file.mkv', None): b'file.None', - (b'file.mkv', b''): b'file.', - (b'file.mkv', b'avi'): b'file.avi', - (b'file.name.mkv', None): b'file.name.None', - (b'file.name.mkv', b''): b'file.name.', - (b'file.name.mkv', b'avi'): b'file.name.avi', }, { # p1 - unicode test cases (None, ''): None, @@ -239,21 +192,17 @@ def test_remove_extension(p): ('.bashrc', None): '.bashrc', ('.bashrc', b''): '.bashrc', ('.bashrc', ''): '.bashrc', - ('.bashrc', b'avi'): '.bashrc', ('.bashrc', 'avi'): '.bashrc', ('file.mkv', ''): b'file.', ('file.mkv', 'avi'): b'file.avi', ('file.mkv', None): 'file.None', - ('file.mkv', b''): 'file.', ('file.mkv', ''): 'file.', - ('file.mkv', b'avi'): 'file.avi', ('file.mkv', 'avi'): 'file.avi', ('file.name.mkv', ''): b'file.name.', ('file.name.mkv', 'avi'): b'file.name.avi', ('file.name.mkv', None): 'file.name.None', - ('file.name.mkv', b''): 'file.name.', ('file.name.mkv', ''): 'file.name.', - ('file.name.mkv', b'avi'): 'file.name.avi', + ('file.name.mkv', ''): 'file.name.', ('file.name.mkv', 'avi'): 'file.name.avi', } ]) @@ -263,17 +212,10 @@ def test_replace_extension(p): @pytest.mark.parametrize('value,expected', [ - # bytes test cases - (None, b''), - (42, b''), - (b'', b''), - (b'filename', b'filename'), - (b'fi\\le/na*me', b'fi-le-na-me'), - (b'fi:le"nale|na?me', b'filename'), - (b' . file\u2122name. .', b'file-u2122name'), - (b' . file\tname. .', b'filename'), - (b' . file\x00as\x08df\x1fname. .', b'fileasdfname'), + # special test cases + (None, ''), + (42, ''), + (b'', ''), # unicode test cases ('', ''), @@ -373,6 +315,8 @@ def test_convert_size(): assert sut.convert_size(100, -1) == 100 # returns integer sizes for floats too assert sut.convert_size(1.312, -1) == 1 + # return integer variant when passed as str + assert sut.convert_size('1024', -1) == 1024 # without a default value, failures return None assert sut.convert_size('pancakes') is None diff --git a/tests/legacy/__init__.py b/tests/legacy/__init__.py index d0542d6527..9426f1cec0 100644 --- a/tests/legacy/__init__.py +++ b/tests/legacy/__init__.py @@ -15,3 +15,4 @@ # along with Medusa. If not, see . """Tests for base package.""" +from __future__ import unicode_literals diff --git a/tests/legacy/common_tests.py b/tests/legacy/common_tests.py index 6c54dde5e3..487d275d59 100644 --- a/tests/legacy/common_tests.py +++ b/tests/legacy/common_tests.py @@ -1,13 +1,14 @@ # coding=utf-8 """Unit Tests for common package.""" - -from __future__ import print_function +from __future__ import unicode_literals import unittest from medusa import common +from six import text_type, iteritems + class QualityStringTests(unittest.TestCase): """Test Case for strings in common.Quality.""" @@ -96,7 +97,7 @@ def test_sd_tv(self): cur_test = 'sd_tv' cur_qual = common.Quality.SDTV - for name, tests in self.test_cases.items(): + for name, tests in iteritems(self.test_cases): for test in tests: if name == cur_test: self.assertEqual(cur_qual, common.Quality.name_quality(test)) @@ -107,7 +108,7 @@ def test_sd_dvd(self): cur_test = 'sd_dvd' cur_qual = common.Quality.SDDVD - for name, tests in self.test_cases.items(): + for name, tests in iteritems(self.test_cases): for test in tests: if name == cur_test: self.assertEqual(cur_qual, common.Quality.name_quality(test)) @@ -118,7 +119,7 @@ def test_hd_tv(self): cur_test = 'hd_tv' cur_qual = common.Quality.HDTV - for name, tests in self.test_cases.items(): + for name, tests in iteritems(self.test_cases): for test in tests: if name == cur_test: self.assertEqual(cur_qual, common.Quality.name_quality(test)) @@ -129,7 +130,7 @@ def test_raw_hd_tv(self): cur_test = 'raw_hd_tv' cur_qual = common.Quality.RAWHDTV - for name, tests in self.test_cases.items(): + for name, tests in iteritems(self.test_cases): for test in tests: if name == cur_test: self.assertEqual(cur_qual, common.Quality.name_quality(test)) @@ -140,7 +141,7 @@ def test_full_hd_tv(self): cur_test = 'full_hd_tv' cur_qual = common.Quality.FULLHDTV - for name, tests in self.test_cases.items(): + for name, tests in iteritems(self.test_cases): for test in tests: if name == cur_test: self.assertEqual(cur_qual, common.Quality.name_quality(test)) @@ -151,7 +152,7 @@ def test_hd_web_dl(self): cur_test = 'hd_web_dl' cur_qual = common.Quality.HDWEBDL - for name, tests in self.test_cases.items(): + for name, tests in iteritems(self.test_cases): for test in tests: if name == cur_test: self.assertEqual(cur_qual, common.Quality.name_quality(test)) @@ -162,7 +163,7 @@ def test_full_hd_web_dl(self): cur_test = 'full_hd_web_dl' cur_qual = common.Quality.FULLHDWEBDL - for name, tests in self.test_cases.items(): + for name, tests in iteritems(self.test_cases): for test in tests: if name == cur_test: self.assertEqual(cur_qual, common.Quality.name_quality(test)) @@ -173,7 +174,7 @@ def test_hd_bluray(self): cur_test = 'hd_bluray' cur_qual = common.Quality.HDBLURAY - for name, tests in self.test_cases.items(): + for name, tests in iteritems(self.test_cases): for test in tests: if name == cur_test: self.assertEqual(cur_qual, common.Quality.name_quality(test)) @@ -184,7 +185,7 @@ def test_full_hd_bluray(self): cur_test = 'full_hd_bluray' cur_qual = common.Quality.FULLHDBLURAY - for name, tests in self.test_cases.items(): + for name, tests in iteritems(self.test_cases): for test in tests: if name == cur_test: self.assertEqual(cur_qual, common.Quality.name_quality(test)) @@ -195,7 +196,7 @@ def test_unknown(self): cur_test = 'unknown' cur_qual = common.Quality.UNKNOWN - for name, tests in self.test_cases.items(): + for name, tests in iteritems(self.test_cases): for test in tests: if name == cur_test: self.assertEqual(cur_qual, common.Quality.name_quality(test)) @@ -223,8 +224,8 @@ def test_anime(self): 'full_hd_bluray': common.Quality.FULLHDBLURAY, 'unknown': common.Quality.UNKNOWN, } - for cur_test, expected_qual in test_quality.items(): - for qual, tests in test_cases.items(): + for cur_test, expected_qual in iteritems(test_quality): + for qual, tests in iteritems(test_cases): for name in tests: if qual == cur_test: self.assertEqual(expected_qual, common.Quality.name_quality(name, anime=True), @@ -279,12 +280,12 @@ def test_all(self): self.assertTrue(status_strings[i]) for i in status_strings: - self.assertEqual(status_strings[i], status_strings[str(i)]) - self.assertEqual(i in status_strings, str(i) in status_strings) + self.assertEqual(status_strings[i], status_strings[text_type(i)]) + self.assertEqual(i in status_strings, text_type(i) in status_strings) for i in status_strings.qualities: - self.assertEqual(status_strings[i], status_strings[str(i)]) - self.assertEqual(i in status_strings, str(i) in status_strings) + self.assertEqual(status_strings[i], status_strings[text_type(i)]) + self.assertEqual(i in status_strings, text_type(i) in status_strings) for i in invalid: with self.assertRaises(TypeError): @@ -293,10 +294,10 @@ def test_all(self): for i in unused: if i is None: with self.assertRaises(TypeError): - status_strings[str(i)] = 1 # 'None' is not None - status_strings[i] = 1 # ...but None can still be used as a key + status_strings[text_type(i)] = 1 + status_strings[i] = 1 else: - status_strings[str(i)] = 1 + status_strings[text_type(i)] = 1 self.assertEqual(status_strings[i], 1) diff --git a/tests/legacy/config_tests.py b/tests/legacy/config_tests.py index 43a7c04d6c..3e98fc102d 100644 --- a/tests/legacy/config_tests.py +++ b/tests/legacy/config_tests.py @@ -1,5 +1,6 @@ # coding=utf-8 """Test config package.""" +from __future__ import unicode_literals # pylint: disable=line-too-long diff --git a/tests/legacy/db_tests.py b/tests/legacy/db_tests.py index 9ddf7258e0..1094ed1454 100644 --- a/tests/legacy/db_tests.py +++ b/tests/legacy/db_tests.py @@ -17,8 +17,7 @@ # along with Medusa. If not, see . """Test show database functionality.""" - -from __future__ import print_function +from __future__ import unicode_literals import threading @@ -51,6 +50,6 @@ def select(self): def test_threaded(self): """Test multi-threaded selection from the database.""" - for _ in range(4): + for _ in list(range(4)): thread = threading.Thread(target=self.select) thread.start() diff --git a/tests/legacy/encoding_tests.py b/tests/legacy/encoding_tests.py index b7e7e71967..11ae19fd96 100644 --- a/tests/legacy/encoding_tests.py +++ b/tests/legacy/encoding_tests.py @@ -1,7 +1,6 @@ # coding=utf-8 """General encoding tests.""" - -from __future__ import print_function +from __future__ import unicode_literals import locale import os.path diff --git a/tests/legacy/exceptions_helper_tests.py b/tests/legacy/exceptions_helper_tests.py index 723d824b43..a9c4fb046b 100644 --- a/tests/legacy/exceptions_helper_tests.py +++ b/tests/legacy/exceptions_helper_tests.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """Test exceptions helpers.""" +from __future__ import unicode_literals import unittest diff --git a/tests/legacy/helper/__init__.py b/tests/legacy/helper/__init__.py index 46db85c341..f6066cb328 100644 --- a/tests/legacy/helper/__init__.py +++ b/tests/legacy/helper/__init__.py @@ -1,2 +1,3 @@ # coding=utf-8 """Tests for helpers package.""" +from __future__ import unicode_literals diff --git a/tests/legacy/helper/quality_tests.py b/tests/legacy/helper/quality_tests.py index 6729181b85..f619467e0f 100644 --- a/tests/legacy/helper/quality_tests.py +++ b/tests/legacy/helper/quality_tests.py @@ -15,8 +15,7 @@ # along with Medusa. If not, see . """Test qualities.""" - -from __future__ import print_function +from __future__ import unicode_literals import unittest diff --git a/tests/legacy/helpers_tests.py b/tests/legacy/helpers_tests.py index 175b663692..6d4c053cf8 100644 --- a/tests/legacy/helpers_tests.py +++ b/tests/legacy/helpers_tests.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python # coding=utf-8 # Author: Dustyn Gibson # @@ -18,14 +18,16 @@ # along with Medusa. If not, see . """Test helpers.""" - -from __future__ import print_function +from __future__ import unicode_literals import unittest from medusa import helpers from medusa.helper.common import media_extensions, subtitle_extensions +from six import iteritems + + TEST_RESULT = 'Show.Name.S01E01.HDTV.x264-RLSGROUP' # TODO: py.test parameters TEST_CASES = { @@ -140,5 +142,5 @@ def test_is_media_file(self): } for cur_test in extension_tests, sample_tests, edge_cases: - for cur_name, expected_result in cur_test.items(): + for cur_name, expected_result in iteritems(cur_test): self.assertEqual(helpers.is_media_file(cur_name), expected_result, cur_name) diff --git a/tests/legacy/media/__init__.py b/tests/legacy/media/__init__.py index 05814aeecf..7422e1e0bd 100644 --- a/tests/legacy/media/__init__.py +++ b/tests/legacy/media/__init__.py @@ -1,2 +1,3 @@ # coding=utf-8 """Tests for media package.""" +from __future__ import unicode_literals diff --git a/tests/legacy/media/generic_media_tests.py b/tests/legacy/media/generic_media_tests.py index 58cc08d691..cf6e770b79 100644 --- a/tests/legacy/media/generic_media_tests.py +++ b/tests/legacy/media/generic_media_tests.py @@ -15,8 +15,7 @@ # along with Medusa. If not, see . """Test GenericMedia.""" - -from __future__ import print_function +from __future__ import unicode_literals import os import unittest @@ -36,4 +35,4 @@ def test_default_media_name(self): def test_media_root(self): app.PROG_DIR = os.path.join('some', 'path', 'to', 'application') - self.assertEqual(GenericMedia.get_media_root(), os.path.join('some', 'path', 'to', 'application', 'static')) \ No newline at end of file + self.assertEqual(GenericMedia.get_media_root(), os.path.join('some', 'path', 'to', 'application', 'static')) diff --git a/tests/legacy/media/show_banner_tests.py b/tests/legacy/media/show_banner_tests.py index 76b6b8a1c1..9351a1dc96 100644 --- a/tests/legacy/media/show_banner_tests.py +++ b/tests/legacy/media/show_banner_tests.py @@ -15,8 +15,7 @@ # along with Medusa. If not, see . """Test ShowBanner.""" - -from __future__ import print_function +from __future__ import unicode_literals from medusa.media.banner import ShowBanner from medusa.tv import Series diff --git a/tests/legacy/media/show_fan_art_tests.py b/tests/legacy/media/show_fan_art_tests.py index a3f14a68cd..8c9ffe423b 100644 --- a/tests/legacy/media/show_fan_art_tests.py +++ b/tests/legacy/media/show_fan_art_tests.py @@ -15,8 +15,7 @@ # along with Medusa. If not, see . """Test ShowFanArt.""" - -from __future__ import print_function +from __future__ import unicode_literals from medusa.media.fan_art import ShowFanArt from medusa.tv import Series diff --git a/tests/legacy/media/show_network_logo_tests.py b/tests/legacy/media/show_network_logo_tests.py index 12542819d8..16c3eb7284 100644 --- a/tests/legacy/media/show_network_logo_tests.py +++ b/tests/legacy/media/show_network_logo_tests.py @@ -15,8 +15,7 @@ # along with Medusa. If not, see . """Test ShowNetworkLogo.""" - -from __future__ import print_function +from __future__ import unicode_literals import os diff --git a/tests/legacy/media/show_poster_tests.py b/tests/legacy/media/show_poster_tests.py index da82479096..818be08ade 100644 --- a/tests/legacy/media/show_poster_tests.py +++ b/tests/legacy/media/show_poster_tests.py @@ -15,8 +15,7 @@ # along with Medusa. If not, see . """Test ShowPoster.""" - -from __future__ import print_function +from __future__ import unicode_literals from medusa.media.poster import ShowPoster from medusa.tv import Series diff --git a/tests/legacy/notifier_tests.py b/tests/legacy/notifier_tests.py index 62fb8fd183..92aaa329b1 100644 --- a/tests/legacy/notifier_tests.py +++ b/tests/legacy/notifier_tests.py @@ -20,8 +20,7 @@ # classes in order to test those classes. Therefore we will be pylint disable protected-access """Test notifiers.""" - -from __future__ import print_function +from __future__ import unicode_literals from medusa import db from medusa.helper.encoding import ss @@ -31,6 +30,8 @@ from medusa.tv import Episode, Series from tests.legacy import test_lib as test +from six import text_type + class NotifierTests(test.AppTestDBCase): """Test notifiers.""" @@ -50,25 +51,25 @@ def setUpClass(cls): # one of the DB columns. Therefore, to test properly, we must create some shows that # store emails in the old method (legacy method) and then other shows that will use # the new method. - for show_counter in range(100, 100 + num_legacy_shows): + for show_counter in list(range(100, 100 + num_legacy_shows)): show = Series(1, show_counter) - show.name = "Show " + str(show_counter) + show.name = "Show " + text_type(show_counter) show.episodes = [] - for episode_counter in range(0, num_episodes_per_show): + for episode_counter in list(range(0, num_episodes_per_show)): episode = Episode(show, test.SEASON, episode_counter) - episode.name = "Episode " + str(episode_counter + 1) + episode.name = "Episode " + text_type(episode_counter + 1) episode.quality = "SDTV" show.episodes.append(episode) show.save_to_db() cls.legacy_shows.append(show) - for show_counter in range(200, 200 + num_shows): + for show_counter in list(range(200, 200 + num_shows)): show = Series(1, show_counter) - show.name = "Show " + str(show_counter) + show.name = "Show " + text_type(show_counter) show.episodes = [] - for episode_counter in range(0, num_episodes_per_show): + for episode_counter in list(range(0, num_episodes_per_show)): episode = Episode(show, test.SEASON, episode_counter) - episode.name = "Episode " + str(episode_counter + 1) + episode.name = "Episode " + text_type(episode_counter + 1) episode.quality = "SDTV" show.episodes.append(episode) show.save_to_db() diff --git a/tests/legacy/pp_tests.py b/tests/legacy/pp_tests.py index 154136a936..6f75564b92 100644 --- a/tests/legacy/pp_tests.py +++ b/tests/legacy/pp_tests.py @@ -16,8 +16,7 @@ # You should have received a copy of the GNU General Public License # along with Medusa. If not, see . """PP Tests.""" - -from __future__ import print_function +from __future__ import unicode_literals import unittest diff --git a/tests/legacy/providers/__init__.py b/tests/legacy/providers/__init__.py index 0661325e08..6e4bc62da4 100644 --- a/tests/legacy/providers/__init__.py +++ b/tests/legacy/providers/__init__.py @@ -1,2 +1,3 @@ # coding=utf-8 """Tests for providers package.""" +from __future__ import unicode_literals diff --git a/tests/legacy/providers/generic_provider_tests.py b/tests/legacy/providers/generic_provider_tests.py index 03a6d6d307..3920c96c28 100644 --- a/tests/legacy/providers/generic_provider_tests.py +++ b/tests/legacy/providers/generic_provider_tests.py @@ -15,8 +15,7 @@ # along with Medusa. If not, see . """Test GenericProvider.""" - -from __future__ import print_function +from __future__ import unicode_literals import unittest diff --git a/tests/legacy/providers/nzb_provider_tests.py b/tests/legacy/providers/nzb_provider_tests.py index 139f982edb..fa2650d2e7 100644 --- a/tests/legacy/providers/nzb_provider_tests.py +++ b/tests/legacy/providers/nzb_provider_tests.py @@ -15,8 +15,7 @@ # along with Medusa. If not, see . """Test NZBProvider.""" - -from __future__ import print_function +from __future__ import unicode_literals import os diff --git a/tests/legacy/providers/torrent_provider_tests.py b/tests/legacy/providers/torrent_provider_tests.py index 7b14136acf..66afa37ec3 100644 --- a/tests/legacy/providers/torrent_provider_tests.py +++ b/tests/legacy/providers/torrent_provider_tests.py @@ -15,8 +15,7 @@ # along with Medusa. If not, see . """Test TorrentProvider.""" - -from __future__ import print_function +from __future__ import unicode_literals import os diff --git a/tests/legacy/scene_helpers_tests.py b/tests/legacy/scene_helpers_tests.py index 1a9989fcb3..8bdf453995 100644 --- a/tests/legacy/scene_helpers_tests.py +++ b/tests/legacy/scene_helpers_tests.py @@ -1,5 +1,6 @@ # coding=utf-8 """Test scene helpers.""" +from __future__ import unicode_literals import unittest diff --git a/tests/legacy/search_tests.py b/tests/legacy/search_tests.py index cf1a4c6ebb..fd1b821ad3 100644 --- a/tests/legacy/search_tests.py +++ b/tests/legacy/search_tests.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python # coding=UTF-8 # Author: Dennis Lutter # @@ -17,8 +17,7 @@ # You should have received a copy of the GNU General Public License # along with Medusa. If not, see . """Test searches.""" - -from __future__ import print_function +from __future__ import unicode_literals import unittest @@ -27,6 +26,8 @@ from medusa.tv import Episode, Series import test_lib as test +from six import iteritems + TESTS = { "Game of Thrones": { "tvdbid": 121361, "s": 5, "e": [10], @@ -77,7 +78,7 @@ def do_test(self): cur_string = '' for cur_string in season_strings, episode_strings: if not all([isinstance(cur_string, list), isinstance(cur_string[0], dict)]): - print(" %s is using a wrong string format!" % cur_provider.name) + print("%s is using a wrong string format!" % cur_provider.name) print(cur_string) fail = True continue @@ -89,8 +90,8 @@ def do_test(self): assert season_strings == cur_data["s_strings"] assert episode_strings == cur_data["e_strings"] except AssertionError: - print (" %s is using a wrong string format!" % cur_provider.name) - print (cur_string) + print("%s is using a wrong string format!" % cur_provider.name) + print(cur_string) continue search_strings = episode_strings[0] @@ -137,7 +138,7 @@ def do_test(self): """) # create the test methods for forceSearch in (True, False): - for name, data in TESTS.items(): + for name, data in iteritems(TESTS): filename = name.replace(' ', '_') for provider in providers.sorted_provider_list(): diff --git a/tests/legacy/show/__init__.py b/tests/legacy/show/__init__.py index a754c59ffc..e2078fe2ce 100644 --- a/tests/legacy/show/__init__.py +++ b/tests/legacy/show/__init__.py @@ -1,2 +1,3 @@ # coding=utf-8 """Tests for show package.""" +from __future__ import unicode_literals diff --git a/tests/legacy/show/coming_episodes_tests.py b/tests/legacy/show/coming_episodes_tests.py index 19831e6d5b..549aee4d70 100644 --- a/tests/legacy/show/coming_episodes_tests.py +++ b/tests/legacy/show/coming_episodes_tests.py @@ -15,8 +15,7 @@ # along with Medusa. If not, see . """Test coming episodes.""" - -from __future__ import print_function +from __future__ import unicode_literals import unittest diff --git a/tests/legacy/show/history_tests.py b/tests/legacy/show/history_tests.py index 82401b0476..5d455565ce 100644 --- a/tests/legacy/show/history_tests.py +++ b/tests/legacy/show/history_tests.py @@ -15,8 +15,7 @@ # along with Medusa. If not, see . """Test history.""" - -from __future__ import print_function +from __future__ import unicode_literals import unittest diff --git a/tests/legacy/show/show_tests.py b/tests/legacy/show/show_tests.py index 4d96d42987..1f77a30b50 100644 --- a/tests/legacy/show/show_tests.py +++ b/tests/legacy/show/show_tests.py @@ -15,8 +15,7 @@ # along with Medusa. If not, see . """Test shows.""" - -from __future__ import print_function +from __future__ import unicode_literals import unittest diff --git a/tests/legacy/snatch_tests.py b/tests/legacy/snatch_tests.py index e3a1ac556f..eefc089a85 100644 --- a/tests/legacy/snatch_tests.py +++ b/tests/legacy/snatch_tests.py @@ -17,8 +17,7 @@ # along with Medusa. If not, see . """Test snatching.""" - -from __future__ import print_function +from __future__ import unicode_literals import unittest @@ -28,6 +27,9 @@ from tests.legacy import test_lib as test +from six import iteritems + + TESTS = { "Dexter": {"a": 1, "q": common.HD, "s": 5, "e": [7], "b": 'Dexter.S05E07.720p.BluRay.X264-REWARD', "i": ['Dexter.S05E07.720p.BluRay.X264-REWARD', 'Dexter.S05E07.720p.X264-REWARD']}, @@ -126,7 +128,7 @@ def do_test(): # create the test methods cur_tvdb_id = 1 for forceSearch in (True, False): - for name, data in TESTS.items(): + for name, data in iteritems(TESTS): if not data["a"]: continue filename = name.replace(' ', '_') diff --git a/tests/legacy/ssl_sni_tests.py b/tests/legacy/ssl_sni_tests.py index 85aa07a770..fcc328a6fa 100644 --- a/tests/legacy/ssl_sni_tests.py +++ b/tests/legacy/ssl_sni_tests.py @@ -16,15 +16,16 @@ # You should have received a copy of the GNU General Public License # along with Medusa. If not, see . """SSL SNI Tests.""" -from __future__ import print_function +from __future__ import unicode_literals import unittest - import certifi import medusa.providers as providers from medusa.helper.exceptions import ex import requests +from six import text_type + def generator(_provider): """Generate tests for each provider. @@ -45,7 +46,7 @@ def _connectivity_test(): try: requests.head(_provider.url, verify=certifi.where(), timeout=10) except requests.exceptions.SSLError as error: - if 'certificate verify failed' in str(error): + if 'certificate verify failed' in text_type(error): print('Cannot verify certificate for %s' % _provider.name) else: print('SSLError on %s: %s' % (_provider.name, ex(error.message))) diff --git a/tests/legacy/test_lib.py b/tests/legacy/test_lib.py index c3a7be9162..233b6289c8 100644 --- a/tests/legacy/test_lib.py +++ b/tests/legacy/test_lib.py @@ -19,8 +19,7 @@ # pylint: disable=line-too-long """Create a test database for testing.""" - -from __future__ import print_function +from __future__ import unicode_literals import os.path import shutil @@ -33,6 +32,8 @@ from medusa.providers.nzb.newznab import NewznabProvider from medusa.tv import Episode, cache +from six import text_type + # ================= # test globals # ================= @@ -44,7 +45,7 @@ SHOW_NAME = u"show name" SEASON = 4 EPISODE = 2 -FILENAME = u"show name - s0" + str(SEASON) + "e0" + str(EPISODE) + ".mkv" +FILENAME = u"show name - s0" + text_type(SEASON) + "e0" + text_type(EPISODE) + ".mkv" FILE_DIR = os.path.join(TEST_DIR, SHOW_NAME) FILE_PATH = os.path.join(FILE_DIR, FILENAME) SHOW_DIR = os.path.join(TEST_DIR, SHOW_NAME + " final") @@ -169,7 +170,7 @@ def __init__(self, provider_name): # pylint: disable=broad-except # Catching too general exception except Exception as error: - if str(error) != "table [" + provider_name + "] already exists": + if text_type(error) != "table [" + provider_name + "] already exists": raise # add version column to table if missing @@ -184,7 +185,7 @@ def __init__(self, provider_name): # pylint: disable=broad-except # Catching too general exception except Exception as error: - if str(error) != "table lastUpdate already exists": + if text_type(error) != "table lastUpdate already exists": raise @@ -217,16 +218,6 @@ def teardown_test_db(): from medusa.db import db_cons for connection in db_cons: db_cons[connection].commit() - # db_cons[connection].close() - # - # for current_db in [ TEST_DB_NAME, TEST_CACHE_DB_NAME, TEST_FAILED_DB_NAME ]: - # file_name = os.path.join(TEST_DIR, current_db) - # if os.path.exists(file_name): - # try: - # os.remove(file_name) - # except Exception as e: - # print('ERROR: Failed to remove ' + file_name) - # print(exception(e)) def setup_test_episode_file(): @@ -236,12 +227,11 @@ def setup_test_episode_file(): try: with open(FILE_PATH, 'wb') as ep_file: - ep_file.write("foo bar") + ep_file.write('foo bar') ep_file.flush() - # pylint: disable=broad-except # Catching too general exception except Exception: - print("Unable to set up test episode") + print('Unable to set up test episode') raise diff --git a/tests/legacy/tv_tests.py b/tests/legacy/tv_tests.py index b512e1f465..1b5c78977b 100644 --- a/tests/legacy/tv_tests.py +++ b/tests/legacy/tv_tests.py @@ -17,8 +17,7 @@ # along with Medusa. If not, see . """Test tv.""" - -from __future__ import print_function +from __future__ import unicode_literals from medusa import app from medusa.tv import Episode, Series diff --git a/tests/name_parser/__init__.py b/tests/name_parser/__init__.py index a467eff9a2..a9805ac644 100644 --- a/tests/name_parser/__init__.py +++ b/tests/name_parser/__init__.py @@ -1 +1,2 @@ """Name parser tests.""" +from __future__ import unicode_literals diff --git a/tests/name_parser/parse_air_by_date.py b/tests/name_parser/parse_air_by_date.py index c56f5d943b..2b6cb24a08 100644 --- a/tests/name_parser/parse_air_by_date.py +++ b/tests/name_parser/parse_air_by_date.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/test_list_associated_files.py.""" +from __future__ import unicode_literals from medusa import helpers import medusa.scene_numbering diff --git a/tests/name_parser/test_parse_anime.py b/tests/name_parser/test_parse_anime.py index 5496fb727f..21a2369237 100644 --- a/tests/name_parser/test_parse_anime.py +++ b/tests/name_parser/test_parse_anime.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/test_list_associated_files.py.""" +from __future__ import unicode_literals from medusa.name_parser.parser import NameParser import guessit @@ -158,6 +159,38 @@ }, 'expected': ([2], [1], [2]), }, + # Anime show, season scene name with one alias, with scene numbering. Using the season scene name. + { + 'name': u"[HorribleSubs] JoJo's Bizarre Adventure - Stardust Crusaders - 12 [1080p].mkv", + 'indexer_id': 1, + 'indexer': 262954, + 'mocks': [ + ('medusa.scene_exceptions.get_scene_exceptions_by_name', [(262954, 2, 1)]), + ('medusa.scene_numbering.get_indexer_absolute_numbering', 38), + ('medusa.helpers.get_all_episodes_from_absolute_number', (2, [12])), + ], + 'series_info': { + 'name': u"JoJo's Bizarre Adventure", + 'is_scene': True + }, + 'expected': ([12], [2], [38]), + }, + # Anime show, season scene name with two aliases because it's parsing the full path inc the show folder, + # with scene numbering. Using the season scene name. + { + 'name': u"JoJo's Bizarre Adventure (2012)\Season 02\[HorribleSubs] JoJo's Bizarre Adventure - Stardust Crusaders - 12 [1080p].mkv", + 'indexer_id': 1, + 'indexer': 262954, + 'mocks': [ + ('medusa.scene_exceptions.get_scene_exceptions_by_name', [(262954, 2, 1)]), + ('medusa.helpers.get_absolute_number_from_season_and_episode', 38), + ], + 'series_info': { + 'name': u"JoJo's Bizarre Adventure", + 'is_scene': True + }, + 'expected': ([12], [2], [38]), + }, ]) def test_anime_parsing(p, create_tvshow, monkeypatch_function_return): diff --git a/tests/name_parser/test_parse_series.py b/tests/name_parser/test_parse_series.py index 33e04327c1..571e3cf0dc 100644 --- a/tests/name_parser/test_parse_series.py +++ b/tests/name_parser/test_parse_series.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/test_list_associated_files.py.""" +from __future__ import unicode_literals from medusa.name_parser.parser import NameParser from six import iteritems diff --git a/tests/notifiers/__init__.py b/tests/notifiers/__init__.py index 87ca9e2e51..219dbc3444 100644 --- a/tests/notifiers/__init__.py +++ b/tests/notifiers/__init__.py @@ -1,2 +1,3 @@ # coding=utf-8 """Tests for medusa.notifiers module.""" +from __future__ import unicode_literals diff --git a/tests/providers/__init__.py b/tests/providers/__init__.py index 7dacfd3503..1279adebbe 100644 --- a/tests/providers/__init__.py +++ b/tests/providers/__init__.py @@ -1 +1,2 @@ """Provider tests.""" +from __future__ import unicode_literals diff --git a/tests/providers/conftest.py b/tests/providers/conftest.py index 766ec63354..1215d42650 100644 --- a/tests/providers/conftest.py +++ b/tests/providers/conftest.py @@ -14,15 +14,15 @@ def get_providers(): - from medusa.providers.torrent import (anidex, horriblesubs, limetorrents, newpct, nyaa, rarbg, shanaproject, - thepiratebay, tokyotoshokan, torrent9, torrentz2, yggtorrent, zooqle) + from medusa.providers.torrent import (anidex, limetorrents, nyaa, rarbg, shanaproject, tntvillage, + thepiratebay, tokyotoshokan, torrentz2, zooqle) + from medusa.providers.nzb import anizb, binsearch - return (anidex, horriblesubs, limetorrents, newpct, nyaa, rarbg, shanaproject, - thepiratebay, tokyotoshokan, torrent9, torrentz2, yggtorrent, zooqle) + return (anidex, limetorrents, nyaa, rarbg, shanaproject, tntvillage, + thepiratebay, tokyotoshokan, torrentz2, zooqle, anizb, binsearch) -@pytest.fixture(scope='session') -def providers(): +def get_provider_data(): Provider = namedtuple('Provider', 'name type klass data') providers = [Provider(name=provider.__name__.rpartition('.')[2], type=provider.__name__.split('.', 3)[2], @@ -31,7 +31,6 @@ def providers(): for provider in get_providers()] for provider in providers: - # Load provider test config input_file = os.path.join(__location__, provider.type, provider.name, provider.name + '_test.yaml') with open(input_file, 'r') as stream: @@ -41,3 +40,8 @@ def providers(): provider.data.update(test_data) return providers + + +@pytest.fixture(scope='session') +def providers(): + return get_provider_data() diff --git a/tests/providers/nzb/anizb/anizb_backlog.yaml b/tests/providers/nzb/anizb/anizb_backlog.yaml new file mode 100644 index 0000000000..581e130dae --- /dev/null +++ b/tests/providers/nzb/anizb/anizb_backlog.yaml @@ -0,0 +1,99 @@ +interactions: +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; d26d37e1-3389-11e9-8d14-1c1b0d9d2a41)] + method: GET + uri: https://anizb.org/api?q=Dragon+Ball+Z+003 + response: + body: {string: !!python/unicode ' + + Redirecting... + +

Redirecting...

+ +

You should be redirected automatically to target URL: http://anizb.org/api/?q=Dragon+Ball+Z+003. If + not click the link.'} + headers: + connection: [keep-alive] + content-length: ['289'] + content-type: [text/html; charset=utf-8] + date: ['Mon, 18 Feb 2019 14:31:15 GMT'] + location: ['http://anizb.org/api/?q=Dragon+Ball+Z+003'] + server: [nginx/1.14.0 (Ubuntu)] + status: {code: 301, message: MOVED PERMANENTLY} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; d26d37e1-3389-11e9-8d14-1c1b0d9d2a41)] + method: GET + uri: http://anizb.org/api/?q=Dragon+Ball+Z+003 + response: + body: {string: !!python/unicode "\r\n301 Moved Permanently\r\n\r\n

301 Moved Permanently

\r\n
nginx/1.14.0 + (Ubuntu)
\r\n\r\n\r\n"} + headers: + connection: [keep-alive] + content-length: ['194'] + content-type: [text/html] + date: ['Mon, 18 Feb 2019 14:31:16 GMT'] + location: ['https://anizb.org/api/?q=Dragon+Ball+Z+003'] + server: [nginx/1.14.0 (Ubuntu)] + status: {code: 301, message: Moved Permanently} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; d26d37e1-3389-11e9-8d14-1c1b0d9d2a41)] + method: GET + uri: https://anizb.org/api/?q=Dragon+Ball+Z+003 + response: + body: {string: !!python/unicode "\n\n \n anizb\n https://anizb.org/\n + \ highspeed anime indexer\n \n http://www.rssboard.org/rss-specification\n + \ python-feedgen\n en\n Mon, + 18 Feb 2019 14:31:16 +0000\n \n [JasonSpidey71]Dragon + Ball Z - 003 - All Right! This is the Strongest Combo in the World!\n + \ https://anizb.org/dl/39101/\n [JasonSpidey71]Dragon + Ball Z - 003 - All Right! This is the Strongest Combo in the World![BroadcastAudio][CC][Pilot] + [1/8] - \"[JasonSpidey71]Dragon Ball Z - 003 - All Right! This is the Strongest + Combo in the World!.mkv\" yEnc (1/2251) 1613392113\n https://anizb.org/dl/39101/\n \n + \ Mon, 05 Nov 2018 00:10:06 +0000\n \n \n + \ [JasonSpidey71]Dragon Ball Z - 003 - All Right! This is the Strongest + Combo in the World!\n https://anizb.org/dl/39446/\n + \ [JasonSpidey71]Dragon Ball Z - 003 - All Right! This is + the Strongest Combo in the World![BroadcastAudio][CC] [1/9] - \"[JasonSpidey71]Dragon + Ball Z - 003 - All Right! This is the Strongest Combo in the World!.mkv\" + yEnc (1/2625) 1880952777\n https://anizb.org/dl/39446/\n + \ \n Mon, 05 Nov 2018 16:32:01 +0000\n + \ \n \n [JasonSPIdey71]Dragon Ball Z - 003 - + All Right! This is the Strongest Combo in the World! [05296DC3]\n + \ https://anizb.org/dl/40230/\n [JasonSpidey71]Dragon + Ball Z - Saiyan Saga - Raditz Saga[Episodes 1-6][BroadcastAudio][DBOX][CC] + [1/8] - \"[JasonSPIdey71]Dragon Ball Z - 003 - All Right! This is the Strongest + Combo in the World! [05296DC3].mkv\" yEnc (1/2123) 1521651607\n + \ https://anizb.org/dl/40230/\n \n + \ Fri, 09 Nov 2018 16:04:40 +0000\n \n \n\n"} + headers: + connection: [keep-alive] + content-disposition: [inline; filename=feed.xml] + content-length: ['2596'] + content-type: [application/rss+xml] + date: ['Mon, 18 Feb 2019 14:31:16 GMT'] + server: [nginx/1.14.0 (Ubuntu)] + status: {code: 200, message: OK} +version: 1 diff --git a/tests/providers/nzb/anizb/anizb_daily.yaml b/tests/providers/nzb/anizb/anizb_daily.yaml new file mode 100644 index 0000000000..292b8bd879 --- /dev/null +++ b/tests/providers/nzb/anizb/anizb_daily.yaml @@ -0,0 +1,738 @@ +interactions: +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; d26d37e1-3389-11e9-8d14-1c1b0d9d2a41)] + method: GET + uri: https://anizb.org/api?q= + response: + body: {string: !!python/unicode ' + + Redirecting... + +

Redirecting...

+ +

You should be redirected automatically to target URL: http://anizb.org/api/?q=. If + not click the link.'} + headers: + connection: [keep-alive] + content-length: ['255'] + content-type: [text/html; charset=utf-8] + date: ['Mon, 18 Feb 2019 14:31:10 GMT'] + location: ['http://anizb.org/api/?q='] + server: [nginx/1.14.0 (Ubuntu)] + status: {code: 301, message: MOVED PERMANENTLY} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; d26d37e1-3389-11e9-8d14-1c1b0d9d2a41)] + method: GET + uri: http://anizb.org/api/?q= + response: + body: {string: !!python/unicode "\r\n301 Moved Permanently\r\n\r\n

301 Moved Permanently

\r\n
nginx/1.14.0 + (Ubuntu)
\r\n\r\n\r\n"} + headers: + connection: [keep-alive] + content-length: ['194'] + content-type: [text/html] + date: ['Mon, 18 Feb 2019 14:31:10 GMT'] + location: ['https://anizb.org/api/?q='] + server: [nginx/1.14.0 (Ubuntu)] + status: {code: 301, message: Moved Permanently} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; d26d37e1-3389-11e9-8d14-1c1b0d9d2a41)] + method: GET + uri: https://anizb.org/api/?q= + response: + body: {string: "\n\n + \ \n anizb\n https://anizb.org/\n + \ highspeed anime indexer\n \n http://www.rssboard.org/rss-specification\n + \ python-feedgen\n en\n Mon, + 18 Feb 2019 14:31:11 +0000\n \n [Leeson] + Kimagure Orange Road - 48\n https://anizb.org/dl/65437/\n + \ [Leeson] Kimagure Orange Road (720p Web AC3) [1/7] - \"[Leeson] + Kimagure Orange Road - 48.mkv\" yEnc (1/809) 579781131\n https://anizb.org/dl/65437/\n \n + \ Mon, 18 Feb 2019 05:52:05 +0000\n \n \n + \ [GJM] To Aru Majutsu no Index III - 19 [6B11483D]\n https://anizb.org/dl/65439/\n + \ [GJM] To Aru Majutsu no Index III - 19 [6B11483D].mkv [1/8] + - \"[GJM] To Aru Majutsu no Index III - 19 [6B11483D].mkv\" yEnc (1/1367) + 979664014\n https://anizb.org/dl/65439/\n + \ \n Mon, 18 Feb 2019 06:18:01 +0000\n + \ \n \n A Silent Voice - Koe no Katachi 1036p + V1 [jhl]\n https://anizb.org/dl/65440/\n A + Silent Voice - Koe no Katachi 1036p V1 [jhl][H265][EN51,JP51,CNT51,INS51,HX,COM] + [1/9] - \"A Silent Voice - Koe no Katachi 1036p V1 [jhl].mkv\" yEnc (1/3826) + 2742068162\n https://anizb.org/dl/65440/\n + \ \n Mon, 18 Feb 2019 08:36:01 +0000\n + \ \n \n Boku no Hero Academia All Might - Rising + The Animation [ENG SUB][OVA].mp4-480\n https://anizb.org/dl/65444/\n + \ My Hero Academia - All Might Rising [1/2] - \"Boku_no_Hero_Academia_All_Might_-_Rising_The_Animation__[ENG_SUB][OVA].mp4-480.mp4\" + yEnc (1/26) 18386002\n https://anizb.org/dl/65444/\n + \ \n + \ Mon, 18 Feb 2019 09:54:06 +0000\n \n \n + \ Boku no Hero Academia All Might - Rising The Animation [ENG SUB][OVA].mp4-480\n + \ https://anizb.org/dl/65443/\n My Hero + Academia - All Might Rising [1/2] - \"Boku_no_Hero_Academia_All_Might_-_Rising_The_Animation__[ENG_SUB][OVA].mp4-480.mp4\" + yEnc (1/26) 18386002\n https://anizb.org/dl/65443/\n + \ \n + \ Mon, 18 Feb 2019 09:54:06 +0000\n \n \n + \ Boku no Hero Academia All Might - Rising The Animation [ENG SUB][OVA].mp4-480\n + \ https://anizb.org/dl/65442/\n My Hero + Academia - All Might Rising [1/2] - \"Boku_no_Hero_Academia_All_Might_-_Rising_The_Animation__[ENG_SUB][OVA].mp4-480.mp4\" + yEnc (1/26) 18386002\n https://anizb.org/dl/65442/\n + \ \n + \ Mon, 18 Feb 2019 09:54:06 +0000\n \n \n + \ Boku no Hero Academia All Might - Rising The Animation [ENG SUB][OVA].mp4-480\n + \ https://anizb.org/dl/65451/\n My Hero + Academia - All Might Rising [1/2] - \"Boku_no_Hero_Academia_All_Might_-_Rising_The_Animation__[ENG_SUB][OVA].mp4-480.mp4\" + yEnc (1/26) 18386002\n https://anizb.org/dl/65451/\n + \ \n + \ Mon, 18 Feb 2019 09:54:06 +0000\n \n \n + \ Boku no Hero Academia All Might - Rising The Animation [ENG SUB][OVA].mp4-480\n + \ https://anizb.org/dl/65441/\n My Hero + Academia - All Might Rising [1/2] - \"Boku_no_Hero_Academia_All_Might_-_Rising_The_Animation__[ENG_SUB][OVA].mp4-480.mp4\" + yEnc (1/26) 18386002\n https://anizb.org/dl/65441/\n + \ \n + \ Mon, 18 Feb 2019 09:54:06 +0000\n \n \n + \ Boku no Hero Academia All Might - Rising The Animation [ENG SUB][OVA].mp4-480\n + \ https://anizb.org/dl/65445/\n My Hero + Academia - All Might Rising [1/2] - \"Boku_no_Hero_Academia_All_Might_-_Rising_The_Animation__[ENG_SUB][OVA].mp4-480.mp4\" + yEnc (1/26) 18386002\n https://anizb.org/dl/65445/\n + \ \n + \ Mon, 18 Feb 2019 09:54:06 +0000\n \n \n + \ Transformers Victory01 - The Brave Hero of the Universe - Star + Saber\n https://anizb.org/dl/65452/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory01 - The Brave + Hero of the Universe - Star Saber.mp4\" yEnc (1/549) 393114715\n + \ https://anizb.org/dl/65452/\n \n + \ Mon, 18 Feb 2019 10:46:02 +0000\n \n \n + \ Transformers Victory02 - Surprise Attack! Dinoking\n + \ https://anizb.org/dl/65450/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory02 - Surprise + Attack! Dinoking.mp4\" yEnc (1/538) 385192239\n https://anizb.org/dl/65450/\n + \ \n Mon, 18 Feb 2019 10:46:45 +0000\n + \ \n \n Transformers Victory03 - Attack! Leozack\n + \ https://anizb.org/dl/65448/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory03 - Attack! Leozack.mp4\" + yEnc (1/500) 357959476\n https://anizb.org/dl/65448/\n + \ \n Mon, 18 Feb 2019 10:47:24 +0000\n + \ \n \n Transformers Victory04 - Unite!! Multiforce\n + \ https://anizb.org/dl/65449/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory04 - Unite!! Multiforce.mp4\" + yEnc (1/510) 365265021\n https://anizb.org/dl/65449/\n + \ \n Mon, 18 Feb 2019 10:48:08 +0000\n + \ \n \n Transformers Victory05 - Move Out! Rescue + Team\n https://anizb.org/dl/65446/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory05 - Move Out! + Rescue Team.mp4\" yEnc (1/494) 353452858\n https://anizb.org/dl/65446/\n + \ \n Mon, 18 Feb 2019 10:48:51 +0000\n + \ \n \n Transformers Victory06 - Infiltration...Uranium + Mine\n https://anizb.org/dl/65447/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory06 - Infiltration...Uranium + Mine.mp4\" yEnc (1/505) 361933691\n https://anizb.org/dl/65447/\n + \ \n Mon, 18 Feb 2019 10:49:29 +0000\n + \ \n \n Transformers Victory07 - Explosion!! + Energy Base\n https://anizb.org/dl/65465/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory07 - Explosion!! + Energy Base.mp4\" yEnc (1/523) 374669673\n https://anizb.org/dl/65465/\n + \ \n Mon, 18 Feb 2019 10:50:08 +0000\n + \ \n \n Transformers Victory08 - Big City - + Underground Terror\n https://anizb.org/dl/65466/\n + \ Transformers Victory (Sub) - 1-37 Complete [1/6] - \"Transformers + Victory08 - Big City - Underground Terror.mp4\" yEnc (1/505) 361575320\n + \ https://anizb.org/dl/65466/\n \n + \ Mon, 18 Feb 2019 10:50:46 +0000\n \n \n + \ Transformers Victory09 - Clash!! Two Great Heroes\n https://anizb.org/dl/65464/\n + \ Transformers Victory (Sub) - 1-37 Complete [1/6] - \"Transformers + Victory09 - Clash!! Two Great Heroes.mp4\" yEnc (1/538) 385304743\n + \ https://anizb.org/dl/65464/\n \n + \ Mon, 18 Feb 2019 10:51:30 +0000\n \n \n + \ Transformers Victory10 - The New Warrior - Hellbat\n + \ https://anizb.org/dl/65462/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory10 - The New Warrior + - Hellbat.mp4\" yEnc (1/492) 351974055\n https://anizb.org/dl/65462/\n + \ \n Mon, 18 Feb 2019 10:52:16 +0000\n + \ \n \n Transformers Victory11 - Attack the + Shuttle Base!!\n https://anizb.org/dl/65463/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory11 - Attack the + Shuttle Base!!.mp4\" yEnc (1/467) 334736838\n https://anizb.org/dl/65463/\n + \ \n Mon, 18 Feb 2019 10:52:57 +0000\n + \ \n \n Transformers Victory12 - Tanker Robbing + Operation\n https://anizb.org/dl/65460/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory12 - Tanker Robbing + Operation.mp4\" yEnc (1/522) 373803541\n https://anizb.org/dl/65460/\n + \ \n Mon, 18 Feb 2019 10:53:39 +0000\n + \ \n \n Transformers Victory13 - Move Out!! + Breastforce\n https://anizb.org/dl/65461/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory13 - Move Out!! + Breastforce.mp4\" yEnc (1/577) 413396551\n https://anizb.org/dl/65461/\n + \ \n Mon, 18 Feb 2019 10:54:24 +0000\n + \ \n \n Transformers Victory14 - Rescue Jean!!\n + \ https://anizb.org/dl/65458/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory14 - Rescue Jean!!.mp4\" + yEnc (1/536) 383770871\n https://anizb.org/dl/65458/\n + \ \n Mon, 18 Feb 2019 10:55:08 +0000\n + \ \n \n Transformers Victory15 - Mach and Tackle\n + \ https://anizb.org/dl/65459/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory15 - Mach and + Tackle.mp4\" yEnc (1/527) 377608108\n https://anizb.org/dl/65459/\n + \ \n Mon, 18 Feb 2019 10:55:51 +0000\n + \ \n \n Transformers Victory16 - Fierce Battle!! + Asteroid\n https://anizb.org/dl/65456/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory16 - Fierce Battle!! + Asteroid.mp4\" yEnc (1/524) 375438507\n https://anizb.org/dl/65456/\n + \ \n Mon, 18 Feb 2019 10:56:37 +0000\n + \ \n \n Transformers Victory17 - Planet Micro + - The Mysterious Warrior\n https://anizb.org/dl/65457/\n + \ Transformers Victory (Sub) - 1-37 Complete [1/6] - \"Transformers + Victory17 - Planet Micro - The Mysterious Warrior.mp4\" yEnc (1/516) 369834840\n + \ https://anizb.org/dl/65457/\n \n + \ Mon, 18 Feb 2019 10:57:19 +0000\n \n \n + \ Transformers Victory18 - Rescue! Gaihawk\n https://anizb.org/dl/65454/\n + \ Transformers Victory (Sub) - 1-37 Complete [1/6] - \"Transformers + Victory18 - Rescue! Gaihawk.mp4\" yEnc (1/493) 353280653\n https://anizb.org/dl/65454/\n \n + \ Mon, 18 Feb 2019 10:57:58 +0000\n \n \n + \ Transformers Victory19 - Unite! Liokaiser\n https://anizb.org/dl/65455/\n + \ Transformers Victory (Sub) - 1-37 Complete [1/6] - \"Transformers + Victory19 - Unite! Liokaiser.mp4\" yEnc (1/483) 346012062\n + \ https://anizb.org/dl/65455/\n \n + \ Mon, 18 Feb 2019 10:58:39 +0000\n \n \n + \ Transformers Victory20 - Assemble! Warrior Combiner\n + \ https://anizb.org/dl/65453/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory20 - Assemble! + Warrior Combiner.mp4\" yEnc (1/596) 426555029\n https://anizb.org/dl/65453/\n + \ \n Mon, 18 Feb 2019 10:59:18 +0000\n + \ \n \n Transformers Victory21 - Resurrection! + The Destron Fortress\n https://anizb.org/dl/65480/\n + \ Transformers Victory (Sub) - 1-37 Complete [1/6] - \"Transformers + Victory21 - Resurrection! The Destron Fortress.mp4\" yEnc (1/510) 364990702\n + \ https://anizb.org/dl/65480/\n \n + \ Mon, 18 Feb 2019 11:00:04 +0000\n \n \n + \ Transformers Victory22 - Battle Up of Anger!!\n https://anizb.org/dl/65481/\n + \ Transformers Victory (Sub) - 1-37 Complete [1/6] - \"Transformers + Victory22 - Battle Up of Anger!!.mp4\" yEnc (1/510) 364891430\n + \ https://anizb.org/dl/65481/\n \n + \ Mon, 18 Feb 2019 11:00:43 +0000\n \n \n + \ Transformers Victory23 - Fight to the Death!! Antarctic Battle\n + \ https://anizb.org/dl/65478/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory23 - Fight to + the Death!! Antarctic Battle.mp4\" yEnc (1/558) 399603506\n + \ https://anizb.org/dl/65478/\n \n + \ Mon, 18 Feb 2019 11:01:24 +0000\n \n \n + \ Transformers Victory24 - Crisis! Desert Ambush\n https://anizb.org/dl/65479/\n + \ Transformers Victory (Sub) - 1-37 Complete [1/6] - \"Transformers + Victory24 - Crisis! Desert Ambush.mp4\" yEnc (1/512) 366380982\n + \ https://anizb.org/dl/65479/\n \n + \ Mon, 18 Feb 2019 11:02:10 +0000\n \n \n + \ Transformers Victory25 - A Deadly Battle Bet\n https://anizb.org/dl/65476/\n + \ Transformers Victory (Sub) - 1-37 Complete [1/6] - \"Transformers + Victory25 - A Deadly Battle Bet.mp4\" yEnc (1/507) 362924341\n + \ https://anizb.org/dl/65476/\n \n + \ Mon, 18 Feb 2019 11:02:52 +0000\n \n \n + \ Transformers Victory26 - Ginrai Dies!!\n https://anizb.org/dl/65477/\n + \ Transformers Victory (Sub) - 1-37 Complete [1/6] - \"Transformers + Victory26 - Ginrai Dies!!.mp4\" yEnc (1/467) 334615573\n https://anizb.org/dl/65477/\n \n + \ Mon, 18 Feb 2019 11:03:33 +0000\n \n \n + \ Transformers Victory27 - Fight!! Victory Leo\n https://anizb.org/dl/65474/\n + \ Transformers Victory (Sub) - 1-37 Complete [1/6] - \"Transformers + Victory27 - Fight!! Victory Leo.mp4\" yEnc (1/592) 423707067\n + \ https://anizb.org/dl/65474/\n \n + \ Mon, 18 Feb 2019 11:04:11 +0000\n \n \n + \ Transformers Victory28 - Desperate Situation!! Cybertron\n + \ https://anizb.org/dl/65475/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory28 - Desperate + Situation!! Cybertron.mp4\" yEnc (1/565) 404290984\n https://anizb.org/dl/65475/\n \n + \ Mon, 18 Feb 2019 11:04:54 +0000\n \n \n + \ Transformers Victory29 - Awaken! Victory Leo\n https://anizb.org/dl/65473/\n + \ Transformers Victory (Sub) - 1-37 Complete [1/6] - \"Transformers + Victory29 - Awaken! Victory Leo.mp4\" yEnc (1/520) 372735725\n + \ https://anizb.org/dl/65473/\n \n + \ Mon, 18 Feb 2019 11:05:36 +0000\n \n \n + \ Transformers Victory30 - Turnaround! Deadly Victory Unity\n + \ https://anizb.org/dl/65471/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory30 - Turnaround! + Deadly Victory Unity.mp4\" yEnc (1/508) 364107834\n https://anizb.org/dl/65471/\n \n + \ Mon, 18 Feb 2019 11:06:16 +0000\n \n \n + \ Transformers Victory31 - Jan - Defend the School!!\n + \ https://anizb.org/dl/65472/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory31 - Jan - Defend + the School!!.mp4\" yEnc (1/536) 383639376\n https://anizb.org/dl/65472/\n + \ \n Mon, 18 Feb 2019 11:06:56 +0000\n + \ \n \n Transformers Victory32 - Mysterious! + The Base Explosion Trap\n https://anizb.org/dl/65469/\n + \ Transformers Victory (Sub) - 1-37 Complete [1/6] - \"Transformers + Victory32 - Mysterious! The Base Explosion Trap.mp4\" yEnc (1/443) 317070466\n + \ https://anizb.org/dl/65469/\n \n + \ Mon, 18 Feb 2019 11:07:40 +0000\n \n \n + \ Transformers Victory33 - The Death-Bringing Space Insects!!\n + \ https://anizb.org/dl/65470/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory33 - The Death-Bringing + Space Insects!!.mp4\" yEnc (1/576) 412785066\n https://anizb.org/dl/65470/\n + \ \n Mon, 18 Feb 2019 11:08:18 +0000\n + \ \n \n Transformers Victory34 - The Strongest! + Victory Saber\n https://anizb.org/dl/65467/\n Transformers + Victory (Sub) - 1-37 Complete [1/7] - \"Transformers Victory34 - The Strongest! + Victory Saber.mp4\" yEnc (1/602) 431411749\n https://anizb.org/dl/65467/\n + \ \n Mon, 18 Feb 2019 11:09:05 +0000\n + \ \n \n Transformers Victory35 - Terror of the + Giant Tsuanami\n https://anizb.org/dl/65468/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory35 - Terror of + the Giant Tsuanami.mp4\" yEnc (1/541) 387469978\n https://anizb.org/dl/65468/\n \n + \ Mon, 18 Feb 2019 11:09:50 +0000\n \n \n + \ Transformers Victory36 -The Wrath of the Resurrected Giant Fortress!\n + \ https://anizb.org/dl/65483/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory36 -The Wrath + of the Resurrected Giant Fortress!.mp4\" yEnc (1/489) 350183163\n + \ https://anizb.org/dl/65483/\n \n + \ Mon, 18 Feb 2019 11:10:30 +0000\n \n \n + \ Transformers Victory37 - Clash! Fortress vs Victory Unity\n + \ https://anizb.org/dl/65482/\n Transformers + Victory (Sub) - 1-37 Complete [1/6] - \"Transformers Victory37 - Clash! Fortress + vs Victory Unity.mp4\" yEnc (1/584) 418138129\n https://anizb.org/dl/65482/\n + \ \n Mon, 18 Feb 2019 11:11:06 +0000\n + \ \n \n [U3-Web] Dororo 2019 - EP06 [WEB 1080p + AVC E-AC-3] [Multi-Subs] [6A45FE84]\n https://anizb.org/dl/65484/\n + \ [U3-Web] Dororo / \u3069\u308D\u308D / \u591A\u7F85\u7F85 + 2019 [EP06] [Multi-Subs] [AMZN WEB-DL 1080p AVC E-AC-3] [1/8] - \"[U3-Web] + Dororo 2019 - EP06 [WEB 1080p AVC E-AC-3] [Multi-Subs] [6A45FE84].mkv\" yEnc + (1/2065) 1479762899\n https://anizb.org/dl/65484/\n + \ \n Mon, 18 Feb 2019 11:50:02 +0000\n + \ \n \n [HorribleSubs] Saint Seiya - Saintia + Shou - 10 [480p]\n https://anizb.org/dl/65486/\n + \ [HorribleSubs] Saint Seiya - Saintia Shou - 10 [480p].mkv + [1/6] - \"[HorribleSubs] Saint Seiya - Saintia Shou - 10 [480p].mkv\" yEnc + (1/425) 304448809\n https://anizb.org/dl/65486/\n + \ \n Mon, 18 Feb 2019 12:06:07 +0000\n + \ \n \n [HorribleSubs] Saint Seiya - Saintia + Shou - 10 [720p]\n https://anizb.org/dl/65485/\n + \ [HorribleSubs] Saint Seiya - Saintia Shou - 10 [720p].mkv + [1/7] - \"[HorribleSubs] Saint Seiya - Saintia Shou - 10 [720p].mkv\" yEnc + (1/889) 636929866\n https://anizb.org/dl/65485/\n + \ \n Mon, 18 Feb 2019 12:08:23 +0000\n + \ \n \n [HorribleSubs] Saint Seiya - Saintia + Shou - 10 [1080p]\n https://anizb.org/dl/65488/\n + \ [HorribleSubs] Saint Seiya - Saintia Shou - 10 [1080p].mkv + [1/8] - \"[HorribleSubs] Saint Seiya - Saintia Shou - 10 [1080p].mkv\" yEnc + (1/1821) 1304657581\n https://anizb.org/dl/65488/\n + \ \n Mon, 18 Feb 2019 12:10:02 +0000\n + \ \n \n [Erai-raws] Saint Seiya - Saintia Shou + - 10 [720p][Multiple Subtitle]\n https://anizb.org/dl/65487/\n + \ [Erai-raws] Saint Seiya - Saintia Shou - 10 [720p][Multiple + Subtitle].mkv [1/7] - \"[Erai-raws] Saint Seiya - Saintia Shou - 10 [720p][Multiple + Subtitle].mkv\" yEnc (1/889) 636527575\n https://anizb.org/dl/65487/\n + \ \n Mon, 18 Feb 2019 12:14:07 +0000\n + \ \n \n [Erai-raws] Saint Seiya - Saintia Shou + - 10 [1080p][Multiple Subtitle]\n https://anizb.org/dl/65489/\n + \ [Erai-raws] Saint Seiya - Saintia Shou - 10 [1080p][Multiple + Subtitle].mkv [1/8] - \"[Erai-raws] Saint Seiya - Saintia Shou - 10 [1080p][Multiple + Subtitle].mkv\" yEnc (1/1820) 1304255295\n https://anizb.org/dl/65489/\n + \ \n Mon, 18 Feb 2019 12:20:01 +0000\n + \ \n \n [Erai-raws] Virtual-san wa Miteiru - + 06 [720p HEVC][Multiple Subtitle]\n https://anizb.org/dl/65492/\n + \ [Erai-raws] Virtual-san wa Miteiru - 06 [720p HEVC][Multiple + Subtitle].mkv [1/7] - \"[Erai-raws] Virtual-san wa Miteiru - 06 [720p HEVC][Multiple + Subtitle].mkv\" yEnc (1/753) 539280338\n https://anizb.org/dl/65492/\n + \ \n Mon, 18 Feb 2019 13:00:07 +0000\n + \ \n \n [Erai-raws] Virtual-san wa Miteiru - + 06 [1080p HEVC][Multiple Subtitle]\n https://anizb.org/dl/65490/\n + \ [Erai-raws] Virtual-san wa Miteiru - 06 [1080p HEVC][Multiple + Subtitle].mkv [1/8] - \"[Erai-raws] Virtual-san wa Miteiru - 06 [1080p HEVC][Multiple + Subtitle].mkv\" yEnc (1/1825) 1307797651\n https://anizb.org/dl/65490/\n + \ \n Mon, 18 Feb 2019 13:06:01 +0000\n + \ \n \n [U3-Web] Dororo 2019 - EP05 [WEB 1080p + AVC E-AC-3] [Multi-Subs] [CD0B6408]\n https://anizb.org/dl/65491/\n + \ [U3-Web] Dororo / \u3069\u308D\u308D / \u591A\u7F85\u7F85 + 2019 [EP05] [Multi-Subs] [AMZN WEB-DL 1080p AVC E-AC-3] [1/7] - \"[U3-Web] + Dororo 2019 - EP05 [WEB 1080p AVC E-AC-3] [Multi-Subs] [CD0B6408].mkv\" yEnc + (1/787) 564112856\n https://anizb.org/dl/65491/\n + \ \n Mon, 18 Feb 2019 13:06:06 +0000\n + \ \n \n Transformers Victory 01 - The Brave + Hero of the Universe - Star Saber\n https://anizb.org/dl/65508/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 01 - The Brave Hero + of the Universe - Star Saber.mp4\" yEnc (1/549) 393114715\n + \ https://anizb.org/dl/65508/\n \n + \ Mon, 18 Feb 2019 13:20:01 +0000\n \n \n + \ Transformers Victory 02 - Surprise Attack! Dinoking\n + \ https://anizb.org/dl/65506/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 02 - Surprise Attack! Dinoking.mp4\" yEnc (1/538) + 385192239\n https://anizb.org/dl/65506/\n + \ \n Mon, 18 Feb 2019 13:20:35 +0000\n + \ \n \n Transformers Victory 03 - Attack! Leozack\n + \ https://anizb.org/dl/65507/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 03 - Attack! Leozack.mp4\" yEnc (1/500) 357959476\n + \ https://anizb.org/dl/65507/\n \n + \ Mon, 18 Feb 2019 13:21:20 +0000\n \n \n + \ Transformers Victory 04 - Unite!! Multiforce\n https://anizb.org/dl/65504/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 04 - Unite!! Multiforce.mp4\" + yEnc (1/510) 365265021\n https://anizb.org/dl/65504/\n + \ \n Mon, 18 Feb 2019 13:21:59 +0000\n + \ \n \n Transformers Victory 05 - Move Out! + Rescue Team\n https://anizb.org/dl/65505/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 05 - Move Out! Rescue Team.mp4\" yEnc (1/494) + 353452858\n https://anizb.org/dl/65505/\n + \ \n Mon, 18 Feb 2019 13:22:38 +0000\n + \ \n \n Transformers Victory 06 - Infiltration...Uranium + Mine\n https://anizb.org/dl/65502/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 06 - Infiltration...Uranium Mine.mp4\" yEnc + (1/505) 361933691\n https://anizb.org/dl/65502/\n + \ \n Mon, 18 Feb 2019 13:23:16 +0000\n + \ \n \n Transformers Victory 07 - Explosion!! + Energy Base\n https://anizb.org/dl/65503/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 07 - Explosion!! Energy Base.mp4\" yEnc (1/523) + 374669673\n https://anizb.org/dl/65503/\n + \ \n Mon, 18 Feb 2019 13:23:57 +0000\n + \ \n \n Transformers Victory 08 - Big City - + Underground Terror\n https://anizb.org/dl/65501/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 08 - Big City - Underground + Terror.mp4\" yEnc (1/505) 361575320\n https://anizb.org/dl/65501/\n + \ \n Mon, 18 Feb 2019 13:24:38 +0000\n + \ \n \n Transformers Victory 09 - Clash!! Two + Great Heroes\n https://anizb.org/dl/65499/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 09 - Clash!! Two Great Heroes.mp4\" yEnc (1/538) + 385304743\n https://anizb.org/dl/65499/\n + \ \n Mon, 18 Feb 2019 13:25:19 +0000\n + \ \n \n Transformers Victory 10 - The New Warrior + - Hellbat\n https://anizb.org/dl/65500/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 10 - The New Warrior - Hellbat.mp4\" yEnc (1/492) + 351974055\n https://anizb.org/dl/65500/\n + \ \n Mon, 18 Feb 2019 13:26:03 +0000\n + \ \n \n Transformers Victory 11 - Attack the + Shuttle Base!!\n https://anizb.org/dl/65497/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 11 - Attack the Shuttle Base!!.mp4\" yEnc (1/467) + 334736838\n https://anizb.org/dl/65497/\n + \ \n Mon, 18 Feb 2019 13:26:39 +0000\n + \ \n \n Transformers Victory 12 - Tanker Robbing + Operation\n https://anizb.org/dl/65498/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 12 - Tanker Robbing Operation.mp4\" yEnc (1/522) + 373803541\n https://anizb.org/dl/65498/\n + \ \n Mon, 18 Feb 2019 13:27:15 +0000\n + \ \n \n Transformers Victory 13 - Move Out!! + Breastforce\n https://anizb.org/dl/65495/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 13 - Move Out!! Breastforce.mp4\" yEnc (1/577) + 413396551\n https://anizb.org/dl/65495/\n + \ \n Mon, 18 Feb 2019 13:27:53 +0000\n + \ \n \n Transformers Victory 14 - Rescue Jean!!\n + \ https://anizb.org/dl/65496/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 14 - Rescue Jean!!.mp4\" yEnc (1/536) 383770871\n + \ https://anizb.org/dl/65496/\n \n + \ Mon, 18 Feb 2019 13:28:35 +0000\n \n \n + \ Transformers Victory 15 - Mach and Tackle\n https://anizb.org/dl/65493/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 15 - Mach and Tackle.mp4\" + yEnc (1/527) 377608108\n https://anizb.org/dl/65493/\n + \ \n Mon, 18 Feb 2019 13:29:15 +0000\n + \ \n \n Transformers Victory 16 - Fierce Battle!! + Asteroid\n https://anizb.org/dl/65530/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 16 - Fierce Battle!! Asteroid.mp4\" yEnc (1/524) + 375438507\n https://anizb.org/dl/65530/\n + \ \n Mon, 18 Feb 2019 13:29:52 +0000\n + \ \n \n Transformers Victory 16 - Fierce Battle!! + Asteroid\n https://anizb.org/dl/65494/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 16 - Fierce Battle!! Asteroid.mp4\" yEnc (1/524) + 375438507\n https://anizb.org/dl/65494/\n + \ \n Mon, 18 Feb 2019 13:29:52 +0000\n + \ \n \n Transformers Victory 17 - Planet Micro + - The Mysterious Warrior\n https://anizb.org/dl/65528/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 17 - Planet Micro + - The Mysterious Warrior.mp4\" yEnc (1/516) 369834840\n https://anizb.org/dl/65528/\n \n + \ Mon, 18 Feb 2019 13:30:31 +0000\n \n \n + \ Transformers Victory 18 - Rescue! Gaihawk\n https://anizb.org/dl/65529/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 18 - Rescue! Gaihawk.mp4\" + yEnc (1/493) 353280653\n https://anizb.org/dl/65529/\n + \ \n Mon, 18 Feb 2019 13:31:12 +0000\n + \ \n \n Transformers Victory 19 - Unite! Liokaiser\n + \ https://anizb.org/dl/65526/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 19 - Unite! Liokaiser.mp4\" yEnc (1/483) 346012062\n + \ https://anizb.org/dl/65526/\n \n + \ Mon, 18 Feb 2019 13:31:50 +0000\n \n \n + \ Transformers Victory 20 - Assemble! Warrior Combiner\n + \ https://anizb.org/dl/65527/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 20 - Assemble! Warrior Combiner.mp4\" yEnc + (1/596) 426555029\n https://anizb.org/dl/65527/\n + \ \n Mon, 18 Feb 2019 13:32:25 +0000\n + \ \n \n Transformers Victory 21 - Resurrection! + The Destron Fortress\n https://anizb.org/dl/65524/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 21 - Resurrection! + The Destron Fortress.mp4\" yEnc (1/510) 364990702\n https://anizb.org/dl/65524/\n \n + \ Mon, 18 Feb 2019 13:33:08 +0000\n \n \n + \ Transformers Victory 22 - Battle Up of Anger!!\n https://anizb.org/dl/65525/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 22 - Battle Up of + Anger!!.mp4\" yEnc (1/510) 364891430\n https://anizb.org/dl/65525/\n + \ \n Mon, 18 Feb 2019 13:33:47 +0000\n + \ \n \n Transformers Victory 23 - Fight to the + Death!! Antarctic Battle\n https://anizb.org/dl/65523/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 23 - Fight to the + Death!! Antarctic Battle.mp4\" yEnc (1/558) 399603506\n https://anizb.org/dl/65523/\n \n + \ Mon, 18 Feb 2019 13:34:26 +0000\n \n \n + \ Transformers Victory 24 - Crisis! Desert Ambush\n https://anizb.org/dl/65521/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 24 - Crisis! Desert + Ambush.mp4\" yEnc (1/512) 366380982\n https://anizb.org/dl/65521/\n + \ \n Mon, 18 Feb 2019 13:35:11 +0000\n + \ \n \n Transformers Victory 25 - A Deadly Battle + Bet\n https://anizb.org/dl/65522/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 25 - A Deadly Battle Bet.mp4\" yEnc (1/507) + 362924341\n https://anizb.org/dl/65522/\n + \ \n Mon, 18 Feb 2019 13:35:54 +0000\n + \ \n \n Transformers Victory 26 - Ginrai Dies!!\n + \ https://anizb.org/dl/65519/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 26 - Ginrai Dies!!.mp4\" yEnc (1/467) 334615573\n + \ https://anizb.org/dl/65519/\n \n + \ Mon, 18 Feb 2019 13:36:31 +0000\n \n \n + \ Transformers Victory 27 - Fight!! Victory Leo\n https://anizb.org/dl/65520/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 27 - Fight!! Victory + Leo.mp4\" yEnc (1/592) 423707067\n https://anizb.org/dl/65520/\n + \ \n Mon, 18 Feb 2019 13:37:05 +0000\n + \ \n \n Transformers Victory 28 - Desperate + Situation!! Cybertron\n https://anizb.org/dl/65517/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 28 - Desperate Situation!! + Cybertron.mp4\" yEnc (1/565) 404290984\n https://anizb.org/dl/65517/\n + \ \n Mon, 18 Feb 2019 13:37:51 +0000\n + \ \n \n Transformers Victory 29 - Awaken! Victory + Leo\n https://anizb.org/dl/65518/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 29 - Awaken! Victory Leo.mp4\" yEnc (1/520) + 372735725\n https://anizb.org/dl/65518/\n + \ \n Mon, 18 Feb 2019 13:38:38 +0000\n + \ \n \n Transformers Victory 30 - Turnaround! + Deadly Victory Unity\n https://anizb.org/dl/65515/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 30 - Turnaround! Deadly + Victory Unity.mp4\" yEnc (1/508) 364107834\n https://anizb.org/dl/65515/\n + \ \n Mon, 18 Feb 2019 13:39:17 +0000\n + \ \n \n Transformers Victory 31 - Jan - Defend + the School!!\n https://anizb.org/dl/65516/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 31 - Jan - Defend the School!!.mp4\" yEnc (1/536) + 383639376\n https://anizb.org/dl/65516/\n + \ \n Mon, 18 Feb 2019 13:39:57 +0000\n + \ \n \n Transformers Victory 32 - Mysterious! + The Base Explosion Trap\n https://anizb.org/dl/65514/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 32 - Mysterious! The + Base Explosion Trap.mp4\" yEnc (1/443) 317070466\n https://anizb.org/dl/65514/\n \n + \ Mon, 18 Feb 2019 13:40:37 +0000\n \n \n + \ Transformers Victory 33 - The Death-Bringing Space Insects!!\n + \ https://anizb.org/dl/65512/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 33 - The Death-Bringing Space Insects!!.mp4\" + yEnc (1/576) 412785066\n https://anizb.org/dl/65512/\n + \ \n Mon, 18 Feb 2019 13:41:09 +0000\n + \ \n \n Transformers Victory 34 - The Strongest! + Victory Saber\n https://anizb.org/dl/65513/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/7] - \"Transformers Victory 34 - The Strongest! Victory Saber.mp4\" yEnc + (1/602) 431411749\n https://anizb.org/dl/65513/\n + \ \n Mon, 18 Feb 2019 13:41:53 +0000\n + \ \n \n Transformers Victory 35 - Terror of + the Giant Tsuanami\n https://anizb.org/dl/65510/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 35 - Terror of the + Giant Tsuanami.mp4\" yEnc (1/541) 387469978\n https://anizb.org/dl/65510/\n + \ \n Mon, 18 Feb 2019 13:42:39 +0000\n + \ \n \n Transformers Victory 36 -The Wrath of + the Resurrected Giant Fortress!\n https://anizb.org/dl/65511/\n + \ Fight! Super Robot Lifeform Transformers Victory - [JPN + - ENG Sub] 1-37 Complete [1/6] - \"Transformers Victory 36 -The Wrath of the + Resurrected Giant Fortress!.mp4\" yEnc (1/489) 350183163\n https://anizb.org/dl/65511/\n \n + \ Mon, 18 Feb 2019 13:43:23 +0000\n \n \n + \ Transformers Victory 37 - Clash! Fortress vs Victory Unity\n + \ https://anizb.org/dl/65509/\n Fight! + Super Robot Lifeform Transformers Victory - [JPN - ENG Sub] 1-37 Complete + [1/6] - \"Transformers Victory 37 - Clash! Fortress vs Victory Unity.mp4\" + yEnc (1/584) 418138129\n https://anizb.org/dl/65509/\n + \ \n Mon, 18 Feb 2019 13:43:59 +0000\n + \ \n \n [HorribleSubs] Dororo - 07 [480p]\n + \ https://anizb.org/dl/65532/\n [HorribleSubs] + Dororo - 07 [480p].mkv [1/5] - \"[HorribleSubs] Dororo - 07 [480p].mkv\" yEnc + (1/146) 104168477\n https://anizb.org/dl/65532/\n + \ \n Mon, 18 Feb 2019 14:04:06 +0000\n + \ \n \n [HorribleSubs] Dororo - 07 [720p]\n + \ https://anizb.org/dl/65533/\n [HorribleSubs] + Dororo - 07 [720p].mkv [1/6] - \"[HorribleSubs] Dororo - 07 [720p].mkv\" yEnc + (1/301) 215240764\n https://anizb.org/dl/65533/\n + \ \n Mon, 18 Feb 2019 14:06:07 +0000\n + \ \n \n [HorribleSubs] Dororo - 07 [1080p]\n + \ https://anizb.org/dl/65531/\n [HorribleSubs] + Dororo - 07 [1080p].mkv [1/7] - \"[HorribleSubs] Dororo - 07 [1080p].mkv\" + yEnc (1/713) 510633813\n https://anizb.org/dl/65531/\n + \ \n Mon, 18 Feb 2019 14:08:07 +0000\n + \ \n \n [DragsterPS] Dororo S01E06 [720p] [Japanese + Audio] [Multi-Subs] [457D45F1]\n https://anizb.org/dl/65537/\n + \ [DragsterPS] Dororo S01E06 [720p] [Japanese Audio] [Multi-Subs] + [1/6] - \"[DragsterPS] Dororo S01E06 [720p] [Japanese Audio] [Multi-Subs] + [457D45F1].mkv\" yEnc (1/420) 300730061\n https://anizb.org/dl/65537/\n + \ \n Mon, 18 Feb 2019 14:10:08 +0000\n + \ \n \n [DragsterPS] Dororo S01E06 [1080p] [Japanese + Audio] [Multi-Subs] [9F52D960]\n https://anizb.org/dl/65535/\n + \ [DragsterPS] Dororo S01E06 [1080p] [Japanese Audio] [Multi-Subs] + [1/7] - \"[DragsterPS] Dororo S01E06 [1080p] [Japanese Audio] [Multi-Subs] + [9F52D960].mkv\" yEnc (1/875) 626859656\n https://anizb.org/dl/65535/\n + \ \n Mon, 18 Feb 2019 14:12:06 +0000\n + \ \n \n [Erai-raws] Dororo - 07 [720p][Multiple + Subtitle]\n https://anizb.org/dl/65536/\n [Erai-raws] + Dororo - 07 [720p][Multiple Subtitle].mkv [1/6] - \"[Erai-raws] Dororo - 07 + [720p][Multiple Subtitle].mkv\" yEnc (1/325) 232644322\n https://anizb.org/dl/65536/\n \n + \ Mon, 18 Feb 2019 14:16:06 +0000\n \n \n + \ [Erai-raws] Dororo - 07 [1080p][Multiple Subtitle]\n + \ https://anizb.org/dl/65534/\n [Erai-raws] + Dororo - 07 [1080p][Multiple Subtitle].mkv [1/7] - \"[Erai-raws] Dororo - + 07 [1080p][Multiple Subtitle].mkv\" yEnc (1/681) 488071859\n + \ https://anizb.org/dl/65534/\n \n + \ Mon, 18 Feb 2019 14:16:42 +0000\n \n \n\n"} + headers: + connection: [keep-alive] + content-disposition: [inline; filename=feed.xml] + content-length: ['55723'] + content-type: [application/rss+xml] + date: ['Mon, 18 Feb 2019 14:31:11 GMT'] + server: [nginx/1.14.0 (Ubuntu)] + status: {code: 200, message: OK} +version: 1 diff --git a/tests/providers/nzb/anizb/anizb_test.yaml b/tests/providers/nzb/anizb/anizb_test.yaml new file mode 100644 index 0000000000..cc273f9486 --- /dev/null +++ b/tests/providers/nzb/anizb/anizb_test.yaml @@ -0,0 +1,29 @@ +daily: + search_strings: + RSS: [''] + results: + - pubdate: 2017-11-08 00:00:00 + title: '[Leeson] Kimagure Orange Road - 48' + link: https://anizb.org/dl/65437/ + size: 629944360 + - pubdate: 2017-11-08 00:00:00 + title: '[GJM] To Aru Majutsu no Index III - 19 [6B11483D]' + link: https://anizb.org/dl/65439/ + size: 1063848607 + - pubdate: 2017-11-08 00:00:00 + title: A Silent Voice - Koe no Katachi 1036p V1 [jhl] + link: https://anizb.org/dl/65440/ + size: 2974523554 + +backlog: + search_strings: + Episode: ['Dragon Ball Z 003'] + results: + - pubdate: 2017-10-09 00:00:00 + title: '[JasonSpidey71]Dragon Ball Z - 003 - All Right! This is the Strongest Combo in the World!' + link: https://anizb.org/dl/39101/ + size: 1752494217 + - pubdate: 2017-10-09 00:00:00 + title: '[JasonSpidey71]Dragon Ball Z - 003 - All Right! This is the Strongest Combo in the World!' + link: https://anizb.org/dl/39446/ + size: 2042351015 diff --git a/tests/providers/nzb/binsearch/binsearch_backlog.yaml b/tests/providers/nzb/binsearch/binsearch_backlog.yaml new file mode 100644 index 0000000000..99a9cd05ef --- /dev/null +++ b/tests/providers/nzb/binsearch/binsearch_backlog.yaml @@ -0,0 +1,136 @@ +interactions: +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 3174120f-3388-11e9-b8bd-1c1b0d9d2a41)] + method: GET + uri: https://www.binsearch.info/index.php?server=1&q=Arrow+S07E07&xminsize=20&adv_age=&max=250 + response: + body: + string: !!binary | + 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 + 1ARPMx4AAA== + headers: + cf-ray: [4ab120f6af99c49c-DUS] + connection: [keep-alive] + content-encoding: [gzip] + content-type: [text/html; charset=iso-8859-1] + date: ['Mon, 18 Feb 2019 14:19:27 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + last-modified: ['Mon, 18 Feb 2019 14:19:27 GMT'] + p3p: [CP="NON DSP COR CURa ADMa DEVa TAIa OUR SAMa IND"] + server: [cloudflare] + set-cookie: ['__cfduid=d15e8b237b516029aefe1f98ef6ea54f31550499567; expires=Tue, + 18-Feb-20 14:19:27 GMT; path=/; domain=.binsearch.info; HttpOnly'] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-powered-by: [PHP/5.6.33] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + Cookie: [__cfduid=d15e8b237b516029aefe1f98ef6ea54f31550499567] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 3174120f-3388-11e9-b8bd-1c1b0d9d2a41)] + method: GET + uri: https://www.binsearch.info/index.php?server=2&q=Arrow+S07E07&xminsize=20&adv_age=&max=250 + response: + body: + string: !!binary | + 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 + //8DAK5ThvDYDwAA + headers: + cf-ray: [4ab120f77999c49c-DUS] + connection: [keep-alive] + content-encoding: [gzip] + content-type: [text/html; charset=iso-8859-1] + date: ['Mon, 18 Feb 2019 14:19:27 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + last-modified: ['Mon, 18 Feb 2019 14:19:27 GMT'] + p3p: [CP="NON DSP COR CURa ADMa DEVa TAIa OUR SAMa IND"] + server: [cloudflare] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-powered-by: [PHP/5.6.33] + x-robots-tag: [noindex] + status: {code: 200, message: OK} +version: 1 diff --git a/tests/providers/nzb/binsearch/binsearch_daily.yaml b/tests/providers/nzb/binsearch/binsearch_daily.yaml new file mode 100644 index 0000000000..0506a7bac9 --- /dev/null +++ b/tests/providers/nzb/binsearch/binsearch_daily.yaml @@ -0,0 +1,262 @@ +interactions: +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + Cookie: [__cfduid=d15e8b237b516029aefe1f98ef6ea54f31550499567] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 3174120f-3388-11e9-b8bd-1c1b0d9d2a41)] + method: GET + uri: https://www.binsearch.info/browse.php?server=2&max=50&bg=alt.binaries.teevee + response: + body: + string: !!binary | + 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 + FqzA6ZrFQj1ueGbu/wEAAP//AwC41E8NZbEAAA== + headers: + cf-ray: [4ab120fafd3cc4c4-DUS] + connection: [keep-alive] + content-encoding: [gzip] + content-type: [text/html; charset=iso-8859-1] + date: ['Mon, 18 Feb 2019 14:19:27 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + p3p: [CP="NON DSP COR CURa ADMa DEVa TAIa OUR SAMa IND"] + server: [cloudflare] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-powered-by: [PHP/5.6.33] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + Cookie: [__cfduid=d15e8b237b516029aefe1f98ef6ea54f31550499567] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 3174120f-3388-11e9-b8bd-1c1b0d9d2a41)] + method: GET + uri: https://www.binsearch.info/browse.php?server=2&max=50&bg=alt.binaries.teevee + response: + body: + string: !!binary | + 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 + KJfs0O1Y5VI9afhW4f8BAAD//wMA5a/j/mWxAAA= + headers: + cf-ray: [4ab120fd2a86c4c4-DUS] + connection: [keep-alive] + content-encoding: [gzip] + content-type: [text/html; charset=iso-8859-1] + date: ['Mon, 18 Feb 2019 14:19:28 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + p3p: [CP="NON DSP COR CURa ADMa DEVa TAIa OUR SAMa IND"] + server: [cloudflare] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-powered-by: [PHP/5.6.33] + status: {code: 200, message: OK} +version: 1 diff --git a/tests/providers/nzb/binsearch/binsearch_test.yaml b/tests/providers/nzb/binsearch/binsearch_test.yaml new file mode 100644 index 0000000000..e89ad60417 --- /dev/null +++ b/tests/providers/nzb/binsearch/binsearch_test.yaml @@ -0,0 +1,29 @@ +daily: + search_strings: + RSS: [''] + results: + - pubdate: 2017-11-08 00:00:00 + title: High.Maintenance.2016.S03E05.Pay.Day.1080p.AMZN.WEB-DL.DDP5.1.H.264-monkee.vol00+1 + link: https://www.binsearch.info/fcgi/nzb.fcgi?server=2&max=50&bg=alt.binaries.teevee|nzb_id=238480579 + size: 95923732 + - pubdate: 2017-11-08 00:00:00 + title: High.Maintenance.2016.S03E05.Pay.Day.1080p.AMZN.WEB-DL.DDP5.1.H.264-monkee + link: https://www.binsearch.info/fcgi/nzb.fcgi?server=2&max=50&bg=alt.binaries.teevee|nzb_id=238480578 + size: 1395864371 + - pubdate: 2017-11-08 00:00:00 + title: Last.Week.Tonight.with.John.Oliver.S06E01.720p.WEB-DL.AAC2.0.H.264-doosh.vol00+1 + link: https://www.binsearch.info/fcgi/nzb.fcgi?server=2&max=50&bg=alt.binaries.teevee|nzb_id=238478709 + size: 106189291 + +backlog: + search_strings: + Episode: ['Arrow S07E07'] + results: + - pubdate: 2017-11-08 00:00:00 + title: Arrow.S07E07.The.Slabside.Redemption.1080p.AMZN.WEB-DL.DDP5.1.H.264-Ca sStudio + link: https://www.binsearch.info/fcgi/nzb.fcgi?server=1&q=Arrow+S07E07&xminsize=20&adv_age=&max=250|nzb_id=608128280 + size: -1 + - pubdate: 2017-11-08 00:00:00 + title: Arrow.S07E07.The.Slabside.Redemption.720p.AMZN.WEB-DL.DDP5.1.H.264-Cas Studio + link: https://www.binsearch.info/fcgi/nzb.fcgi?server=1&q=Arrow+S07E07&xminsize=20&adv_age=&max=250|nzb_id=608128279 + size: -1 diff --git a/tests/providers/test_binsearch_title.py b/tests/providers/test_binsearch_title.py index 1c6d8778eb..f1083a7251 100644 --- a/tests/providers/test_binsearch_title.py +++ b/tests/providers/test_binsearch_title.py @@ -1,5 +1,6 @@ # coding=utf-8 """Title parse test code for Binsearch Provider.""" +from __future__ import unicode_literals from medusa.providers.nzb.binsearch import BinSearchProvider import pytest diff --git a/tests/providers/test_generic_provider.py b/tests/providers/test_generic_provider.py index c6e005b574..8b4a68c480 100644 --- a/tests/providers/test_generic_provider.py +++ b/tests/providers/test_generic_provider.py @@ -227,7 +227,7 @@ def test_create_search_string_air_by_date(p, create_tvshow, create_tvepisode): provider.search_separator = separator episode = create_tvepisode(mock_series, 1, 12) - episode.airdate = date(2018, 01, 10) + episode.airdate = date(2018, 1, 10) search_string = { 'Episode': [] @@ -267,7 +267,7 @@ def test_create_search_string_sports(p, create_tvshow, create_tvepisode): provider.search_separator = separator episode = create_tvepisode(mock_series, 1, 12) - episode.airdate = date(2018, 01, 10) + episode.airdate = date(2018, 1, 10) search_string = { 'Episode': [] @@ -310,7 +310,7 @@ def test_create_search_string_anime(p, create_tvshow, create_tvepisode, monkeypa expected = p['expected'] monkeypatch_function_return([( - b'medusa.scene_exceptions.get_season_scene_exceptions', + 'medusa.scene_exceptions.get_season_scene_exceptions', p['season_scene_name_exceptions'] )]) diff --git a/tests/providers/test_search.py b/tests/providers/test_search.py index dcd0b61ffc..692b30509d 100644 --- a/tests/providers/test_search.py +++ b/tests/providers/test_search.py @@ -6,7 +6,7 @@ import functools import os -from tests.providers.conftest import providers +from tests.providers.conftest import get_provider_data import vcr @@ -14,7 +14,7 @@ record_cassettes = False __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) -record_mode = 'all' if record_cassettes else 'none' +record_mode = 'once' if record_cassettes else 'none' def search(search_type, provider): @@ -31,6 +31,10 @@ def search(search_type, provider): with vcr.use_cassette(cassette_path, record_mode=record_mode): actual = provider.klass.search(test_case['search_strings']) + # Check if we got any results + if record_cassettes: + assert actual != [] + for i, result in enumerate(actual): # Only compare up to the info hash if we have magnets if expected[i]['link'].startswith('magnet:'): @@ -48,7 +52,7 @@ def search(search_type, provider): def generate_test_cases(): - for provider in providers(): + for provider in get_provider_data(): for search_type in ('daily', 'backlog'): test_name = 'test_{0}_{1}_search'.format(provider.name, search_type) generated_test = functools.partial(search, search_type, provider) diff --git a/tests/providers/torrent/anidex/anidex_backlog.yaml b/tests/providers/torrent/anidex/anidex_backlog.yaml index 4357aaf652..08d68d917b 100644 --- a/tests/providers/torrent/anidex/anidex_backlog.yaml +++ b/tests/providers/torrent/anidex/anidex_backlog.yaml @@ -5,175 +5,174 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - Cookie: [__cfduid=d2f7548dd7aff55b9c8f90e7cc7f65f9c1511722576; PHPSESSID=s820rugu1lql7kkjnkj5p88vt0] - User-Agent: [!!python/unicode Medusa/0.1.17 (Windows; 10; 7a741c30-d2db-11e7-97d7-1c1b0d9d2a41)] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET - uri: https://anidex.info/?q=Dragon+Ball+Super+115&id=1%2C2%2C3 + uri: https://anidex.info/?id=1%2C2%2C3&q=Dragon+Ball+Super+115 response: body: string: !!binary | - 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 - LgEA + H4sIAAAAAAAAA+xda3eiyNb+nF6r/0MNM6c101EBwVuis7zHxBij5mbeXlkllEo3AgOFSc7lv7+r + ClBMiLlIJ6bHPmeSUNRl165d9Tzs2gWfP+39Vjku9y7bVTDGE7Xw+dMe+Q1UqI3yDNKYwudPJA1B + ufD509beBGEIpDE0LYTzjI2HsQwzvzHG2Iihv21lmmcuYqfFWFmfGBArAxUxQNI1jDScZxrVPJJH + yFdOgxOUZ6YKujF0E/uy3igyHudlNFUkFKMXO0DRFKxANWZJUEV5zqnmt1gM9MYIwIE+RSAJaLUY + jizw58S28J9A0icIDBXTwkDRAB4jQPq0C6B2B3Q8Ria99loGpJBT5k84xMj8kxSxkFNlLHZfdGjj + sW76BC9qSgXdPuiijCzJVAys6No8cxFg3TRJq9iE0g9kAstAkgJVxVK0ERHXk2po6hNQhRYGRUuB + RBWSasskE9SUCdoBE6iN4A6RXpF2AJRtFYOpIiPdAlCTwUQ3Ufy+TD/Q3Y1uypZPelceawcMFOxe + 7ID5H46YO/da/Q6nO0DWbzRVhzK9KaNbcnekIez9th7oZKTrIxXFLAWj2BSZylCR4KKCmFHzUBJL + epK7sA9G9o/esSGaBqypt4cpdd/S4TS93xab2XNZOWJAgpqs24Rh6gYy8V2e0Uc50sQ1afThQNFS + QWWwgtV7+ScIRMsQo5Fu3m2DGHiqCmUCR/4qyCyxcomEo6C4og31BM1jJSaKJSWKNB009ZEeN7TR + 4xXbpvpEtX8pcp77F1/m/8WXk1/+zldMONK1ryWoql+7toHMrxwnPt5AoLkyb2yvS8bmzvDr9QYN + yAjPLUBVtB/ARGqeUSTSg7GJhnkmMYRTch1XJJ25nzMiQU3XFAmqESd7JEitEZAobO1R0yg8ahB7 + CSeD0wJZoEq6ji1sQgNIuolAudv1lhLavivewMuVkCxrfhXn4pJl/TXNJ3nG6ZSF71RkjRHCdE49 + bMVCKpLwC9uJOaXiE0UjDT63LWmMpB8D/falrXnlnm6rbFtYnwDnLhjqJsBjxQIYTQwVYhTUqGO9 + Fm0Sj9EEuSoUA1vyGqrpGoY3yNI1BEbqnTEm1mIF1T/0ck4QbQOqanA/qEnuJVwY/fxpb6DLdyTJ + kbDw+RMA0aGtSWSqRZUda0ffGe2YO3Bnsv0f5SpSp2tkUYPqHVYk63jwHUk48i1v7ipX5rc8+fHf + /87Kb/+H1kdS43/nnV///e/Vt+24YVvjKDRH9oQs79v/26E31Tz3p4ZuQAViFN3ehXkrLpkIYlRV + EckY1bd3SI2TvBUfIeymWqW7Hhy14ARF9e0r9tsujEPrTpPy3C6MW6aUH+1O4gYkC0VLl1Fc0Sxk + 4hIa6iaKko6RKv+3Hb1RNFm/2ZF1iUq1E3F0EtmZTb2bm5u4ixLQU0Fc0ieJ+dV3K7ITGcHI9i5R + LwAjGI04fYjsgMhpMZbNiFw6wyVjHEmANtZpXienhTSZJBtwhAgLcavZS8yGx7UM5RbJQIPTATQ9 + e9DgFEgqtKw8495wfsVkNIRkPXMvh6RsDOsGNeqtPVmZlSMrGFQ0ZDq3Fu65pYnlzO5v7Q1sjHUN + kAUwzzgXzL0SWB+NVAQkXVWhYSGZATLE0E0mbTrpXjI0R4TR/e6UZgA0FRhDtwbUZCTnmSFUSV6a + SsQ1dXXWlCfV1p5lQM0TwzJjuqbeMYWeI4gGp8qIAvteguQLLERmWoxW+ZMy7SUcbXmX8J7WBibU + ZAYocp4Z6xN07enWnfBMwVvboTtUCVmZ+kaNFPRUuFizp/DZiMwG01Z9WT1z0eCU8Wq7JmuOS5xU + haaq+kih5BwAAEg3XAGddECRJ89c6jbQEJIB1oGqE2iOMwW/miJDaIEhjNkG4Wzkr+FNxBnlsSLL + SMtHsGmjiFth5JTmi3g6BQsq1+A0psIBUmPZLM8UnLxuTkdhRNi9hKo4y/rnT6Q3bmGnsyNTtw23 + p7M+eYmBglvItJ6Wu06reJ7cTt4FuV2ZA0Ue6xZWtNE9mWepQUJbGJpPy7zvVPGk0JwgsEzBzf0M + sWVTNwhLX5T4d+b+fXepuLduzEoDU1d9i4/TD2gZumEbeYb05JFFxFn+AtRCqFVMUkxJRU9rp6EN + 9WeqhmQNzChBkyD/bIFwzJPObN+knOljgjTbld4x4a25+jyoGuqmPbHiLlmc6IgB3tJ6PVCh9uMR + M9aUKTItBd893fMabWLed+faW5G86fWIjLlE4laWpBcLOIbWGMPR09JdVMrluWzkKkiyxSkEB7qN + vcXs3oLm3nvMXp4WqEgqmEtEL+erkX9FeiiYNIbaCKn66BHhfPeDBFQVCz8tYJlWQtbnuZTztMdF + DRRJMaVcIqGYUtxU/q1rcQ1h98llxXFtdHzD2uiUn6tC01aR9Yj63HuvV12HVDAXi14GC7aXsFVv + RXT/Jtg7zzgr8Bgae3+aymiMnb4R8KHuhMKaLa+PIWUMKxP0DLicqXSRU00Vi7jyYuoopmiqoiGm + ULeRhZ+xuD5nWXXp0H0LcqnOfY4TjKzKSIspWgyq+AW9JK4WoGhERmogINCSSd224RdklhIgiYE0 + SVFfKkhXGWnANmaSEEFcw7xnxORXSGZsTPzzc6GWYLMGj/x7LzLxgP17g4C0KVJ14xl04ghZFvHA + PZNSHEFFBc/iFK5wC4vSksF6MCvAkn8PTHTi9sJvpL60kDXkpfis9UXSkqfua1e8hWm1mB7e5EKa + /AxZ3XkVfMsjVVsLs48mDHVz4jwRXDv2fU1S7j8G0lwLc3D++Oq469z8JKP3qO168gzF8baO9ZsY + VqQf7mxyNkkYjmeNW2ZBAsZ1sc+u5wapU68umELVRnmGY4BT18yZuq/IaMGyI9T+gTMLZEJPzEih + w2W+uuplCrSIk+LU/lhrLON2CMmF7li/AVBVnyrDP5DwWFPvXighLRIk4V7CEWg2uET7vsV1cYD/ + thXpx7WFoCmN3UF21i8n6ekhB5A66qhDwZPA5/NRNMPGMfrYyxRc89qaLXT+iz2a1fUDYXSLmUDz + WRCYFmGAoUIJjXVVRmaeOSEZgCe+YzR/Mw8765Z1x8TZTQBkNwHQ3QRAdxPmQ7jgkJl3KjbAmn/l + dr1ZbsYB1sAAa57/jHF7Z9mDiYIDZHJBI5gP0CzgWevDPdcQNQq/d2nu6fHsY3FxeLhk+DxExH2Y + iBMYmfmBHP/hvN69hAanrhs60DnoGtkEKjPtueL4skMVmRjQnzHLliRkWe6VrFgTxaIMDhBTiUlI + w/NqaaYFok5HEJu6NiqcGjJxsUc5LtZFBt7O7SXcOx5lscANMhEYmPoPpLneeQQMsvczRDdAhndW + HDRwxAKafgOoMzQO/DqdOUXpg5czyd1ufv5EEJKkYziwmHvEJkYTXeeYD0b+It7cvGvTS6wjZqi2 + 88wxWvocKU+hJiHZnSURP7Od+7QobXQUapjIQhr29jL9yMe6KzfxkjOsH/v+8vbo7s2qL0yhSBbJ + 4LYi/rYiXi/JIjNFEdJihI/MW4xwO/xO0k3wekd2sSIzQSKPykE2FGlxZ+NrJtETsjhSJP1SCDvi + ogxNZYpAka6Mz5SEVFHwFXuZNIJfmtR9WUZjDFr6FKnPlCVFJJkVepkkol+S9E5mUZYjskn6TClI + 4QIt8DIJUn4Jsjscu8Nx96Qge7TPlMKroEALvUyS9IKl8otC1OGEMtBnmSkfKdD8L2s/s9D+/Wli + GKobnvBsMchU8RV7mTTZBWmERWnaioRt8/kKESIFr8jLpODYBTHuzdsi3bY/I9v2z5VEjBR8pV4o + DLcgzL2Je0xieZ4rRipSoPlnAhCHzT13qOPFIpu6ntfKshJ/SRA766CHLHSzN88YUCbxDTmQMm4B + xxu3u3NGBgnImBbFGv4WGLaqeo8A99z29NHC+d/WPTqAIfHAmMgydM1Spp47nSYv5AFOTgubikF2 + gOjVWJ8i0/1b0jUZaWRn0PUTYy/Ki16YM+KDx7OK/bTBe+zgssYjzsUhZZcx3SCM4Ek3qBtAEfwE + 7lU5UvXBMx5Wm1Ab2XCEfCiNx/4OucInWSr74s3gvigqWsoja4qKCHFeIAYzl0gk8SSifrHyQ7eO + L3qehN5EglmLbuKlknRJhopT3s9RFjXwcEgBlukOmKecDPvYwEr6hEYALBWj7GZ6dEDpHhge25OB + FbONpXU1lR8+z8PTXZn1ISk81gcvUG1puz0n0Ol+y4G+gdcK4sTFLRXjiGZ5lhS/xWLPG93HBfL2 + BJ69zUPlcR9nnm1d6SDroiYxluUnZxqwlH8jn2W9aJqRsusxxYRHlSCpuvRjqQzF0asV4Gz3X9Pd + AAwnxhc9D5fpIqbZE2Qq0lPTlKql+AKteE+o9ML1jTypGmia+g1x/rmbxU9KhZCMTOvV1uIUf2uD + cRxYK2qGLHLLF1aEpPEKylHd8m+tHbr3O9fNbF4FwxWJMXwKqwwVYSS/Vg+SV8FPVsRewiNmJHHG + 1/awG1C44CgMoHJyEEYRtuzyV0lXdTMHfmdZdkZ4aRAxU6As1MkW8WXbdYbBGkNZv8kBjvBe9z9z + NIBRdge4/48nt3cBCZmMkQU4BzjOuHUTbhAZxRwY6Kq8CwZQ+kEchZoc8xrKDrO7jv3nAOElu2Ds + FuEy5EpWLEOFdzngbEzGBmT53AVTZGISzBuDqjLScmCiyLKKXJHdNEcJu2BG3VmQJFUOdJOwVxPK + im3lAMcat8D7j1zsui4QEANde+C6+choKZORp6cXinWvSa+lWdu7EUAferxw8aEKR1ZiNCBh4hEA + VZyPVLWRqljjmUXNrhPEjOTHLEFFQwz8SzKzZCZR+r2QeylO0bMRiuWbXPckeYTL+KLz3IBz52Es + m8oImZl1urcSTupjVd2LTTSg5uzkeZFyV3QoO/Vv4OFUj5HJDq7SPGt8A1dHtoqVWNcefANXt3xK + +AauDAvZsv4tPvkxZQph1bQQlfToXtWDXmk6XqeexePxJzuyfHP08S0eggHzUBA0gT9QpNDx1u/A + hh6fAAswUljYbNlaVs63hLoGKaueLS597HjS4fzw2QN6Eyf4+eMJwZznjNxftzhvm1pugJVx7uzg + pFFJ1/ulk3op1U9d1k5q1XI7VRJOWsfFi9PWF2zm3bCxecRYLpVNZRNQ03Rbk9DSh5onO/ngyQYW + ntb2bJh4Lg2OSs8v4M0JnuXSMY6LcRnAJ3NiOpdkwWmvzBS4u2WVBbFVt8Ym2eiw6S6JnAO8zBQA + u6yqAHb3aE1LK3qMCHk9zcQzoF5iClwydX/Vda99xGJOGnwTYMMiNiziF2UR6UAWkX5jFrFfPSs7 + kCuGQyYerfB9OUXI/fznUov0R6AWR+WOWOoedMoHp/16Jd3otcrn/Vq9xvOn/WS3dbLm1IJLs2FQ + i1SOFUKlFsnQqEVyRWqRTMbTlFrwbHJDLTbUYkMt/NQiFUgtUj+TWnBsJmTMfVGNb0gu3qCn/1x2 + kfoI7OKy1Ske840kL/S7pZYo1tvlfr/JN8tdMdU5K5+uObtIJsUw2IWYY9nQ2UXgMYFbSYUTGo0T + w6YCtZEXRHoDTU3RlqqqhZBsARLQ499fCY3DcCtwmEzadY/wqcyGw2w4zOMcRsE+DtPAUFWgNj8c + 6V2/nMOsSDQEnwnNiQZJfS3RqJRq1w5MXhOYvKYwec1x4nXttNncr8QnhsAUnpMrLELwhhI9gejv + C810VNcfmputarp7JCTPyue1y3T3spQ8LLW6jWLpol9Nn5eO1hyaxWR2NWhOA57NsdkcL4YKzZnQ + Hvwzqz74Z+MiBc20uMHMDWZ+OMxMZrMBmElSw8fMp9HprbAyNEnWGiPpKK4/Rla7vbOj83N+P1m6 + PGudl/hG56J7WE32OwdCqXbYW/d990wqHIzkUr8oRnJZ98EyzW0wcoORHxAjM4EYmfkJGNmtxOFU + WYZMTo6fj5GhSbLmGPkhYtPK7Wa9v39QrtRPSslSrybW+XbystjqVy7Ok739dXfx8nxIGMmmQ8VI + ITSMFFaNTYuzFCKz74+Q/HsjpLTOCNmBN++IkN8NH0IeQANqyJpP0nnCL7R/LCb5gEdUmvrq/ePu + ca18EOvAG+vxbdBob/8QcHyGvU3zLCAx4KBYLG87D46r1hDa/vC79CSE/eAwUd+vJv/Wsmfcs+cQ + oJKjs0zhKxdsms8gDI7drT9h6Jwe9C/7ldNU/fwg3awnTztn7fRl7bK3L3Sryf3mmhOGlLBiMLsA + 2HSOF3NsJlTCwPFjpgC4MBgDrWoVyiBk3KfqNL8hDRvSsCENi6QhE0gaMj+ZNJQvVkTaRyt4W8oQ + cj/WjDG8BvY/hJ/goNY4Pj2+qDaEyr54JlTK6Ua3mD483m9f9Dvlg+q67zdn+ZBgnw8X9jPhwX5m + RdhPZ2aH2ISNO33jTn8c9w3Vh/ttfSHS3Lv8lTCfY/kAzCepr8b8umkbEBwpJlSeOI5FAPIbuCom + U1WBq6W9aOvVKggN89+jHx8e86nlrD/mp1r9dPGkfNytXzYbZ+et/T5/1G+1Lg/OKs12ryese/g3 + z62G+UnApXJCJieGG2OWDW1vILvq3gDnbg6k0hvA3wD+5mzZHPLZpBgA+ST11ZDf2V8CcFVtBLoG + BG3d/AauztGgo5CTUs6JKaawQuHQoP6t5f+gmwH8bDOAf/1mADW09WcIfPqi3z1PVvhi5+CwXK9V + zk4vD+qHQrtzmCoenV6su1dASK7MELgcy+WS4UYPcKnQKAKtaiWvAB/n1ufdNpvdgM1uwFrRBC7I + M0BSX00Tmkg3oCk/4QbvFM+f2H4PpZ7QyMM79uqfHFRALXH9eYTYbHRLlXaLT7WL553LWvqYb/Q7 + yUaDF08a4sG6RyGmxZV5BJvJsemcGHJQQZrwCCEUHpFekUcI8QzoEVdDSti8I2/jbFjCI4amj0fU + TKRJc1+Dd/nWofpCNhUA9DT11aH6AaHvLA1/J85wSUXX3TE0FW0Etesz8tlqXbtum/r8iNlK5UML + 83+HXnxQQE/OAD35akB3LG79Af18v1frVht8stKsFS8Ojkvl87J4eX7QvLwoVc5ajXV/L108C+or + Anoyx2ZyYjZcQGfDcwywqx5Q917qskHzDZpvtg58VIFNBlEFNvl6n0AJ/kByTbHGjz3yCuALffCN + gRLE0th9kevVUVv4dkW2zZnC6nWE5gt4p978Q18251jeB/ABHPXStbNaq95r1YTW8cV+ul/ar9SE + 03SqUk+dlNacMmTS/Mo+ADbHczku3FfZiuOwGIO4Ynxhkk1RwpAU1+As4oYybBwAL0L1TCCqZ1ZB + 9YZl6XasBjWLvFv1ybemnh13e7WOFzf3+sKh4fhby/8PDghwDO0DvI++fnLZbxZPiulWtZ+8uDwv + 93rdRrvVaLUandNmce0DAlYMGeQBl85xQk5kQ37uD++YAKlqlbe5ckknZpDf+PE3MP4BYZwPhHH+ + p8O4+2mVV6Hgw7JvDeJhSf/RY/cdU1l/IO4KR8eteuWwdlo+FPu10mm/e3p00Ut1LysHopA8/tVj + 9z0gDjsyL2QgXuV5OpOMC+5r1TdIvEHij4bEqaCvt9DUVyOxPLCup7qFh2YQGhEscvALXGWEzK3g + hqa/olRo6Ls+Ev+iEXCOQa0/Xh92Ds6azepZM1Ut9vbFVLrf4lPicWm/3uvuVzqH6x4BRz5TtiJg + sxkK2Pwv+pFYFpQeVrAB6g1Qrz9QC4FALbweqCulLqi2wFnt21L42q+ANM+2mcILC4QGz+8t51uA + 8hwvFwb3d0mfTJCG78VaLAC2jIbQVrEPsOeFwD0wMmmEhnsbLEOi+derOB8YvQ93ED4Cd6gn+yel + 42K3074oCenTY/GodV47PhbFfueycVipr/s7fFd3urNpck6fT4a7cx4adRBXPYMnxHln65zbfAxm + QyCWEIjJrY9AdA2oKdYYRJvFXvFoezZdH6T/StF3KVYMYivsCgf32/Yd7NoD67cn96mviulUmctk + Bc9D/tqioTGYt5X9w3v3qZ18AG9Btdo4Lrf7F93yfjV5lj4XhXrrsH551D+rFS8b6/7Zd1FgV0b8 + ZI5Nhe0sWJ/PvnMZ0Y2V23zZZgP4G8BfCvhsIOCzPxfwnZD0SlVIZaq8+BLMDCj5pnAfnuT/4Hi8 + 1Mf4TGz9opi6SFZqx8mDo7Nm4+AgJewXk0ciny4XhdLR/q8fBsDyuWTob+un5+pDiQJY9Vg9zztv + 50mzm3f2bojC5hyejxiI2SBPAEl9NTGgQ9mpPx3r5io01iWBcVfn1VKs0vwGrsjbbL6BK8NCtqx7 + yBt+paHRiXXp74f3K1CrW3+6kG7si+X+SYU/LleSxWqvvH9y0G23++1q77LcLK57+H6KF0KgC3w6 + J/yEIARuHYIQeNY5tJ8UNsf2N3RhQxcW6IIQSBeEn0kXvONt4eLni2t9Q8LwRj3+BRjDh4g9aLWa + R2KryQvn9WK9fpa+OGgIpXapenKarlWL1aO1f9FPcrUX/XiMgUuFyxjCO2fAr3rOQMw4B/6EDWfY + cIYNZ1jgDOmgMwwk9dWcoWpCJWYufbutt+t+ZKtYMVREhp0W9/By5TpC4wPv1JuPj/7pD3FqIXXe + OhXO9g+71VbnIN3vi23xpFk7Ozxotc56R411/xhwOOjPCTlB+EUPLWRT7vZCMrnB/g32b7Dfj/2B + 2wtp8ediv/sqvFXAclkVb4r84fflFwD+D7FRUBIuz3vtUqWZPGod7J9WS23+5FIoNkrl+mH7sN5Z + +42CZAgbBeS0YrjAz/Ghva2PVrXSoQP3PT8cz25OLW6wfxODuIwLpAL9AKnUmxw6SGXZoshx2VcE + 7i8UfY9DByHI/kHDEMVZGKL4+jBEamLrTxf6rctWt1o+FIqp7lG51u5WepWL1EmzWutdVPvNdX+3 + bzh+AlYIOwyRnlfg1+G8QjrjvNs3teEKG66w4QrLuUKg3yAlvsV5BT7FV9OcWH151P9CyXc4rxCG + 5P9oovAh/AqnvYveaee8eMifdS5O+Vq7dpQWznr7p4ft0/3L1Pk/wq9AiIIYrl8hOw5WC7qVVDiB + WNG1GDYVqI1U5FR3A01N0ZbqqoWQbAETWci3PIbkvciu+JZiXnDfmJBNbwjJhpBsNi78BIQLJCDc + G2xcvNSz/z5bEj9FyvXediCjv/70oFMUW03x+CJ1tH/R6J1dVnu1s+MLQeiI1cNa7yT1D6AHXI4X + c3zml/2sIM8JmzcfbIB7A9xBwM0GAjf7FtGGLw7Ge6c4wp8j55qD94d4F0H7UDg9PW6k+3WR7xyV + q8nqUfW4WWyVDhvHzbNO7R+wCcDleD7sowJceF8kWDFigIvzoFdiCllhswmwge4NdM+gO8VnAg4X + Oqmvhu5DOFFq3WB4Y/nU7CwcqNATdt4JOY4dKJj85sQaV02lyfcEwqoqNLh/37590H2CEF557Jrk + B/hYcP/8vMtXmgepbql7dHLQ63b6J5et83LjpNYSSsK6fy6BXeFrCWw6lmQBz+ZEMZfMOlyCDymg + gHCJZCgBBeNVX1Tgftso+4o3Hrs39xJ4oMt3tOxeAsOBisjfDvCRP4xAw+uO9RtFGwEOYB3wGaAP + yU931bb2EgYtq8FpYGnamK169GQCzZGi5QC7CyTbtAg1MHSF4jfjlTfgSNHoHsx87jsdUBUvj6xY + RH7ZARTWP28p2/kXX+b/xZeTX/7OOyvdV7LSfaUr3VeOE7/ow6GFcP6RJwW68ROTdXugIgdaKWQu + mwEH9sQgGhoqpoWBAUfo3mxQldkoPewPlLAyJXMQkm2eWXYfHQzq/M/stWOGz+62Cpf0mtibrTrG + pkFqbK5Fuqa3NbNDsPdbLAYSkq5hqGgElmKO2mj6BFkWHKHre7e3KLUllvAgA+NTGmFyMU3XiJ5n + Rv+wuS1HvL2hrpM1xy3vXLkGbQQuTuTviY3JwJR1487R4BdJN+52Ac9yHIiRX1mwB71pPSNBDKGi + FXQLeiaUfiCTKA/EwGx8yeJt5RKJsa7qo+FtXNInDMDQHCGcZ64HKtR+zNaKtql/RxIGbo1t3cRQ + ZQqLyc7oOHM34fTNGRZPJyVdxxY2oQEk3UTgAE5hVzIVA3/+tJV/8T9vnEjNbRVKSAYQAzxGAGky + WVLIn7Iu2eR7CMDS6TUxJwu4KGvh+WhbVBBKpZmEc2Elvv9tI/MuPlG0+Hf6mQ/nxsMCA69nie/W + /OLVBWMWUpGEl5bHdwZyjCXxHU6hk0ptaQpN8AfIg+8nRPpdx/T+iHqq2I7rWjQijQnMRHZAJD7A + WmyoqAjkyM/IDhjamkTWyug2+A+xTVKhohk2BnnwRxSPFWt7h042zZ7UFBVZIO/cj48QjrLb8SFN + /CsgMa4ibYTHIAc4pwqHbnnlp1CNbsdNZJDxjCb+7/8Sox0QSUR8afE//y+R2AGRyDbp2ZZTDpvK + aITMaIQ2QpUX2QFXnnw7Dp/7Rov8j/z8/GnL6yWQoKFgqCr/RjWy0DYRxsiMWthUtJGrARNh29SA + kxaXxtAs0j5h/dQwkFmGFopug69eBktVJBTlnOYc/c9b0ycT6J2m6VJRo4rs07SqWETR3nAR9VVV + RP4s3TVkknfXy+r0FMkgDzR0A4qmCe+i9DYgWYa6CaIKyBNoVMAerTmuG0QMbyB2gfL1q9v4ljIE + UX+eK6CAb3GvES/X1qzZuGFb44ASU6jayJGSdp/+AH49ehV81xUtGtmJ+DXlt1QTQfkuOrfHmZLo + xAR5oOoShfW4haApjXfdhX/rjyjzOyl87XFRUt/1wMZY15jtuKQq0o95vWhKWnO690ccfoe3Ubev + tqnmAENSElByFEcu4sbY+Msrnn/QEOPY9haZozkQqVd7ETcFWnealANDqFrITXKpY2427UBUhhjO + 1L016yNZt0EeMAnG0e3W/9wqJCiN0WKtBH6QhntUAv8Nw9RJcxWIoXvDGSd3vKgq4oZJf1ecr884 + JkWybPn1O77G+mikIqJPuppE7y8cW1Oo0jVjITOd5LuvVfYYEVx1a/sy0WWUZ75OoRqqyonED3F/ + Oz7GE9XJGrfG+k10Oy4jFd5FOZElKxyU0bHtqWvpyG0lElBFJnYqC384txYGdSaHiQj0zcfTP5yq + PtJt/JLJ4eiaaR93e57FO0OYeGIM3aYeG42fPBgLSnBXqOfb/0y9TglKdmbovJdwH4f2EkS6wudP + /w8AAP//AwCjryzLmhwBAA== headers: cache-control: ['no-store, no-cache, must-revalidate'] - cf-ray: [3c3f111958aa2c3c-AMS] + cf-ray: [4a9a54407afd96ac-FRA] connection: [keep-alive] content-encoding: [gzip] content-type: [text/html; charset=UTF-8] - date: ['Sun, 26 Nov 2017 18:56:17 GMT'] + date: ['Fri, 15 Feb 2019 19:55:02 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] pragma: [no-cache] - server: [cloudflare-nginx] - vary: [Accept-Encoding] + server: [cloudflare] + set-cookie: ['__cfduid=d1f5bf4290473706b12869339dd42e2301550260495; expires=Sat, + 15-Feb-20 19:54:55 GMT; path=/; domain=.anidex.info; HttpOnly', PHPSESSID=cb358a35j7ltmnajsb9gqnsdgv; + path=/; domain=.anidex.info] + transfer-encoding: [chunked] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/anidex/anidex_daily.yaml b/tests/providers/torrent/anidex/anidex_daily.yaml index 185eb38e2d..e70bad3838 100644 --- a/tests/providers/torrent/anidex/anidex_daily.yaml +++ b/tests/providers/torrent/anidex/anidex_daily.yaml @@ -5,220 +5,223 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - User-Agent: [!!python/unicode Medusa/0.1.17 (Windows; 10; 7a741c30-d2db-11e7-97d7-1c1b0d9d2a41)] + Cookie: [__cfduid=d1f5bf4290473706b12869339dd42e2301550260495; PHPSESSID=cb358a35j7ltmnajsb9gqnsdgv] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET uri: https://anidex.info/?id=1%2C2%2C3 response: body: string: !!binary | - H4sIAAAAAAAAA+ydyW7rSLqg104g3yFSVTclV1oSZ0o6lhOaZ0vWbJ9rHITEsMRjimRy8FADcKsX - jV50P0HvetVAA73oV8rVfYtGcJAlm7Zli7SlLJ6qtE0yhj/mj3/88fPHH45/KrYL/fNOCcyNhXTy - 4w/H+DeQoDzLRpAcOfnxB3wPQeHkxx8OjhfIgGA6h5qOjGzENK7iqcjDg7lhqHH0myneZCPj+CAX - LygLFRriREIRMFVkA8lGNlIrZZEwQyvxZLhA2ciNiG5VRTNWgt6KgjHPCuhGnKK4dXEERFk0RCjF - 9SmUUJa0k/kpHgf9OQJwotwgQAMrWQPOdPCXhakbfwFTZYHAlajpBhBlYMwRwGX6AqB8DxRjjjTr - 2s0Z4Eh2nL/AKwNpf8FRdGQnGY8/Fh2axlzRVgTPyWIR3T0pooD0qSaqhqjIq4GBoWgaztbQ4PQa - aUBX0VSEkqiL8gzL64p1pSkLUIK6AXK6CHFdTCVTwIGgLC7QEVhAeQaPsPji9AhAwZQMcCMKSNEB - lAWwUDSUeCLVNbq/VTRBXxHJEUg/AhPRcC6OwMMftpxHj7L9Dm+OgKDcypICBeuhgO7w05mMDPe3 - /iT/maLMJBTXRQPFb5AmXolT+KiKZs3GlM0rNDk26zPzut9WWU2FZemuwUlVXYE3fLXDNtMjQWxF - QBJngPOQRPkaaEjKRsQpTm6uoatsJHkFb/B1Qpwqdv8+ODZEQ0IndquB46R9aT/CXSuvKIZuaFAF - U0VDoNDruZ3AysJJd+KGSk51/eEqQSamuv7rTZamIrY0unEvIX2OkPHQe8uKbMBbpCsyAjPpXp1j - EfXXs7lSZCNuRVygxEKUcV4vZPNQEh1JaGq8sSxxO9abMprO0fR6oty9NSs33vMZuXkVTN1QFsB+ - Cq4UDRhzUQcGWqgSNJBXpvY41K0sjTlaIKeNWM+c3Iyq/VaTBfpcXFjDqYt0VZGFxHc701opBXRT - xXMYUK6cwEhCCzyS7PGHBBGC30ykiWjZtj/F41/FKyAZoFYC6Ut87+DYlg/o2jQbwdOqnkkmFV1P - LODdVJATU2WRxBM1q8/FmySd4BPUw7XVOt/1yMmxU8yNk9TsAiXJBJOg3CvP5I5/+opkQby6tAvx - 4w/HSWeR+PGH44ki3OOlZBkcgNiVKU/xoI6JR/qRcjQ70o7g0eLwb+LXaMUa/zkZSveGONXbk+9o - akQvs9oX8at2mcU//v73ZfzDv1np4buJ37L2r7///evlYUI19XkMajPTqvDDfxxZD6Us+RcZ3YIi - NFDs8AvM6omphqCBSnbLxJTDI5ziIqsnZshw7ur5+z6cncIFiimHX4nLLzAB9Xt5miW/wASuwtmX - RUKFeDo8VQSUEGUdaUYeXSkaiuGC4ST/cRi7FWVBuT0SlKkl1VHUrpPoUdRtgtvb24QzA0K3CqzG - eLj6rkePojMYPfyCqxeAGYxF7TJEj0B0kIunUyzJp0g6TuIb0DQUK6wdUkeygG+rcIbwGusks96a - eAYS75AAZHgzgZrbN2V4A6YS1PVsxHlg/4oL6ArixcW5vMJx44aiRuy+JojLeHgOh6KMNPvR2jMn - Nu45y+cHxxPTMBQZGPcqykbsi8ijGIYym0kITBVJgqqOhAgQoAGd2zhP+757G2ozzCt/smNHANRE - GEd3KpQFJGQjV1DCYa27WFxNkZZZuVIdHOsqlF0xdC2uyNJ95KRvCyLDG3FmLVrHSRzOMxKe0eNW - kgEFOk7ateVewke1NtGgLESAKGQjc2WBvrl168yJEWcBPE5Cp6mSgniz0mo4oluF6ym7Fb5skWVj - mtJKULe7yPAm4qb2DU/LDhRIonVXUmaihZ4AAICL4Qho3wfW6pyNnCsmkBESgKEAScGclIicrFZT - 9AqCKxg3VYwj+K+r26jdyHNREJCcjRqaiaJOetGBFS7qVilYq3EZ3sQlOEFSPJ2mIid2WCekXV9Y - 1uOkJNrT4Y8/4MI4ke2yzjTFVJ2CLovk3vSSW0ea/rrYFSuFzcS2w66J7YjsKfFc0Q1Rnj0SeXnX - Q2bdgNrrIlftFF6VmWQYInLihN5AakFTVIyf6wL/KfL4uTNPPJo0lrGBpkgrM49dDqirimqq2Qgu - yTMziLPOPqkVUb5S4lNRm0ro9cqpyVfKhjWDg3oGnEINg8tycrD7pjWqVwbksjoWSDYd4e3+e/BQ - e+4ydaVo5kJP2EyfWCgoAtxp9dtEgvK1dx+WxRuk6aJx/3rBy1YOD0W3r93JyB1az4iYSSbvhOn0 - rfLNoT434Ox14cbFQuFBNHzlJdj68IETxTTcaezRVOY8e6azvC5PDsd/EMi6fJiHVueip3JN51Ce - IUmZPSPbynMP+SRRN16Xr2ClgeflByEf7j0vqadEojbNJJOiNk1o4l8VOSEjI2k39HaNWuuutGmt - W9i0AjVTQvozlec8e3fFdXH8B6msy03lwiPgGbHsR/6OAMpbruOkKblTtPM3JoGHgMsIz7GB+6cm - zuaGXTS8GGJtQeRkx+b7ZxbuuCEu0Aar97JGD15ct02kGxvM9JvM8Q6XPe47DnM9hi3PRV6cyXFR - fkPhQNPiMyye1S2AZ/fF6ZrqqgzLO0+FUJE8FaW3yNATZzIw1aUQWAanJz7qtfiXT/1WXawOyLVU - vPsxeObfZ+HMk5cPp/6RfIMkRd0AaFpI1+EM6RtCTQuKEtiIahzZ1iahF9rqyVAAL/x70jkXTilW - u+fKPX8ryL2z0lffJCx+5f/mSLc2ntbv+zKqkCxsIKYzoLwfuUR3sDbsrBtXiraw30W+2R37G77z - +PXTCrU2+B5em201pxMeB3Rf8R0NqCraKve5chs3xOm1M4zsrYcISRHqXWRNgoijtl5eP3RFxVLt - gxsomSgbISPATmupxq6KAlrr01Gr5wO7/wsYj7ToSZdM/eJUb+TEimLfsVN/Ljci4hQICSe9uXIL - oCS9Fod6ImFblu7fKKEVxUvC46Qt0LJxce2vzKrrDfybKU6vv+kIatO508j2xGXfer3JAbQUhJYi - w5VgRdckyqppxK337ciJ070OljPc6sWxFdTRPxnozoh4dp81ga0oEaBKcIrmiiQgLRs5wwGAK77d - aX6LPC2sE9dpkwh4aK01nc+D/PGJIa/Ozo7CzAk4MWQwMWRXRRdxCqKbk4VoeGTvLAyeK70VAmw0 - EzxSPlnNv6q/etAluT1hfRp4Ojms6KCwgjKZwEvFUtNkaygf0j1OyvDG0dV7qh+d7rSA4rLyHHFW - gkMJaQawftpvYvafgqgvRF3HO5kA94j4FMnGQ5pWoDXytlrP0BR5dnKqGOIUgVh7aigTpAGSPMwc - J52HoKxIknKLt/DwpqSOtBukgYVyg44AWkBR0sFEU65RAvTxloaoA1m5BZa69QjoCt6/NOY4tobw - VoelDHPiyYoBJgg/0/HeoT5XTEmwok8QuFW0a1GeJVabZam5tV4S7RnBqakff8ALKb5vwIkeeYQ/ - ceumo8FbWW5+xSrnrDMAnu9fcVUyLVSWZi++8go3UJ4iwRlR0VXofVC8WVhpt4qqIVxydy9xdYEk - nFne2gwhVpfIXyMnOTxxeqcZXU0z6hYGTzw3KIpTjpLRh5Sj5BF1RDs33FLgHdPoMsPor6KQtYOd - WI+WOb+Sp50btZobc8Su59UUbxDIWbPioxxx0JOVx2/LlV7NlXuc52xugFPlBkmP8uRwjsuHb8uR - Wc2RP0qt59nC28+PcsOBTqwHb8uJXc0pfUQSRyT5KDe8uf4oNzfgifXwbTlyaz2GWs+sAhcWGK51 - Fyp6Yt1/Wz78Wj6Pu6WqSs62+5PscNdcefy2XFNruTLruXbEqWFqTwvIRE/cR2/LLb2W26PhkLPM - IYbYHOJxhmz0ZOXp2/IkibVMH42HNjYueZwdFz2x7i8zwtqLR+pKW9OEt75dzZKuJ3+dQsOeLtz5 - 1NqozkZUKGA7kAzg1DtAUurdlwdosaZaTbemWOoOqKYkuZT8SKlu0bf9v4NH66gBJxKK21vCunjj - Krut22thgB1SNzRRxeuRdTVX8LJm/z1VZAHJeNPO0eMarnmRdaEticGYLxNeXXJdMifTqrf+78ri - r7iiog10FAVooJmi3Xu/nTopziRlssGLXBPKMxPO0MrSZMxXi+OIThOW5OsPPUsiSuhF+iqLEsJg - ubYYLnUF0eSvv2V/dheYn/XslRP8ZyWLTZGinmsyNl94Kc8eDlC0o6+uwOtFfdpywBAsbZZbCyni - mfabKgvbZOLFdnMCvdhuxtxcTPS4EjfVFxNritcrr9+vF2VZBpp5pgyuFdSL2fZte6rHGXu+JL9T - Dtvm6kUpWlaQjYT4KR7frG2flcdVN2+sabbEcVh/467FP9e15oIQV14dUUAX/4pWOtZzwwkH24mh - xDw7lCRlev1KiXOzTcpq76J/s9TaBlyoPytZ+EKx47K5QJo4jePKeb0Ocm+oAt2cTpGu2+9hzqv/ - a/UANU25dbZgX58OeggJSNM36QF2yA/uBLYaZpsKwNPTyzMiQtP5ZnUgOUE/uBKst/OHKlgOCc9h - gE0JX1tOVAkZSNigwFM3bLAlPk66LIRvLhHp2HDM69bUVx70JHgtGBhEHWScKpKiZcCfCIJYMqZF - p5ETC/zsYNGVYF/s+tbnUFBuM4DEqOn8p80mMEYcAef/CfrwC7BMU/EcmQEkqd45N24Rbq4MmCiS - 8AVM4PQa67RkIe5mlL5Kf7H7cwZgRvgC5k4UMoWvBFFXJXifAaIsiTKKT/Ac9wXcIM0Qp1CKQ0mc - yRmwEAVBQo7Izj27Er6AJS0TgMZJThQNE6MGBdHUM4Ak1Dvg/ocvvjgv5yAOeubEUUnh1hIXM7ee - 3ijWoyzdnJZ5f4lalprRpLjAOwHJKwnO9KRqJFQZa0kkIxvtKJphzkxslx6z/4bS4bJ/PfM0ibuY - 8FwvkdCVAVZn2cjzw8nC4bXAL64ylom8qK+MsEeCPAMdK2Zsjv25/WqUTpP8Q8d1HiXtu88l9ciI - T4WyvenkmpR9zcNr1DMn+iVoKLKCGxtqUJ+LIuihaygCWQS9uXltXpnXJrhVfgJxQHDga754+ZWn - CPXyayrNsOVcMXWZWFzfRE58TnDNoOfZrZYnZZQVYwfLmUgkXi3Py5t73jGe791rC8XJi0FXpkun - hwmS27lewv1XtZhPmR+6A8Gb+1+Rywb8zK93RtbU5MzEEOeZfJUaDmoNtnRxmjtlxp0eQ/VHXImr - dFtnjSHT/NnQso7R1IO9VIZLc+kklGXFlKfopZeJV8v45I3i5SJabxXCC5h74rH5bXVs++GLRi0v - S4pfNUAcn/Sx9OSKIv/0VOzVt48XxWRJErTyr3erJas4w5EiSD5OknGKA2QqwxAZmgKDfiFyQnKL - l1LzImEnySY+JGSqAt4TyABuETkB5EtJeSDlsykRLyX0HJY5qREg/zQBt3escM8D06xs0YWQ8y8B - ObPJCuSU5Jkk6vPliF1e/5FAhkt7gQyXfj/IlDQoxjV4q18Cq1Fn0ICaqON1PAW+kkQKL+JVqAk9 - c+Ku4W+O4xuO7Ia0OwcbuAPsPGw024PqsHbKFoZcuXnW6ZfHlc6w1eHy5VrjjD/jQ9gIBjZ4kvUB - Nmgiw9A2bFA+wQaV1jFtcH7ghpXWy0m9Ahwkl0iBSj5yQjEhdYTUEVLHCnWkPKkjFRR12JqDNy3j - T6N8EHN8jKy7RxypPSAOiu0US2P+/IKt1gaNC67RYjsVql7vVXpdqtrJhcQRDHHQNOETcRD+Eoet - 3kj7pd94Qgpv4Q0uQVq48UScEDdC3PjXxg3eEzf49+NGEUGhLOrzS3CKjPh30wTW1oNuWu37sCbn - coXLxEJlIidvjuIbbuyCrK/gxrPHPvCU93BAFS3gNYqedN198k+gFH4PKGXU7XC9an9ULwyp02au - PuYuKHo8rhe5YX/UOqdDSgmIUtK8D5RCpjIUY1MKnfKRUli/IIXfglHoBGsxSogoIaJ8AqJsDRKc - J0hw7wcJfY7ddImXRajPQQOqKhIBQf4C2iqS8Zz0S0kWLJc3m4b0DRs+XrLd00lwe7Dal7pnPNsZ - NuvF3CjHjTvFLl/od5r16nl+yPX7tXC1D8jkIkVtvdrzGTadoZxdEJb3cbWn/Frt2W12QByNBBWu - 9uFqv4erPeu52rPvX+17inSB5EtQhTNTQzNzoYAYmU5Rh0uzAZ5hijRHl1zF/xtj+Lb6f76ku0cD - 7B7QAF/qUaXyWafCcK1Cv8EPB/1xvtPudc4vikOu3AlpICAaSDCgsj0NsBmGdAww5/7BAOPb/sQ2 - Bpg0n+AsHOBDHAhxINyfWAENxhM0GF/MIfq3Cihgv9qr1oktUzJEVUK4qa04HoYGb4gYhGnETsi9 - exDC7AGElC9opnnRLY1a1X6l3KIbZ7lypdeudBqdRoVh+iGEBAMhKYrwQyVBZwh2hyFkm/0HxjHJ - 5EIECREkRJAVBKE9EYQOAEFs04G3r+QvxQseQD5F6t3DD3ofDqEOT3OVUWVQHoyHXKtSOW8x9bMq - n6u0WqPTXCvEjx220uQzLJVh0r7iB4vxw5dDITglZivzB8o20QzPoYb8EfLHKn9QnvxB+cIfbRmB - joimuGFTJHtDvUmf8NbYQbDIx5RgL/1icNQeIEkt12m2muMqTzcb52x+VCgUR2yhzTbz1f6QaoYm - mQEhiW2B4AOS0AFoRHi/NCLkNtsy6dAkM0SSEEk8kIT0RBIyKCTZXMPwxsgfBCT+y7+fPELug9Ho - eZeiKI6t9agWnx9cNDt0bjA+a476w7NOaciFPBIMjzAc6Y+KhEz7zyOkb1s0zFY8QthGo6GOJASS - EEhWgcTT6ShH+AIkVcXU0bWID3o2TFkEsf7w8O22F+9NJQhE+dgS7Ser7INP0VOudjpstob98Xmt - ke+ctViuVDqtFbmzyjnTq52HrBIMq3BMyh9WIbgd1p3QPqhOSDZElRBVQlR5QBXW060omw4aVTbX - QbwzkQ8GFf/Ls5ecwu6DO9IqW+GL+TE/orqlaomp0YXCRf68x5cG/VY5XzwLOSUgsxOS8YNTyAxL - BaBT8c33ObeV2autUyHpEFRCUAlBZQVUPF2DsbwvoJKXkCyA3tuVDm+IGASQ7ITcuwch++D7q9Er - N8vVer4wrPH0sMee9QqliwbTyHGDKt2lQkOToHyic4Q/EEITu7yxs422hKSc879keAA4pJCQQlYp - xNOvGMsFQCGbaxQ2jxc8g3yK1LtHIPvgj4xiLzrng04u16hURo1ytVpvsKcV6pTOU/1KnamEBLLT - p2/IDMn4TyCcb6au5BYEQiXo0AFJyB8hfzzhD09PZyzrC3/Q8Rk0dMuFeFNUZEDh9RlBXZHxIs2/ - ScGwXVpBcMpnlG4/93D2wX0aWxqNz+jxqNRol+jSkL8oj0e5/jhHs/1WhRqFdrEBwUuapv2BFyIA - 9Ul6J3ypko7rknAPJ6SXkF7W6MXTfRrLfAy9bK6a2CqpT2EX/8u2n+iyD07Xqv0xd95n2SZf5orF - Ub3WLlD1Qv2cY5rNTq4cfg03qCM9hC/mJ0SG4f1HF3YXrE9cryepEFxCcAnBZQVcPJ2usf44Xast - FNNQgA4RqGloAkFNTLzdouO9qQSBKx9bov0klX3wz8aetQf9QbdSKNSLjdLFsFzLN5uDs+Z5udjP - sY1CSCoB2agwaX9IhQjARz25G95QSMYxUgmPH4e0EtLKGq14umhjqaBpZXMlxDsT+WBW8b88+4kq - ++C3rVKsNBq9QZ3K9zsc08mV2zW+x5d7+Wq7cDaqhvtBAaEKlfbDTwqTzjD+numhLVTxxZqF3taa - JeWcPqZDUglJJSSVVVLx9NzG+uO5rQXnimno5jW0DtueK1YTv1EJ8c5EgiCVDy3PfpLKXnh0Ywud - MUu3K70uc5bPN5r1NnfKM63zEV9uFql6SCoBeUnhfSIVKgilim+fAX45pdeVKoytVAm/BByiSogq - q6ji6dONJQJGlc11EO9L42NBxf/S7Cen7IM3t/NurnhRGjNFij3v8BzH0HyzPSyNCjmerpRy4QHl - oI4HEYQ/nBKENzeS3glO4RxDFYoMMSXElBBTHjCF8XSTwvjjJqWBrvF63EOyjmTwM8ije0UW1vQH - T1fyDSMFASKfKu/OUQezD25RBh1qMKRKQ6o45mtUozDim3ydrXKDYrnWPqXCfZygvkhMs35QRyoQ - 6vDtUHJqO68oVOhENoSOEDqeQoenVxSGCx46LGXAG9fwZZwPR45gpd094NgHLyj1WoluNMv0BZ2n - qnxrPC6VR6VOt9/t1ofVRusiBI6A1BwpPw4SM3yG4XbZGSy/lTNYx2t9uBkTAkcIHKvA4ekGhWF9 - 8lqv/NW0HbR3kWggfFp2/ZTsC9qDN0YOxkv9B8i/l/suzD54NhmfNod0l+ZzuTJ/Ouy1h+w5Q3Ns - qdwfcmW+UQqBJBggYUmfgIRK+Q8k9C588I92eCT0yhbiSIgjqzji6deEYT4OR57RLLwt7qfByJbS - 7yeL7IOrkjO6Vq7lmlSpNGZaZ2f5/nDQHJQb9XyzwucL+VzIIgGdqmFYf1iEZP+oyhHKsVQld+BQ - DfXZNDLdZRrpwttPpJHv6gqN1KEKZaQ/DNuHG38oHvF0V8Js4a6kPb/X411rVa6IsgEXEMTsyYaw - Pl6XBrH+GJBUirjjKQLcURwDcrnCYWKhMpGTraL7RiUfX4b9BJN98EzSz7HF0lmJG4/obqfLnNfp - Tr5M1YajcaNcv2BD3/VB7dpwfngmoYNx/0oS/n3DbxvrVJ5yvuJHESGchHASwskanBApLzghUu+H - E7stm1AWLkHD/C5q0Pq4rqJBcAtBD35XTCCLYGBA01YaxEalfFdUAdY7gPPBkGGYDkmAUjxXoA9B - NzcCXwmOzZfYMuOqJQLPwzfM2dHa2EsWwr1y51ko1xtQLaZWPB+Uag0q12wO6fqQaZfrhXJ10GmE - JrNBeWlL+eFPlmCWG0aUjyyU8u2czlYGLLaLNi6koJCCQgpao6C0JwWl/aEg6/Tsd1EGFVMz7R+W - rgIrKihikxU/lSJTaSLNe634PqceCPnsRA3sJ/Ok94B5uNEpPy7XynW2zp/3cq0xe1ZgKqNxZ8Dn - uPJ5aCQTlA99Or27zOObkcxWfmmdTxfuwMd/QuYJmWenmMfzbDKxxdnkQa+DF+veJSiaSAItqBtI - 0wGebUAc0Cz4ShS5XD6dLrqr+Btj+MYmny/p7oHGPpxHPhv0y8Val2Zz5X7/opGrVxmW4/tMp9S7 - OOvnWiFoBAQaaT+8oBB0hiX8Bw3ftpnoLUAjzWMUi5zswOGgEDRC0Ngp0PA8j0xwvti/WM0qKaBn - LhZIA03xBrmLMkHFivCeOgSxfK/z1JLkjvKwJdk6uSDsYz6pjPupL9mHU86DUemsUKEKXa40bLMU - 1W+en40G5xdUm+XOhoMQY4Kyl0nwoOIHxjAB6EtIgvALZChim4NFLG3rTEgm/GRyeLQoPFq0ijKe - J50Jn046i9Z3a34CgwXUzPh0DmXQfe2A8EZxAjlK9HnS7h507MNJZv6iSw1qjeZglO+1S/yg2mMu - hq0eO8oVSud0PtykCQo6eNof3QnN+Q8dDLsTnw+kUomUfZg5HepPQv1JqD9Zgw7P80OEP+eH2gsR - iiAnGgjbirb1uYhmyhHo6+a9gg/7wiPQUmQBit/tb+ilQay12bEcP1MOQqvy+SXfTwXLPhxIql7U - C1yHKrS7gxLXHLfLoxJfpeqj6ogbnFHDbsg6QbmRS/A+wU4AG0Vs2jcFy1b6lQRp61foHbDEDfUr - oX5lh1DH03ULwQSuX3nO58kmUT5auxKorLvHG/vgmWVEdUeVSqFBc40hX6ixg9F5vTAuVJhuvdYd - Ds9D3giGN0ie3WHc8O0rgtQ2x35I3uWNXTj/HPJGyBs7xBuUJ29Q7+eNPLxGQlnU55egZq3HQIcI - 1DQ0gaBmKxKWX83L5QqXjvbgPdF8445dkvkV/ljrSxKcIAlYP61JcNlVumgBr1H0pOtk9xnYQu0B - tvQG570G1+dbnUGpUxry4w7NjFu9Rr3ODvJnvUKILUH5beH8wBYqQ/D+Ywvlmz0tuw210M73fegd - 8G8b7gj9K+4IbQ0XpCdckO+GixcNN4FruXlabcQtY9A0RdxhqwrQ6pQqlGsOauiRE58S8gtAPrVc - +7kJQ+4BXVxQhUq1xFY7xXzhNNfiq9VCP3dBnZfGfGl02uiEdBGQUoSzHH1shxdchmUyLLfLp3W2 - 2YMhQP7pweJQHRKqQ/6V1SFE2ssNCr77bnVIRTLRJThFRvy7aWKvZD1TN622xbqBQoEtEkSecHcz - 3hDaN+XH50m4a1RhNfTuf5Cncp7v51tn1LjHVwen5d4FQ7ebxTHbLDaK+YtySBUBOcFPU1vrLLgM - xWVIByro3TRj3cbVLMU7bvDToWVHiBYvoMXibgUteiqURX0OYs1cP9c6XI7fJ/f/UKjBe6LGFt5H - OuY97JkT/SeP7QhJXNuNKBCpdKGQWzpQfW9U3yDkY2XfR5WH1TV2Hk4KFYpny+MKR1ON03p9SDd7 - 54PWeb1dqIxpnqqFcBLQhgq1vR0Im6HTGTrtK5xQ9hd6fHGFRm1rCMKnnS0Vig0d4Yd7KuEpm3Ug - 4TyBxB8vJZt5Zd/weMmWiQVxluZTyrefGLMP/kl6+fHwnGYK/WI+1z+7OO+VLhoMXW606RLbLbXb - IcYEgzEcw/iAMSSVYRyMYfy0C0kzvilZyG1crbGc/eHjVDoVallCLUuoZXkBalhPqGF90bJYjRyf - QQNqor6maKBKxXSOL5Y8dBQbRgpCs/Kp8u4eiOyDz5IWVcufUu3hkCt2x7V+qVo5b47ZfGWcGzMd - fjwMQSQgfQpN+AMiFOs/iPh3jJfcxkKVIZ3vCpJUaKIaqlNCdco6eTCe5MH4ok554ahrLNePb6Zm - eGciQahPPrQ8+6k22YdTwPwZ1R7X69S4SVfHPFOqDutco9Pk+SJ92q7V+yGtBGSakiJ9oBWCzhAp - /2mFSZP+uVjbildct64svwO8EupNQr3JDtML7UkvtC96k7aMQEdEU9zQKZJ1XZ9+TROpUrGc9rLs - 2ChKEDqTT5M1WAJ57hTxsrs5fYsEkniN9OjJL6R319oMXvbCZVqryIwvCt1WvstUa7lBk++2Onm+ - fTpk6qed0/C0TkDwwjLbe0xjMgyZYf3d82EwvPC+sAtjbfls83Ed99PFZIguIbqE6PIiulCe6EIF - gy72Vkg+TTPpFMNvQgMeMT4EXD5G0t3AFnqJLfQ22LIPLkzada5f4gfl8nmvTVf6vUKPb3ANpt8o - j/h2leFDbAnK4pbzB1uYAHQunH87RNtgC0s5Brckx4Q7ROEOUbhDtAYqpCeokL7sED3vkGxTK9T3 - pBDE3tDHlWQ/N4b2wRNKOVduj8t8f5BrtC46fbbebXG1U5rvd07PmvSQCiEloI0hhvQBUuh0IBtD - LOPbxlDal32h1C64WguVK6FDlN1hlFTKi1FSqfczShFBx2fquWlei/inbJ1xOTdNfQ6BgEBOMzPu - JfYwMlesMy+khwtWH1PzjV0+vYQ+cMy+uJm1uuIeHCfqFLrVaq5+0WucFSmqQPEDtjgcXpQL1WKj - Xg/xJyD88eHLg0yGZDKU47KF9RN/fPMDt9WneOx9pSfnqkP9TKif+RfXz6Q8PbSkeF/0M/axmsrq - sZpN1RlvihqERuYDZN9LVUxqHzy0lAanrXblnKr2O6MqP+yytW6jNM6P+t3uWeOiNwhZJKj9IsIn - FiH9ZxEfjzant/oMcjptu49jw5PNoSbmBR4xtBUe6Zva9aomZnn9R6IR3lMTw2+hiRkiA2lQxtYf - l9/yUJI0RVl8Q9/OFfNa0ZVv8W8U+c1WSHz7ClOTqUBNl35g3x/ZNyL5aPk/n0k2NX+hluYv1Bbm - L/w+qFbqOf6iPm6UiqdMvUH3qtU+27loDtrli1qTYhpciDNBHZBObY0zdIamMxTtK87QFs74ATM4 - pW184ZKOaoUNNSuhZiXUrKyyDOnpZp9M+6JZGUENmqAHJaQvoAxO0S2I5Yse2ol1zcTG0YLQqHy6 - zDunSyH3wRU/dXZ+1u/m2w12SFVz9dPeaMQxlVx+1C60+U7nIoSPYOCDsT7oux18kBmGy7DOV495 - P7/vQ/hn1sJt4+2W5J0jQztgexvqUnZXl6KZKwTSNXVdhPLDFr97/UfiD8JzZ4fYYmenXGzLTVFG - l6CvgKZyg+JdE/Q1xZxIuIFbpmSIqiROoSEqMr4BEbiGGgQDfS5qiv13rDgsApKgmDuW51Z3USyN - RdBZ+MY1u1kXe7mjROyFz//8uNnv1buVdo1iSoOL7qBTyRVKgxFXz9cqnbOQggL6zCG7vXULmaHS - y48o+0lBtF8MtNV2UsJBoB3YTQp1MOEnlN9BKp5O+YktnPLPkarI6FrBbuYXCrYXPbddyzfgX9HK - 5e//8d//83/+v9//+X9//y//7fd//tff//l//vN//e/Vy9//43+AGJlOE4fga6NW7IF0mrK0DnNn - sXYtWD84R984Zm9qan82pvxxJ0PswycEGu1ic1AdltlWb9BtNMvl0xzfqQ6HrX79tMSwoS+8oKjI - +gLh1lTEZ9gAqIjl/MIiahvVEEU7x7L50Ow3BKNwc2oduTw/GUCwvmxOdTRRtuaLvmmY1mZNmntx - i2eDCEFsSH2KnLunftmHTwQMmV69lR9Xe/Sona9Tw+o4P2S4VnVcZnqdwShUvwQEGinLt8m2oEGk - M6TziYCUr5tQvpEGyae3soIhQR+jBh16gAlRI0SNddTw/EYA4c83ArbafNnoME8QOQQBM7tTE/u5 - CbUPnx5o1Iv9HpXj6fooXx6Xxr2L6gUzHHP1WivXGwxDN3hBHbGm/NiEIh48zPhKQSnKt0PWW0EQ - b+9Dpch3QJDz8DhpTBTh3op7nDTgREL4b3vFxn+onoOmN1ducTuTwFAASwDlCrCpI55ngbPi6MdJ - 1YovwxvPFKwMTcllqwXUZqKcAcQXMDU1HXONqogWfCw7qgpnomzNehG3rHZhjiXRDSOIOi6DYC+G - xOq0YxkM/RtVoP6NKtA/K1dXOjKyhGevh/JMQnHBmnLtxd9a1V/q/3VzoeLKuBI13QAqnKFH3V8S - lw3yVGw4NcQbPFXAE3Il+NOQUasSZtFluaLe5WKJKDYzd1J6e3ySIKLYBYCTwLq0dhqv1i2b4tkN - 6tfu2xtXsARfqF/ciU3J7sEytHqwMwbcfhxd6YXRk2MdLtSTDpwhMEMy0vDIBKIMSJoFCx2vqvg5 - 7ssHD2PiYDlArBkXJKeKbEBRRhqwJjj8GN9fIF2HM/Tt0eMD62UBd88nASIr3RizcVxWZNwrlqPx - aXYHdhGPrxQFz4dOfPvKGWWq58SJ/16YBhIiJwVFvbdb4eepot5/ARRBkiCOf/HgoZEjmOmL6A70 - NTi9RhqudxB/CIAXQj2TTM4VSZld3SWmyiICDKjNkJGNfJtIUL5ezl0dTfmOpgZwUuwomgGlyMn6 - bbth7XkkaRfJblG3KvKKYuiGBlUwVTQE6vAG9qaaqBo//nCQffM/t3lwyh0JTpEAoAGMOQJIFvAU - h/8UlKm5QLIBdMW6xj1RBw6x6MZDI+uWINY7SSRpX+jJ77+ZSLtPLEQ58d3ayLUfPI0wcUuW/K4/ - XLw7YlxHEpoab40vKFPdOw6uo1qJJMCNiG5VRTPAHOKXH0UDPVO7glOUFJB+bSgqGImyoNzqIAUm - 5syzdtbyFBFJxN1U4xNzFr9VtGtovfI+K7txryK7fye/wxto37W6/w3UwJ9BFnw/wzX/xR4tf465 - zXiYUORYFH/Ua4aiRyCamBhy/EqUEMjgn9EjcGXKU7zmxA7B3/BwwgmKsmoaIAv+HDPmon54ZM0x - srkoixLSQdZ+npghI0YcJq6sm7963ExISJ4Zc5ABpJ2Evcnpxr+BUuwwoSEV98VY8t//PTk7AtFk - dOVe4i//nkwegWj0EJfswI5naOJshrRY1MrEavjoEfjqyndk76JeWlH+gX/++MOBW0owhapoQEn8 - KyrjlayJDANpMd3QRHnm1ICGDFOTgX0vMZ1DLWeVyVAGqoq0AtRR7BD84gbQJXGKYqSdnV3/D7kp - iwV03mhQzxI1JgorNS2JOq5ot7lw9ZUkhP/M39cEHPaLG9QuKRJAFsjoFuQ0Dd7HrMcAB8FdMyaC - LEYMERxbKScUFYvhNsQXIP7yi5P5gXgFYqthvgIRXCbcTNxQB8tsE6qpzz1i3EDJRLaUVvGtH2C1 - Ht0EviuiHIseRVdrarWnaggK97GH/risJGtSAVkgKfZLYUJHUJvOvzhr1cGfY5E/4cjf3HcSnN63 - iWkYihw5TEwlcXr9kC66wbnZxftzAn6HdzGnrKYmZUAE30nCqV1x+CKhztVf3ejZJxlF7L59gMdo - BkQrpX7UuQP1e3maAVdQ0pFzyyHxzHLYgZgADbis7oNlGfGaA7IgkozYdXvwDyeJKZzO0XqqeMVE - stG3JFh9oGoKzq4IDeg8sNvJaS+rKhKqZv0uoitoSobdpXCQg9X6nX8zlNlMQrg+rdkk9njiOLiB - kjVnrAW2BvmX91b2HGEUcFL7eaEIKBv55QZKvlY5lvgpqhwm5sZCsoMm9LlyGztMCEiC9zGSJfAM - BwXUNt3qerHlDpJJKCHNsBPzvzkP1hp1KYeG8LL90J6rzSkpM8U03jI47LqOdNq9vtvj7SZMvtKG - TlbPtUbAjbFWCc4MtXn/X1avHcMCteXqfJx0Xi2Pk1g6i4z/PwAAAP//AwA9dneOaesBAA== + H4sIAAAAAAAAA+x9aW/rSpreZ1/g/odqdfeVfa8lcackW7qgdlmrtdnymYODMlWWeEyRai5e7nQD + Od1IgAABJpkgAwTIzCAzSDLIZBkkXwJkJvkvcXrycf5CUFy0mbZli7ZlH57ua5tk1VtvLaznqbfe + evntN/s/yzWynX4zD0bGWE5/+80+/g1kqAxTIaSE0t9+g+8hOEh/+83W/hgZEIgjqOnISIVM4ywS + D80ejAxjEkG/MqWLVOg40hUiWXU8gYZ0KqMQEFXFQIqRCpXzKTQYorl8ChyjVOhCQpcTVTPmkl5K + A2OUGqALSUQR62IXSIpkSFCO6CKUUYq0xfwsEgGdEQLwVL1AgAaWWAMOdfD92NSN74GojhE4kzTd + AJICjBECuE57ACrXQDVGSLOu3ZIBzmTn+R6eGUj7HmfRkS0yEllWHZrGSNXmFBcUKYeublVxgHRR + kyaGpCqzxAIwVE3DpRoaFM+RBvQJEiUoS7qkDLG6rlZnmjoGeagbQNAliJtClM0BTgQVaYx2wRgq + Q7iLtZfEXQAHpmyAC2mAVB1AZQDGqoaiyzqdo+tLVRvoc9o7+ui74FQynItdMPvDVnN3qdTP8GIX + DNRLRVbhwHo4QFf46VBBhvtbv9UmQ1UdyiiiSwaKXCBNOpNEuNhAoWG1IrIZlSaPzYOhed5pTFht + AgvyVYWTS7oKL/hSk60mjgZSLQRi1pB1ipho6gRpxnUqpA6TuIhPuNDbHWXl8spjSIa8lH6MwHYW + Gmioatc7IAIeEiGN4XBeBH5L9GQsZjdQVFLO1JiVRo+NJV2MCdZ9UFWHanSiDO8WbGryA2J/lAYp + 8pdUlvollaXvFuQ5LEMvPC7v6YPryXz7XaJT3JOznpYl5RxoSE6FJBHXYKShs1QodgYv8HVUEtXQ + csqwCBVVkUQoh+3kYa/mC4NYemvfGgLpOzt+P2YnsEvAE1FGVQ3d0OAEiKqGQLbddqcMq3xHvVM3 + VUzU9dlVlIyKuv7jRYqmQnaldONaRvoIIcN6d26XoiMZicYjy4nYuaJjScEFrlqWOELi+al69djS + 3HwPl5U1dUMdA/spOFM1YIwkHRhoPJGhgbwKtUevbhVpjNAYOU3IepbkFlRQFQNeIl1VEBjK15MR + Hi26l/wzN+UYWWVAWfauhzUk92MOXH77zf6pOrjGt2wN099+A8D2mamI+FXblnb1XXV3uKvtwt3x + zh9KH8JFay4UFChfG5KoN04/I9EIf0xpe9IH7WMK//j1r6f5d/7QkofvRn+Vsn/9+tcfPu5EJ6Y+ + 2oba0BzjaXznN7vWQzlFfq+gS5CDBtre2YMpPSpqCBooLyOccFvd2cUSxyk9OkSGc1fPXHfgsA7H + aFvd+UB83INRqF8rYorcg1FdE1PDvXF0AvFEUVcHKCopOtKMDDpTNbSNK4ZF/mZn+1JSBurl7kAV + La12w3abhHenr97l5WXUQQPoNkFUVMex2dVnPbwbHsLwzh5uXgCGcDts1yG8C8JdIZKIsyQfJ+kI + iW9A01CttHZKHSkDfHsChwizDUfMfmzaPc7IkK7QACjw4hRq7nhQ4AUQZajrqZDzwP4VGaAziOcz + 5/IM540Y6sQa1Fv7A2maD89gUFKQZj9aeObkxiNn+nxr/9Q0DFUBeAJMheyL0FIOQx0OZQREVZbh + REeDEBhAAzq3cZn2ffc21IaYuf3czh0CUJNgBF1NoDJAg1ToDMo4rXUXq6up8rQoV6utfX0CFVcN + XYuoinwdSndsRRR4IQ0tAN+P4XSemfCbFrFEPlOi/ZjdWu4lXGq1Uw0qgxCQBqnQSB2jT27bOi98 + KO3O7dDpqthAupjrNZzRbcJFyW6DT3tk2pmmPJfUHS4KvAi50j7hOcchSLJk3ZXVoWSRcAAAwNVw + FLTvAwt5UqG+agIFoQEwVCCrGJqjofR8M4XPoA7OYMScYG6G/zq7DNu9PJIGA6SkwoZmorAjMNy1 + 0oXdNgULTa7Ai4gMT5EcSSSoUNpO66S0Gwwrux+TJXta//YbXBsns13ZoaaaE6em0zq5Nz0V15Gm + P6x30RKxmt522gW9HZ09VR6puiEpwyWdp3e9lNYNqD2sc8kW8aDSJMMQobSTegW1B5o6wWx8UeOf + h5afO1PF0rwxzQ00VZ6bfOx6QH2iTsxJKoRrcsckYk9/Hs2CqVVElDRRRg+3Tlk5U1dsGpzUM6EI + NYz80wnCHp7Wmz33Uk7bY4wU09HeHsJbs+ZzoepM1cyxHnXI4lhFIeBOrZ9OZaic3zGMFekCabpk + XD9c84JVxKzu9rU7I7mv1x06JmOxq4EoPlrBEdRHBhw+rN1xLpud6YavvDRbfIXgqWoa7mS2NKE5 + z+4aLw8rJGABM42sy9lsND8j3VZMHEFliGR1eIdyc8+9FJQl3XhYwawlBM/PMy1n9+5W1VMlSROT + sZikiVFN+klVogoynJXLmv1abs11a7mVXbUJNVNG+h3N5zx7etO1sICZWtalt2L7MVN2Z0Tnb4y9 + s4TTDHehsfunJg1Hhl03DD6W2SC9YdPrXUgZMaQxWgEup026yKkuJB2b7CLyMCIpsqSgULpoIt1Y + YXJdZVp16NDyCHKozjLH8UZWaahEJCUCZeMRtcQmFSApWEdrgADPkYxlm5N5RaZ3PDSZIEWU5Mcq + 0paGCjAnU02wIs7AXBrE+JdPw3gynn8/F6R4D2twx7/XIhO32L/bCUi5QLI6WYFO1JCuY0vbipSi + BiUZrMQpHOUWJqV7OuvWWwHu+XdriI6dWswP0rl7PreQe2dutD5KW7zq/uSot/BaLd737+VCymAF + XZ33yvuRS6q2Ft4+68aZqo3tFcEne3x/wneWl4FWqoV3cLZ8tc11Tnqc0F1qO5a8iWRbW0fqZcSQ + xHPnbbI3Q0IkRUyuQgsahBxT+vR6NiBVy6oLLqBsolSIDAFb1tSYWpIGaGFkh63xD+y3YIDpiRZO + t8j4D07zhtJWFvuOLf2u0oiQUyE0SLdH6iWAsvxQHuqWhg1Fvn6khlYWLw33Y7ZC087FrT83uS52 + 8K9MSTz/pCOoiSOnk+35y771cJcDaBnqLIOCq8GczUdSJqYRsZa9obQzvLamE938xb6V1LEDGejK + CHkOnwWFrSwhMJGhiEaqPEBaKnSIEwBXfXvQ/Cp0u7JOXqdPQmDWWwu2l5n+kVNDmZ+kHcOVk/DU + UMCpobimspBTEd08HUuGR/EOPnhDv5UErDQVLFmBrP6fNyTNjDruUFicB27PDnPGIGwpjEUxYkxN + PrapcCZ3P6bAC8fi7GkHdMbTGErT1nPUmUsOZaQZwPoZ0U1RRLruXA0kfSzpFlkDeFRERKQYM7FW + ogVObvWgoanKMN2dDLA1fZskI200MXaS+zHnictOdHCJNARONfUcKY4hHoEJ3uY5Q5dgAK/1KCgb + YR0o6iWw7J5RMN+mU/untcay32enmt9+g8EQ3zfgqR5a4jAR66ZjB5tDjB+x4TblDN97RkdkIpv2 + 8mJ475JxcAEVEQ2cFyI8T2Jn5iuLIdoNOtGQjhTD3Z6cBznCmaSxQTxEzMPcj6G0gOc9b5nheZlh + tzZ43rhAYSw5TIVnksPkLrVLOzfcWuCNqfC0wLC152cls/espiU/UKZdGj1fGrPLLpZVlS4QEKxJ + balEnDQ99/hxpTLzpXLLZQ5HBqirF0heKpPDJU4fPq5Edr5Efje+WGYN71culYYTpa0HjyuJmy8p + sUsSuyS5VBreFl0qzU2Yth4+rkR+YcRQi4UV4dgidwvDhQqnrfuPKye+UM7ysJxMZGcn/1ZxeGjO + PX5cqYmFUpnFUpuSaJja7Qoy4bT76HGlkcRCcUvvg2DtZPfwTvZyiWw4Pff0kYWSC4UuvRAN7K6y + XBwXTlv3pwVhm8SSxc821OB9S9cwo+uxH0Vo2POFO6Na+5mp0AQO8BZ+EnCTK0BSk6u9GemAeHLV + dGuOpa7AxJRll+UuWaYt9mz/b2sJBg2IjQwa0ieqoksXrsXYur2QBtgpdUOTJniTw7oaqRdIc/4W + VWWAFLz55ZhCDddhybrQpoBvjKaC5+HSZdZkYnKH/ezMIlARdYKR8EFLn+Mj4L3IdEUOZfV0hfVY + FSpDEw7RHDoZo/kKOcrThKX74kPvukgyupc/FSQZYW64AIjTVX849uOvUt+5IPOdnjpzkn+nprAj + SdgbmFXNuLfQNk6Qs/PPw/BiZW/3HjAG1n6O2w5x4q4+FNWxtZ99rxpZJ9GdfWft6Bgjc3yqR8zJ + vbKq0vncOvrhqkzrQDN31cF1r7q33I7ttrNcsudK96mK2N5c96pRs5KspMXPIpHVevduhVwL98qb + FpY+DmNfeXTxXqPLGhKjweDBlwro0k9obmTd9UbhZJvxNjF31leUVfH8Xh2E4Sp1tbekP1kWawOO + J9+pKXhftSOKOUaaJD708lktIDyiAdyllXXhrN8fbAWoaeolNlA5G5oPaoXQAGn6KmPATvnSw8C2 + p6zZCHiWun9mREgcrdYOspP0pRvC2nWcNcP0xfCGFuzd9hCuTGRkoMEKVRbdtM9c5/2YS43wzSlj + 2jccr7UFa5QHmRp4QQfmpQ6DFFVZ1ZLg5wRBTCmnRVZDaYsH2snCc8n27BbXR3CgXiYBiZmn8582 + PIXbxC5w/h+ld/YA9suL4MkyCUhycuXcuES4w5LgVJUHe+AUiufYRKUMIm5BibPEnj2qkwDThT0w + crKQcXw1kPSJDK+TwN79ipziqW4PXCDNwB6jEShLQyUJxtJgICNHZeee3Qh7YEqeCUBjkaeqhvmj + BgeSqScBSUyugPsfvthzFusgAtrmqWNgwr0ljYduOz1SraUi3ZKmZe+FgbW8cH2Pz2Q41GPDU+xz + HAZQNlLhvDKUJX00HVHT6xgeRoO7RoKMzgwwP6eG7nlpLAK8kPpeTLEc7SV97j1a0uQOijHnAuZ4 + NdvLIYpiEww5HZ7Os5hz+y5hSy5wE6jYG0auQ9aHDDxHg4Kkjz6CTKSpqdiPMwlOkCiOVPP7/Fi1 + bN4RQHDgA08Rk48fBCH7MTqeMKH0GpkXXFzu3Pi4pbuiGq+sfzQafVD3+zfX7t4iwDP5zJUAjeE5 + Cqdb7izsWdDdY3sBDNILxvqt+/LNzY7OUBvI01F2L9N/0Ix5m+5D96XwpvwPaGZT++SPV0bK1JTk + qSGNktliuVirHdaKxWKXP6w2uWKJq1RarRx3IuTZ/sF3hpZy/I5mLkdJLsElYlBRVFMR0b3riAcr + eWsxAdMPN/e0n5g4D2qZ1TO47wFFkIkIQUVIFpCJJMMnSR50O9lQOj6+T5gXlXQkVrH53LRs74Mk + oMahNCDvE+XBx+6URN0n6C4+40gjQCaUJpbnUud6ji7MqMDc2A+4wVfBDcZXc9ygPYGKpI/AdlXo + CLWdGetcvv/OuALhzRWIp3OFpnkN2+ap/rOPoAZHqgnaI9X8rIKOem7qI1NHChB08xwuICZZyNBZ + giU+RsfnF6G0D0J84w6vVR8fOMSrkwHiLZCBg26xeFg+YYrVItNuddmjLNcsngh5oXlUqgp8d8PJ + AM0zfpABLknQNhlIbCIZIAM2ELCBgA08LxugE55sgE68GBsgiTiGT1Yo8GSWzz0RPr2kvBYf8K9G + 74AQ4JG0+YSgxTb7tUKba2XbbOE42++2mvnKUb/TOmhXSq1WccMJQZyO+0EImCTN2YSAJH1kBJRf + jIANCEFACIKtA38JQNybAMR92To4UA9UoKigIo2v8RFvCDKqeY6UJGiYQ1WxHsGfcM+Tifvt8OtI + eo5NhZev2de7w4AH4+ZziHqryNaFbPGQ4Q+rLb502OhWivX8YbtXZ4udwuGGcwiO8YND0HSSJWwO + QVH+cAiSxiSC9oNEWKLWMSuQURoUM7dlBEQiIBJfO5HgvIkE93QikdegFNHgpf6odXfNlA1pIiM8 + BixJ7gLcT3G+UYrXr+N7MDJwb4Eg9Bp9ppaly5k+3Wg02RJLn3DHQvsgzwn1qtCrfxVGBpJJMqRN + EBifjAwka+07xH1hCFgWRa9BEagpR+ACkhCQhIAkLJAE1psksC9GEuyVuF/4eZ+016II/tfwPTAE + 9m0whFanQRVK3ZPDstDrMkKtWSkdUKX6YaPVOOQ6X4VfAkknqbjDEHwyIdC0b54JligysZYNgbT4 + Af369IB6bXogbjI9aMHLV6QHnydz9OAATqCC9NmLOrvxzggC400QmKcTBLs7q1AZ3G1rB5ElYzuZ + ANtH+UxLmgCMgKAkMQzTbAJByO6AlnAEPggFhs8UhIJr0X+JYnyjFJvbJhvGNebbcn7DxH2bppM6 + kPFZ6VD6B9L7XViRpjBvgabkTgqd0slJh6kWOUqgulSxyrVqJ5lCvkAxhdqmGzI4mlubpsSTTDxJ + U463xMgfOwZhsRTCFzsGlsWvwVIS0YTFUsjAihFYMQIrxiJJob1JCu2Lz0RJUtQx1MyfzLFqYv+B + +P3+Aw+nfw7/h1fQ8p06N9BvAfKFXuuALbbqDaFf7FW77Uy22jo46B72s90uRbU33TJBsYQPkE/F + kwzhK+QzlH+Qb8li1oB8xjFMkHxgmQgsE4FlYhH0Ke+TEtQaJyUao2s90lrVFL/dybQBScWJK54i + wBXFMdbK24Fa32T5RhZeuXbvYNOCehNnJziq1mzljhmqW2hWm3wuWy+cHDdO2vVaqVbpFaqbvmlB + sj5QA5KY+T36RA0sZsAzvlCDcSidWMepgSQJe8+CjQfmgMAccDc3ONXmuEFT1QxzaOLPDm9nNPiT + JM/OVXo+e2eMwXsvg1pjL6MiaZIC9ZH0EbTxN4+BoBmgYfUnEGQDf+UHx90GEVA0FVCEMnKffsjk + Pjreg6G0P3J8YwqvWKv3wBLexJ5BheYr7X4hy590atxBLXfYzWf5BlM4KnLHtV52009HsJY5fF2W + QHBJJu4rS/D3gCURHLAM2EEQceFZWQHpzQpIxpeICzkVRyGWRLy/XoGK+lld8AqMMxST55iMR0yC + x+R8jsgKL6D528d68k1g/fHJYeGEbTNHrW6hW20KwnEnVysxpWJBaGR6jcKmbxZw6/sH8EmWSVKk + r1jP8nooDRhf3BgtWeQ6eE8y0bhlE2A3YLsgAP0A9Dca9L09Bkj6eUHfOS0Yz+TZPMPQj8FOr6wv + Cvv+6f4ecP9NOAk0jw7o7mGuXmjX+/VctXpIcXWue1im+10+nzvOb/oaP077gft0kuL9X+MznG9x + FddxC2R4xy8wzgROAoGTQOAksIjzhLeTAJHw5/hCXzXPoQSOoCGOMK+zhjdo488ZMzTY7vQE1zOf + JOb98rk8zdBshvTyy/dF5rMcTHjF2r4DykC8CecB5pA6ZKguU6iWD7jjTqWcKR7VK1y30i31snm2 + ueGUgadZHygDw0w/y+ATZUj4FjIJSyLXCYcQpTbltGNgJAiOEWwUWeC9yQLvSzCEh1bHqwQIeJqM + 5wh88JK1eQ/gz7+JfYIWd9zs9EoH3HHuqJRpcX263u0edtuN+nGl0yhvvL2A8QP8qSSb8B/846xf + 6E+tc6aAZx38J+kgZmLAAAIGsMgAvGMmEtzzMoDVIwQ9ScSL4r//dXkP8P8m4iG2D6qskKNpqlo8 + ylfLmd5BodwuMlSu12kI+fbRV+EmgOHf34MDdhgBlvYtjMBaGwYU4xCARBDvKNgwCDYMlhmAt2MA + QftyqvAuyFv5sN0TBDzH+cEXq8d7wP434SpwxDSr5Wy3cCLkyu2D41yu2qz0+93+cb1fEfij1qZj + P8H7gP00n6Rpf7HfCoVMEbRvsZDj66z+SYK3XQSp4NhgsPjfoGOD6+O291eUiTW+opzrfAQVeI6G + pmZKgFIGoI2grioLq9RmJ5JpuRvbj8zhGzK/vqabjsFv4ivI3f5Jny6y1XxZKDSqJ/lMlW8UavX+ + ASOw7fwxs/EYTPmBwVSSpPzFYMtdzxcAXvNIHhnlbF+9YOUdrLxff+Wt4RlBH0syeuTKu6OZuuHn + sjue8DS849tPhu+jRquaA80iEOrlWv4juPnyP29++09v/tGXmy9/evPbf3nz5T/efPnr3//l39z8 + 9o///m//CD/68q9vvvzV7//ub//+b/7o5stf3/zun9/87j/dfPm3N1/+182Xf3Lz5d/8w9/+OfiH + v/uzm9/+1c3v/vPNb//b//0ff/L//tU/u/nyH25+9xc3v/uTmy//5fd/8y9+/+/++81v//j3//VP + f/9Hf3Lz5S9vvvz7my//++bLn//D3/0ZaFaFPqg1euV8KL2x+q2y5F6VmHwFffCcX4G0cWn62pWQ + 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 + s/ZjWLv0t9/8fwAAAP//AwCfDTLE7tABAA== headers: cache-control: ['no-store, no-cache, must-revalidate'] - cf-ray: [3c3f1114ac6d0755-AMS] + cf-ray: [4a9a551ed81996f4-FRA] connection: [keep-alive] content-encoding: [gzip] content-type: [text/html; charset=UTF-8] - date: ['Sun, 26 Nov 2017 18:56:16 GMT'] + date: ['Fri, 15 Feb 2019 19:55:32 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] pragma: [no-cache] - server: [cloudflare-nginx] - set-cookie: ['__cfduid=d2f7548dd7aff55b9c8f90e7cc7f65f9c1511722576; expires=Mon, - 26-Nov-18 18:56:16 GMT; path=/; domain=.anidex.info; HttpOnly', PHPSESSID=s820rugu1lql7kkjnkj5p88vt0; - path=/] - vary: [Accept-Encoding] + server: [cloudflare] + transfer-encoding: [chunked] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/anidex/anidex_test.yaml b/tests/providers/torrent/anidex/anidex_test.yaml index 369d80ef28..88b05d44a2 100644 --- a/tests/providers/torrent/anidex/anidex_test.yaml +++ b/tests/providers/torrent/anidex/anidex_test.yaml @@ -4,34 +4,34 @@ daily: results: - seeders: 1 pubdate: 2017-11-26 00:00:00 - title: '[BakeSubs] Kono Subarashii Sekai ni Shukufuku wo! - 06 [BD][720p][8945FAD8].mkv' - leechers: 0 - link: https://anidex.info/dl/99170 - size: 535822336 - - seeders: 16 + title: '[BakedFish] B-Project: Zecchou*Emotion - 06 [720p][AAC].mp4' + leechers: 2 + link: https://anidex.info/dl/225941 + size: 510656512 + - seeders: 1 pubdate: 2017-11-26 00:00:00 - title: '[Erai-raws] Animegataris - 08 [1080p][HardSub].mkv' - leechers: 16 - link: https://anidex.info/dl/99169 - size: 749731840 - - seeders: 19 + title: '[PuyaSubs!] Mahou Shoujo Tokushusen Asuka - 06 [720p][1FB3C050].mkv' + leechers: 12 + link: https://anidex.info/dl/225940 + size: 392167424 + - seeders: 2 pubdate: 2017-11-26 00:00:00 - title: '[Erai-raws] Animegataris - 08 [720p][HardSub].mkv' - leechers: 24 - link: https://anidex.info/dl/99168 - size: 346030080 + title: '[PuyaSubs!] Mahou Shoujo Tokushusen Asuka - 06 [1080p][5AF71C7D].mkv' + leechers: 5 + link: https://anidex.info/dl/225939 + size: 878706688 backlog: search_strings: Episode: ['Dragon Ball Super 115'] results: - - seeders: 1 + - seeders: 0 pubdate: 2017-11-18 00:00:00 title: '[AnimeRG] Dragon Ball Super - 115 [720p] [Multi-Sub] [x264] [pseudo].mkv' - leechers: 1 + leechers: 0 link: https://anidex.info/dl/96848 size: 227540992 - - seeders: 3 + - seeders: 0 pubdate: 2017-11-18 00:00:00 title: '[AnimeRG] Dragon Ball Super - 115 [720p] [Multi-Sub] [HEVC] [x265] [pseudo].mkv' leechers: 0 diff --git a/tests/providers/torrent/horriblesubs/horriblesubs_backlog.yaml b/tests/providers/torrent/horriblesubs/horriblesubs_backlog.yaml deleted file mode 100644 index 268ac5afdb..0000000000 --- a/tests/providers/torrent/horriblesubs/horriblesubs_backlog.yaml +++ /dev/null @@ -1,40 +0,0 @@ -interactions: -- request: - body: null - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - Cookie: [__cfduid=d5a062596a3dce73d239c437d02e3087c1510663255] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; 0f396cee-c939-11e7-aa23-1c1b0d9d2a41)] - method: GET - uri: http://horriblesubs.info/lib/search.php?value=Dragon+Ball+Super+115 - response: - body: - string: !!binary | - H4sIAAAAAAAAA+xX0W7iOBT9FSsrrWYfkgAJBFDIalrKtAO0Uwqazq72wcQ3xIOJM7ZDyt+PHELL - toXSh5m2UiWEHN9jn+PrQ47wFZ4yQCHDUnYMAQywBJMmETdQCIylmBCazDpGxUBTLgiIYqhLMsVh - WQp8JRAlHYMIPOOJOcWMmTJLQZjVat1ABCtshpkQkChCZcrwqmPoVeSWmUmT4SkwI/hQrdr64/2F - fIwUVQw6xhUAwoyhUqFEERdIxVQiGfPcQLGAqGPY+kHaD1QYQbeYQkd6jys95ds4QCaqVuu+rci2 - FEaTeZRpqlIS0jOm26ykxu5DruuBL1Oc3LVTmnqtEfi4VPiHEWigZvdtjQ0OpPdq++mL+iH0Gvh8 - +mrlieOvAYcIKJAPFNhK6C/txsAndHnfknofifa2/lErF5PP9fJ2QwjbGNOnD220thD6V0v4z7fp - g34SZqpVCiiW5gLPElCbjmw3SnNs+lQafliA0UBPl71br2//faM6mUjaU0Xj9j/jk9Go1/901T27 - /np6Pvn8rdb44kwGl9eDo5PR2P1TiU6sVNq27WSFsaUEDucgrDxqe57n2ThJeJaEoHEZ0bANIuRp - CkJmIgJhqXm70Wq09sBpokAkoHIsBOVCWlpq1XH2UTCAMAYhUywwoRIsLmZP8fAUkmIsCvQOBo2y - pALMVGxJ2m5WHgGlbmphAQmezqyQL3bttZjdcj8tT9FkZS5TWWy4A5sCiAhC9fh+5W3JGAuwQrzg - YIVJu1m5d4QSpix9rXd3tmg/gpObjsxpOMdSbsNd17nFG8HadXteD1t2Vrx4nx/o5/Ea/T9DbxtT - UntJIbdbXrNaq9nl5kZQrjtMErkjfkJOl+cJ45igSPAF6lEGPRwqLlb3tOV5bkWUQbSu6pbZ+tmu - ff+e3ixX8iZfECPo9X6twEmqx0D0r+qewmyrtJb2I1+wBiaeEUwGv0PWiIdzUDuliduyXXfjhsOb - fJnNqBFMRvtTwCZ0+ewsKHPwJbNAS3iJLBiOP51e987c+pd63x0cXZx/PPEGx7V+97x7MT6/PHvP - gvcseHNZ4DbeQBbAyqtATmlt4byyLFguF16l6VVeXxa0aPQjrvFUkSn8oizY/Cd5yTAoNLxEGvS8 - 4bfR5+NT1x0f9xuX1/3aUa8+PHMvPjaGX4+vvPc0eE+Dt5cG3utPA0ekzaiRZa155bWlwY0zdYVy - 2OtLA6elPDFrtpI5nh6YBj8BAAD//wMAnKZf/bsUAAA= - headers: - cf-ray: [3bda0ac986d61acf-DUS] - connection: [keep-alive] - content-encoding: [gzip] - content-type: [text/html; charset=UTF-8] - date: ['Tue, 14 Nov 2017 12:40:56 GMT'] - server: [cloudflare-nginx] - status: {code: 200, message: OK} -version: 1 diff --git a/tests/providers/torrent/horriblesubs/horriblesubs_daily.yaml b/tests/providers/torrent/horriblesubs/horriblesubs_daily.yaml deleted file mode 100644 index 95bc96cfaa..0000000000 --- a/tests/providers/torrent/horriblesubs/horriblesubs_daily.yaml +++ /dev/null @@ -1,143 +0,0 @@ -interactions: -- request: - body: null - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; 0f396cee-c939-11e7-aa23-1c1b0d9d2a41)] - method: GET - uri: http://horriblesubs.info/lib/latest.php - response: - body: - string: !!binary | - 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 - CGXg/zX4stf7AQAA//8DAKauFKkTnwEA - headers: - cf-ray: [3bda0ac365221ac3-DUS] - connection: [keep-alive] - content-encoding: [gzip] - content-type: [text/html; charset=UTF-8] - date: ['Tue, 14 Nov 2017 12:40:55 GMT'] - server: [cloudflare-nginx] - set-cookie: ['__cfduid=d5a062596a3dce73d239c437d02e3087c1510663255; expires=Wed, - 14-Nov-18 12:40:55 GMT; path=/; domain=.horriblesubs.info; HttpOnly'] - status: {code: 200, message: OK} -version: 1 diff --git a/tests/providers/torrent/horriblesubs/horriblesubs_test.yaml b/tests/providers/torrent/horriblesubs/horriblesubs_test.yaml deleted file mode 100644 index 171f513d83..0000000000 --- a/tests/providers/torrent/horriblesubs/horriblesubs_test.yaml +++ /dev/null @@ -1,39 +0,0 @@ -daily: - search_strings: - RSS: [''] - results: - - seeders: 1 - pubdate: 2017-11-14 00:00:00 - title: '[HorribleSubs] Shounen Ashibe Go! Go! Goma-chan - 54 [480p]' - leechers: 0 - link: magnet:?xt=urn:btih:7FINJFIB6C4T2GHUGEFNF4NNTPQAAJYW&tr=http - size: -1 - - seeders: 1 - pubdate: 2017-11-14 00:00:00 - title: '[HorribleSubs] Shounen Ashibe Go! Go! Goma-chan - 54 [720p]' - leechers: 0 - link: magnet:?xt=urn:btih:ZG3LKVRVO6LFFWHYTJSNJHNYLVS7I5AW&tr=http - size: -1 - - seeders: 1 - pubdate: 2017-11-13 00:00:00 - title: '[HorribleSubs] Shounen Ashibe Go! Go! Goma-chan - 54 [1080p]' - leechers: 0 - link: magnet:?xt=urn:btih:QAZ6NJVICWBUJUOCIUJPG6B76PT3UGYU&tr=http - size: -1 - -backlog: - search_strings: - Episode: ['Dragon Ball Super 115'] - results: - - seeders: 1 - pubdate: 2017-11-10 00:00:00 - title: '[HorribleSubs] Dragon Ball Super - 115 [480p]' - leechers: 0 - link: magnet:?xt=urn:btih:ZTERRFKGSDIXWHNUJY26P3ULQXLBERT4&tr=http - size: -1 - - seeders: 1 - pubdate: 2017-11-10 00:00:00 - title: '[HorribleSubs] Dragon Ball Super - 115 [720p]' - leechers: 0 - link: magnet:?xt=urn:btih:MTGHXFI45P5K4LBONAE7LC2KDNDOTNQI&tr=http - size: -1 diff --git a/tests/providers/torrent/limetorrents/limetorrents_backlog.yaml b/tests/providers/torrent/limetorrents/limetorrents_backlog.yaml index 89a2056662..e7070bfcd8 100644 --- a/tests/providers/torrent/limetorrents/limetorrents_backlog.yaml +++ b/tests/providers/torrent/limetorrents/limetorrents_backlog.yaml @@ -5,128 +5,130 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - Cookie: [PHPSESSID=f6m285u1im5opcr5oqjea3cjv5; __cfduid=d61b4a29592b7d3dabd3367290e3ac6d61510665157] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; 7c4823a1-c93d-11e7-92e1-1c1b0d9d2a41)] + Cookie: [__cfduid=db35e03b233610d9eab39422b147cd47f1550260503; PHPSESSID=eitjk78lssq6963ld9l6k8mdg4] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET - uri: https://www.limetorrents.cc/search/tv/Arrow%20S05E07/ + uri: https://www.limetorrents.info/search/tv/Arrow%20S05E07/ response: body: string: !!binary | - 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 - e0dy/VE9mQ8O+3v/BwAA//8DAGNsY5QadAAA + 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 + m9BqMlQ8fPL/AAAA//8DAP0/XolcewAA headers: cache-control: ['no-store, no-cache, must-revalidate, post-check=0, pre-check=0'] - cf-ray: [3bda39350f9d1adb-DUS] + cf-ray: [4a9a552d2cf8c4b0-DUS] connection: [keep-alive] content-encoding: [gzip] content-type: [text/html; charset=utf-8] - date: ['Tue, 14 Nov 2017 13:12:37 GMT'] + date: ['Fri, 15 Feb 2019 19:55:33 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] pragma: [no-cache] - server: [cloudflare-nginx] + server: [cloudflare] + transfer-encoding: [chunked] vary: [Accept-Encoding] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/limetorrents/limetorrents_daily.yaml b/tests/providers/torrent/limetorrents/limetorrents_daily.yaml index eac94f8077..2b438b42a0 100644 --- a/tests/providers/torrent/limetorrents/limetorrents_daily.yaml +++ b/tests/providers/torrent/limetorrents/limetorrents_daily.yaml @@ -5,161 +5,157 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; 7c4823a1-c93d-11e7-92e1-1c1b0d9d2a41)] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET - uri: https://www.limetorrents.cc/browse-torrents/TV-shows/ + uri: https://www.limetorrents.info/browse-torrents/TV-shows/ response: body: string: !!binary | - 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 - z4dX+n8dMent/X8AAAD//wMA2GCeiEmjAAA= + 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 headers: cache-control: ['no-store, no-cache, must-revalidate, post-check=0, pre-check=0'] - cf-ray: [3bda392f7dc11adb-DUS] + cf-ray: [4a9a54718cd9c4bf-DUS] connection: [keep-alive] content-encoding: [gzip] content-type: [text/html; charset=utf-8] - date: ['Tue, 14 Nov 2017 13:12:37 GMT'] + date: ['Fri, 15 Feb 2019 19:55:03 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] pragma: [no-cache] - server: [cloudflare-nginx] - set-cookie: ['__cfduid=d61b4a29592b7d3dabd3367290e3ac6d61510665157; expires=Wed, - 14-Nov-18 13:12:37 GMT; path=/; domain=.limetorrents.cc; HttpOnly', PHPSESSID=f6m285u1im5opcr5oqjea3cjv5; - path=/; domain=.limetorrents.cc] + server: [cloudflare] + set-cookie: ['__cfduid=db35e03b233610d9eab39422b147cd47f1550260503; expires=Sat, + 15-Feb-20 19:55:03 GMT; path=/; domain=.limetorrents.info; HttpOnly; Secure', + PHPSESSID=eitjk78lssq6963ld9l6k8mdg4; path=/; domain=.limetorrents.info] + transfer-encoding: [chunked] vary: [Accept-Encoding] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/limetorrents/limetorrents_test.yaml b/tests/providers/torrent/limetorrents/limetorrents_test.yaml index 570b953382..5d209532a5 100644 --- a/tests/providers/torrent/limetorrents/limetorrents_test.yaml +++ b/tests/providers/torrent/limetorrents/limetorrents_test.yaml @@ -4,36 +4,36 @@ daily: results: - seeders: 0 pubdate: 2017-11-14 00:00:00 - title: Travel Man 48 Hours In S05E04 Stockholm HDTV x264-PLUTONiUM + title: Arrow S07E05 720p HDTV x264-SVA leechers: 0 - link: magnet:?xt=urn:btih:191AF23228394917EF80925CD6E7D5868FDEDB39 - size: 152955781 + link: magnet:?xt=urn:btih:610F125EADED845BB11396F9610222482C995DAB + size: 780769689 - seeders: 0 pubdate: 2017-11-14 00:00:00 - title: Come Dine With Me S08E73 HDTV x264-NORiTE + title: beat bobby flay s19e06 choc o love hdtv x264-w4f[eztv] leechers: 0 - link: magnet:?xt=urn:btih:A148339F51D69A178E9B32045CE2C1267167FBA3 - size: 162109849 + link: magnet:?xt=urn:btih:5682459258E0672D6EFB80D0EDD13309DA064A31 + size: 188974366 - seeders: 0 pubdate: 2017-11-14 00:00:00 - title: Come Dine With Me S08E76 HDTV x264-NORiTE + title: Doom Patrol S01E01 WEB x264-PHOENiX[TGx] leechers: 0 - link: magnet:?xt=urn:btih:C755231982B054536562349BDE1DBF27D705C902 - size: 172396380 + link: magnet:?xt=urn:btih:62C04640C66E80E83BD58A25068DA55B6654C84A + size: 426455859 backlog: search_strings: Episode: ['Arrow S05E07'] results: - - seeders: 2 + - seeders: 63 pubdate: 2017-10-27 00:00:00 - title: Arrow S05E07 1080p WEB-DL 6CH x265 HEVC-PSA - leechers: 8 - link: magnet:?xt=urn:btih:D540765A1D0B49EC1C7BF6186C42D9E652500AAA - size: 524350914 - - seeders: 0 + title: Arrow S05E07 HDTV x264-LOL[ettv] + leechers: 9 + link: magnet:?xt=urn:btih:AF16348EAF93C015C9F16B0807C24635406B4FFD + size: 283629322 + - seeders: 18 pubdate: 2017-10-27 00:00:00 - title: Arrow S05E07 720p HEVC x265-MeGusta - leechers: 0 - link: magnet:?xt=urn:btih:9E3824E13A6401AC1B39E0100062335DDCF3FA38 - size: 290633809 + title: Arrow S05E07 Dual Áudio 720p WEB-DL + leechers: 6 + link: magnet:?xt=urn:btih:FAAAD71EBE82432BDFA5E8B8EAFA43B569D279DD + size: 478465228 diff --git a/tests/providers/torrent/newpct/newpct_backlog.yaml b/tests/providers/torrent/newpct/newpct_backlog.yaml deleted file mode 100644 index 73555bad3a..0000000000 --- a/tests/providers/torrent/newpct/newpct_backlog.yaml +++ /dev/null @@ -1,1635 +0,0 @@ -interactions: -- request: - body: null - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - Cookie: [PHPSESSID=r1j49v1otvv3e63b36utuqlnm1] - User-Agent: [!!python/unicode Medusa/0.1.17 (Windows; 10; 87a3c54f-d2da-11e7-b715-1c1b0d9d2a41)] - method: GET - uri: http://www.newpct.com/descargar-serie/macgyver-2016/capitulo-22/hdtv/ - response: - body: - string: !!binary | - H4sIAAAAAAAAA7R9+1fjuJLwz3fO2f8hk7O3bU+Ekfw2YDghCd1A09BA82iae09IHAh5kheBbvZv - 36qSnDgPOvPttzunh9h6ValUKlWVSvLWn8Xjwvn1SSnz6fzo8/YfWw+DVhN/4nJ1+49/bP25tpY5 - igflzHn5vp9ZW8O0Fr4/DAbdtfhpWB9F2UKnPYjbg7Xzl26czVTkW5QdxOPBOra3mak8lHv9eBB9 - O99bC7KZ9aTp8/qgGctm/7E1wJfto3Ll48so7mV0iwvPyFhjbmWqcb9S7t2Xe5l+3KvHmUGn1wMY - mfteeVDvb63Lqpk//pGg1y634iiL1Xr17qDeaafwkvD/kfSuc1cHHIrxqF6JZV9T3ZTtjOrxc7fT - G6Qaea5XBw9RlWqt0QvL1Nv1Qb3cXANcm3EkWKZVHtdbw1aSkMVmm/V2I9OLm1G23irfx//u9yrZ - zEMvrkVZpOnG+vrz87PZBoCVgVnptNbhd71Zv+uVey/rCvz6IG51m+VBvE5t9NdlcWE+du8Vdadg - ys1B3GtD4WxmAAMECd1us14pI1XWe/1+btxq/h6DWhxX16E2EjnK/g8GCHFaGJwe0K5fT9NUZKrl - l+z20mJr5Rp0Y1nhf8z0tlJud9rQuxVdmuC7Rviut8qVe+zUGvZpvVLu1gfDZmfNstYfqoPRuiRq - glgdyd/rdKMsopjC6QsBUCMwV/R3vDhflkY1Vep/jTEymT/+SMAhqLg3eImynfsNGtsUxP/hIP+R - gf+WNP+bzr9T4/+QBPjfe2CHveZKoCn5dTZ4acb9hzgeJMJxyon9Sd7/x/yu9PtYgNoy4WVHuEL4 - liV8kUxnErOQtTDx/9cQ6MX9bqfdr48Ihf853HY8qLbL5l2nAx3qlbuValvKFwC6Vn6O+51WvG6b - likIbDr57wDWpoA1CVhTgLGlvnnf6dw3Y5jafYKK1KyVW/XmS3Tcjdu5s3K7v+Fwzjz43+dck+C0 - BJy2/Ucy6oXT/ZPzs0wuc/D1W+n0Goc+I9ezh5gWUjdz9lBvZWqdXqbTrMI0uut1nmHS9DN6q9Mf - NF9UMsywPsyJfqZTy+yXDFMxkZwsafiP5VFZpmoZWDEmPft/GcrH/vrj0zDuvZitett8hA5trcs2 - 1Sz8PwNbGfYHnZbZitvDObiSojd17P7t9gQFhJVwDWoQbv+hPlIDWOlUY4LaH7XXB71huyGLQMvZ - acswHjdxu1qv3SJJ1cAdQHcyCoSOYwWcPUDaP/YzNdAC+plyL84A2pW4Cqt5ZgBFasCtcc+QI5Oo - Lf1+F9/p5aTTzVf7QI4BPg7bOK4FwJFGf5ZQmV8ZEKf+mhBrlsf8wHNsh3HGsfH/+GOG/tk5+mdh - uRuU1yq1cv+lDcSplZv9GJa/9b+go4Vi/jx/s/5X5q91SMic9GCqDqBCrzEyM6Vy5SFT7bTK0KF6 - P2M9AGJjkOXlKhbP6LVhu4KCWTd+ZkYg27vRc71d7Txvdm+yP4acu7Uu/ng1/Ovz7G10IzN8u/5j - 7DuU6f4YO2E1q/p0y26yrTplxLt1SOaY0u10obwrk+mvE0OC1f8xdvmPMbbhW9gOQeWqFmQ4snQF - HsULPjqWAopYOFDNn75jM16sKldlTa9MJd0m4ptlRDtqm5CQoD2P3sRQwZJNEyZxr0igVaMDeKl1 - cR4DshVZCxoOQT1hf4rb202kYhzJ5q3ajzH+79k/xraglDih59jnqjbh0Ze5KfokHZTtEPkRNlY0 - 4UH2ys6y7DoBwSq2lcAYJyOWhgFVbay6pP1uZ1pcYTEFMO0KcjQ0UH24w16Jh2EDfgJZ1aRaMIZe - mIBTaGHZOwmNMO9jmyoT2qQc/3kK2rfLL3eTQanSX08CGWBb5ebIpPZmIEF6T7WRpk72lrUizoas - EqWYvV7Ts9koim9at0YvHgx77c1h1E2YoiM5ABmjqmiFVEP+uVVlbOJXygM5V2pKmlXjhLxYVM/2 - K5NioepA1tgcqinkvBAXAAfCvMrSdILnsXyQPUIqj/APjh3IgukoAYCkITm+PqIUtiV20OCfnHjx - Fbsle1FLuiXJOvaS6Zh0bOwlc4lQcLDbOPHclkxuS8CICz7JmejLKesQlljMh5qxxBkIgmSgCjAL - epISINCMG347ocOUlog3jskmjE9ryzJ+QpFKb8LN9vSvI1OsugIpSYyTH0lJRGljvTYSRXWYaKBI - ABhlN98IBdX6ZFoAMlOQFrSX4ptWLrdZ0Y23zVcQaZLJiN/iASEV0zQCmaXIKSHH/TjpIZHV+pEI - nQkUCRpoNWSv0DqCMHRjEwT67e22lO2T1e0/pkrCsmXhnSVkG5nhOnx184mIhyVKx8RdN4/rHeXR - zIAEsxm378HGjSJd52OL55lvbPGxyFs78O4XWGhs6J5tuiXB+NjbM7YjYdqhXbJ3hOlYQcne0IWw - Teab3C9ZhvHhA7aKrgBcHvMDHdsVwmG2axpbERQOmesZ2LrwPOZB8/AU+NC6yw3DIEyEaYUlm1kW - 1rBDZtumKAmo5JmeV7KYAGtlwza9ktjG2nnmhJBpC5Np3zRo0TUZdqYE1SHb3duBvyECshwXtD7T - gcbewXRvj3mesSUsZ0cPzTAEaIHE0dtDCrhAAc/0RcnCRj3svmN60HVmm2GAFFBdgDUf8gEFEIZA - PcCdA96OsQFYhIh2yWduiH0wdmhAoSU7NG0gtHDcpegJJDlACjm0SgMk/F2m7TxBn/1gO9IDG4Hm - dyV5BRDKFICUbWx4rrmlCwtwpIEULhHMYw71zXItItgEe9/0BNLZ5DZW37aE7AP21cEMDm3qls/8 - 0FyOquWZDPsD8GjYbTMA6gCU3T2A7AQ4oEzbxNEKA8JK2I6xrQvQywVkGztAhQ3b2YLBFD7VJJyF - cBnHSqaLpBCOMBOkA9f0Ze/2gHEs0wOAO86G5WDXQ+ygsLEFxzU5whNcDiwv4EBAK3e9uNx4m8yX - r/Pz5ev8fBGewxzH2ApMjgxBnJwnfvE44SJsH0cUKcDHToC4BSXAISAeZHZgBoAKlA9sZFkY2G0Y - Y9+F6YVIWsAT3HQDYnnftCTbfp0ltou9F1wsZOh66EGjvm/QLNkjynAD+HbX2dAdUyABPY+aBeYR - ZiDpDOOAXSmC8oqDHDDkG0lkmHhLwPg4ZKYDjIGyw7JLO75l0sTwiYvkPEaOJArs+jgKHGYrMpEn - eT70Egj+AgQue8jnB2h/foD20wMEmO7PY2oTe9ghybhgF9DwCYkQ5JNjEp28kAHH4KDtZLMbnulC - F7aBR2ksHZJCAiRNQJwWovwC6cRggmAVQ2G6ANqVLArcCpPKxzHfojFxYCq5OLfklOUARoDIBcaA - NCCaZ6Pw4yrfcjgRcJcYtxAyYBvgGG5aDrKfkszMhzlBBWya1UVkmnlSYHVEwc1ji0UlkYsA39iw - uLmN4wXyOaD+Aykes8AKgBSIQ24KPu2ru9C2HC7ohhoubdiPM/1Br14ZaKSqPLlX0c/sgZvPbkyW - 3Ct2afyUGlrmaiu63Hxj2S/BXAnWnJb51+W/mlio+H4zH6iV1/lWpgX+ogIf328BOkJFqu+3kRS5 - c1aA+f5+gaSNl/eLKJJ8e7+E7G17NaZfsI0sGGzaWGjvlqWie++T5hcVuPxdp6jE/WrqHq5spPIb - XqECtfeb2JZovF9gjQq0VrFJayW/nq7uan5lV7++X+JPVWSwiglefscEVOLqN5xGBR7/BhoIJQv2 - cPZ5JWmefkcayQTvl9iWQ3hHvUJVCSbkKhKc/aY5KvDpNzhLEnR/w1OyjaP320iIVFnFd6erOPfk - /cFMgPRX0u581QQ6+g1DyBKfVsuveCUfPK6S1vFKEThaJZPyK7EYrizxbfVUPlk1hc5WdqWxEo/u - anFep2kYwzTsrJxk399vTnLjORYY9IYwxWqrWGZ/pSy7WInQyUrOLaxmu/GqOdZeLcwuVyLydfVQ - nK/GtfOb6S5LNFcLletVHS6tYj3t5d2lXw7u+H0sJIi71TPkaVF/Y6Npsb8u/2r+NcKC1VWsdryq - P9neatIXVxepr2aU59WtlFbyUm/lAr27cnLt07yvw7wvrxKqu6uXkKuVU7Xwfgm0wuSEfx9rqUQ1 - VgnNvVXLYRkLZAfQ7ZdVS/zrqtF8I3Ok6eTTrj9MOomy7exmkpj5qhPjYk4lykILWdYAa841vZAs - ZoGeJgF2GBlRuz6sMFlp1Nuc7MS8bxjsAuMcsqwY3dyyfARGkAnSlhXoCXQbdhDhvlKt3o6rm4Pe - y8/EzD2MmjfHQd68DvK3usGGm3/q+UgfRodmOx4PdMMwH5y8sTlp0vhZNLvD/oM+NEfl5jA20Ms6 - +vABs2Fd04vKRoYuSRMNCFEpDyoP+qXs43hKjivj50F0BcR8nEkrYNrmo55A3BxD3c03wL3cbL5k - fiL6APTP/IcPhzf6RQ7LwcDlGvQEimPuxLg1KKuCj3q6MlQsGIOHXuc5cwCoqSErbiZPsyNKIxhl - K1k2irLldpbBCLX7OEDZZhZpXr5DmmcxsATInl3LAsmzQxyJA/itACcdRtkYagyjbCfLxvDS6mah - w9lylh1F2UyWfcQAmywrRdlRltWi7D4wB2CZ7/XKL2a9T79Alil7bb7FoKZmoAz2F2aOrgaQHd89 - xpUBFp6U/kodkVV+yn5n2vFzBiOtSr0ecIFey5VyH4l2MOvpF4y43FHucULZ5Hc8eTqaPA3VM9Y5 - nKmBI3GQK0D+CZQ6yeUnMIq5CzVaoF+o+phemdQf5ZpJvmHgXHqDUZxuNL6wQcDagRyghog0XWNf - eKQ1NRbDWxV+4C2vsa9hpG1q7BreBuU72lrV2AUUiQcaOxTkaCuR+85N3EjoW91zyJdnmUx70KQj - z91lQQgTrQiVXzTWC2mOuhaXk9QVxrYemgE6Maypz8UOmNaXLcD4JC45gxWgFRM3nQHvINJanWE/ - HnYB0eSl2nlua6wOr1/vNbYLv1+eNXblRNr9p8vC0f3lrsYu4W0MpY65dBhaIXNCcmajx41LAeJy - MyQXj/aqbegWeY5DTzqv8+g5tpk2RAwT1yU5PdkI23Y411gFnhz4fYBfmyOl4OXeAZAeNuYq/9tu - wAJ09LimhTTQOLYZoJ+RCdsMbfTfCUGO2p3saRYd0pwJLoyt0N7RidSnGjm8mIUUagC4UGNl+PEt - GDP4FRZ5qTR2Ci+W7Yw9eC4iel5Az3mgKpR9hCQX3hBhoCGMPVB2F37GUBV+yho7QBbQ2Gdgjxow - AiTWNfYduURjA0i8A1qH6Gzj7AiKqggGVoNnprFn+FFRChr7KFTciMbOML3fPx02477GvsEbBpFo - rB1GHmdjHCZh+VJuC5vIDVxjS09mYNoeesN0GDGmdWhIbCBLaOF4FKmyDfUkp4Y88Ufn81AnJD8e - aw+bTdwEcOxt3aWh9vNqOyTPtHVoU3jAG55pCcm2RdfYAblDHJ4nP3gJgHUAcwd6xiPLZmfwV7B6 - FLI+j4TPniLhsd1IuOx7BJPlGyTa7ArQc6hV9LKbAblmuWOSMxb6IyzkBtq1KAKAL0Batk87Geip - xR0ZYiN0fVrolAylL9QzaRPH903JFJ8jlw2wGrfNZNPHId81C0OTehpKz3KAzlB0LW9FbojpezYg - ZMm5XEB3dZA4ju0STEzcEoBaPnpQcRgMdhcF7Cxy2Gtks0tgiUBjXfjxNdYC8ghgty/weknbYDDa - z5Fg12GUzbJ+ZLEKsJKpsT2gHWcdeAHOizg7h6d1jZ1AA+vrGi3EKMGGzswCSD7nm303f3szCG5p - hTxy0lpEIYj0E2HkHsLcOc8VuPkZROaJA+VKsy3JrOjKfHLykPs808peuNgKFBovNNHCJiDn7D00 - zdfafbl8p2KRaPnGblXFpDw8K+3nEuZmyEWlxn2PB1WYi81Ie251yq/WvVce1znM1VEazWEklzWz - 2+sMOrgvaT6U+8fP7RMVdmdWYGnXx2xo7IxvhrcbQwCvFseak9cfg0QlOZ0ui+VB5w5ybk5vzX63 - WR/oHW6YvRh7EOuG+diptzEJlh6pl10D+rDqHwu9grrWLr4Wo+/4k496kMoaINSjz0K/MGDpbwu9 - aMDS38UCw2hf6AeswPLsFHAAJeDnBEEw6vRRyE4DQI3SZ9b2nsw9nOaOYBlEjB6jUadezZwm7VSD - aTuYfzQzUo80JEd605htvx1M28daH5fU+kjKF+aWAANQUP7WaJRwNEo4Go/sJBrmapuK8E2hnxhm - f3jXH/T0U4ZY3EMv9zirh/oBKC65Cs8dArO1+JR5WhzxSVTWXmpn5uYrsB9tz/RS2zO03YzChtuw - vHAUjbixEqodSbGLmQHtg/ZmtxdsI4qEJRbSLUNtvfQWtyPCINmMQK10itZNj3CTTN+PB+f1VtwZ - DiZaTKapTzv1eWmnPs90SlimRUuHA6tm4Jg7sGrC+wbaCHu4n+OCiAuU8uEKuc44JAyxvyXs7+eF - bTyfdlzkvuiWDioKwz08uWrgNqKx4QawSFmkurBQbjDh/i4IWLlnjHtcIKFxqyjZuyEafn6Hhp8X - aagjeFiZwmQn17JhKcSdPtrIQn1Gbm0xx8WFwYI1Bei+IUwLN5Gh8wHudoPqRZrGDiwKQAbouUfR - Ay7tnS8fpc9E7JkRaoLgNhKO3Xy7gklXacblXpKPM4KKSLUa89/e2FNK3D1JkUCDfxGBHkWztgjr - Rncs96nyoHLUeuVWLF8LM1Pv0HyI6/cPg4koPZjLlocHktzDKNUfrQLdpGiiFuontzpYUAcgjjYL - +OfQxMjI4xBQhlmVErMJI7aXMmI7xYjOhw/td2ZN+50Rb/9u1qRwb1MHyt1u3K4WHurNKqB/CMQ1 - NpfMH7WgXEXZh3q1GoPZJKdaNvUGxtuDfAIDrt1px9lEYh6C1AFiUFh0tQ6LQPkFbNZfvzBvLBay - 9Gbu0lDZF+60Kh4tuKvDCvLCrlR2nlru1GqA8ycaRlp5Ds1uGYPdv2D0aS9udUYxdRE7WNETXvpd - qYbkswvkvtcUs70KkOw/ZSdtxWqVxPKntwZy9z4orD0w2tMExLlQSWRUmsUqxFyXUyO8mUyCSTMN - wmY0mShg6rP9FFqw6im3HFMgGtEjSHLWN3Lwe6l+m+p3pH4r8Jtu8jG1EFC1SV8vc9fh5jNQJyY0 - X4Q+Spb6ppF4VBa5hQNDRFe50eabpLuChc7CXgp9WNVTsJ4TvtmH0b0E1c8g4hFcWEWboBQuggQ6 - joiOFb0/t/T2qFI3VDzTcfH1MjQSQi220dBfjanHArH9nMIWNI+Jv0ITtudpius1EVpcUzwx6cWV - i70YLQVXUeDmUd6lnieUvVhS54JQVBhWAMN2CsN2CkMRKuxEoDA7Q8wut6K1u9+hdJZCCQsPfofL - 57nC+7JwcUnhor4/V/izLJxfUjivD+YKn8nChSWFC/rdXOFnWfhgSeED/csczWMap1NF88MldQ71 - Kz5XKU+VnlWl4ZJKQ/3bfKUzGt2+qjReUmmsf5+r80J1XlWdxyV1HvXd+R5RnbOlempF6alPc3WG - 1KHPS7XUitJS+/MdeqZK+6pSaUmlkj6aq9OiOgNVp7akTm1BiT6mDt2pOidL6pzoe/PINQhQXVX6 - uqTSV/1somBgmeslZa71j3x2wnVTE66bmFxX6K1oaYlQRVPuOlUObZvJ8v8lvfzvJ8v/l3TsU/jh - w5fZ9dybhG/NZQQyw1nIcGR8j72QoeJ7FsKxrufxuvmSIHedQg5wu15EQcc4T/TtudIzZsmYQMeX - Wm7ek0GfGEjokY7pUOjkNuicwk2Cn0C3tclhhSZEyJlrBp4MSp2DiO4JF9RODJ/SXYv8NK43ibMS - VsBcH700YQnDKgPy8Oxg+Bbq25ATUrAn6OKmZ0tl2Aowsk4UQaP1KPbRJy1b1z3TR30Z1GYKkAMt - zJHWTuBOYhAtp4BeQCED/K4X6Y0xscLB4K4wIKOBqFTizPEQMdfGAEHlObFBnV6MZjxeyjXHMyGN - gqJEQxMdjJ4KuOXYv5AchYnaz2WYH0UIO0w7Jz+YZTHXQeyPlzAe+T4Di4HOj7G1LgbS4ZA5no8j - pkbWNikaLpRUOJ4fMgzgLKKV5AMVfemj29FDYVLEJTrryPrw+CRY0VloxVFxeCFTLGZQpFsIrGZa - Psa6yrDaAvlgqV1TeEh3YXLkpe0Ix3oPkRe2g/yWLWYpqJf7aBwpG0wg32JAsoyURTsXUfdLS3r2 - 3nyqL8yn42TY6qlhCz58qC+SStgFJjzlPuO7gAfyL8UbM4ww1F2YUQ6X/k0w4nbIesOIUGAjMFzR - a+cwDz12ONYBRv/hZCKTPVSsDR2ymWeGRBecgQ6GbSOBkI4OOhU5BZADIbixDVUd9D4LR0YCu3I+ - k8Fs05gvdMRymU2RvnKcLGePCZqKwlaOR5gOoYyPlVYtDnp9kcC0i4Cj6nEK8/RBONjJfC9BdeV3 - pEh0MNGnEwiH4jLSPtfbQ2UXgvqWb1d7nXp1osE99xP9jdyN8qUB9uPxmXy+iLSjciV5AyuzftKp - Ts3Mk3I1MTLh5QGsIPl6QO0VSvLtkMSJDF5W0fQyRB3ITEQRgck0D33IMMeQHT2QO5wiOPUQ5Wsg - 5U2eYrspNHwLo+0tj8YN46MtGGqHJBTzXEO6soaAVFuiMAaE5NMjoWZb8u2I+ucFh/L1Y6SdFORj - CZa2E/lYw0Ly8YTKo6HSlAlfKaHeHnT6DzLlOppbSm5AMN6ydjQ3I27qmPzAo5uv7ITJvTKDHd2y - e0h6ZPo4N8wd5jrCAJOAHdyyT5CMnr7iLatGRY5a7QM3YdTi8TGY0caf0UQDbPCZJb0qdVyuX6R0 - hU/v1D1eUvWYLLKk5v07NfPLoOa5rldyY54bGakm1hUjrpuDuD/QrxOFclkLQz6jGP1Z/fBhnbha - VW6rygfLKh9wcqko/aQK+slxSj85JsMhEVzf04JrN5FZ32d1gO+LOgCpJ3PpPqXzhXQ9JY/Q1wY8 - LXa075pcAlkg5DbeNjaKJzkELV7E/PYeHcSQ0sJPT/Nm1OFqRk+RvwHIt4lRduqmTct1Xe0tZARI - 0l/Jy5dzejcUXRMTbtbqbCqrE4zSzbeZtgJTpJvyTHu+pcaSlho6mKbzLc22Y823c7GknYsl7fiz - 7Yj5dopL2inq3TBlDGOs9m6KY3bTGu2Vt0w3gdSZaH58n/NoyXMPcxkq1j7wTdSpAhls75POgac1 - SI1j2U9ZYgYXlkkQe6AFgj7o0Y6WY1N0v9TNQpvq4RpIcfRzsATCCsOFdC5xcOXJKYc2uWxvx7Lx - XIRFDtw8QrVCqVHSIQ9jJxvRPp8lOOojlk3y2UNhbTmJcmLZeYZqMqkmNkcVBDSfMO0+JZqmxSRg - d3ujkUdSu00bGd9TQ/J9aoxg+EGxPIjVVsZltHZl3kv33iusTcfkONON9XaYNIYBN8dhSiKEU8um - XBua3YeuptpSW7U3/V7lL7yohDKzt8namvaT0kn2s7gZVwadnnaLIkhNxE8OemOKfLpfNBFOL+bI - ye800Ytq9mI66K2vKzDr9+zK2KA8QPgymCJ8GaAIS8fdjLxlbtZRiisFMN9ojiE4iRV3ISMkF7ol - zRc8eVEsMB/3NE1Yq/EYHRobyGfcA75ApzhoRsC8lhx0pSTDUxE5MzkLNFpkO1JnScXZZYFnKoW2 - pHjGkbEGUo0GDQHngs/leRedtmYdUHhLUhuyRICmgAyImBGUSkomDkw08abDBkjdTid3ZSkZK3Nk - rHhz4t12TBbyRIr7oSnP3cjdFZyZeJ7OVgeT6MigYynlc1fuU9vcgQSbIwnAKIBZQhsPG7Zl4qky - nDI0M1Fv8pMphcfLxsEugAxc2nXZAXPNwS0cWERQEgg68FZZHFxavSqL44ENz2n2lVmC3FRmCLa3 - lGB7cwTbe4/v9t5Bbe+3qKlpVYBplUJsD+VG5fbmm7hll+8tPtLNfkYXpGDhM3F783p78xF+nsUt - LU3VTmWIWx3GZhJwhgvMn9PjPAkjvTWjptp6rLfv9WfafRyj5zVxGz8rnfQiLd803CwG+QD6zUV0 - ofaLa7CyJjQtRqcsDzmykU1ymWMoHMsbm8VcbuIo/g79v7gBzVA2rjU78g4lDWA8dPoD7dZY5kgc - KUfixBWfdHPqCpYRdlD27Y01U3KnGaS8wvP3cahplv2RPfz4Xdy1vvDyZTg8LDTuY5t34df/kc3O - BAs2ljJPY455GkuYB81VjidqwcCi7Ubbl8LDEqGaHWAXknXkodVgYdRQaOxogUYWA513NG3pb2m8 - w4SNvzU/iks7UUx1Aoy84qI6oBMWW6AaWnLN5rgT6aNfwUKnkGO6dHrVCpWECND9EKCIdeigG9lA - Ss5atjTYyfB0d8lgoiVYxvEAlXxfyUmynVwSyHNYTbbXiosdn26vLWqHBZNOdyNX0ajOSdjGjMAo - LyVXeW7My+8JjPI7YzWXjhZ0wJnaZTa2HJce8DAvKdZATp9MUdSeMNLOTnatheQjefiyWEDnA65n - Li1iWxhJZO2ANW7heVfPJ+XLovgkpaMv8MfFnPwsz5AjXkqOeI4c8XvkiN8hR7w4govy896dkZ8x - ys+LWfk5qyw35uTnhZSf/dsb/aMwEglafE+CNpbtgTTUHgi6zhtRY0GeXoOQa8zL08JvN6iPBO6A - NmXRgyVFz0Fy4YYolF0ilxsApGCmNo31AyO9qVz0FjeVC5MtxknfcF68s/cKpd9mhexlalPyks+E - fx+VBw9mrdkBhkF6vAZ5nZJ6ZbByWrrB9Mu1K8PIXUGjrJ7SauvhdBt3EthziaqoOeicSRobKcoq - u6+LFyPutwdIwOlOAO0bzFSU69Z1aJjAy3iljz6zyJD2PGnratLWKIfB7JNXQBJH/o31p8Fgmb6j - q+MXEqXsZkZuujciMDrUipptD1t3cU++pvgUF7jRr18/35Q4mmW3ZN4Vls67QmrekYJJB5+9XZAF - IABBmpY4+fFQnrokgb2AFFOTRLXJwRhCsev7Ji4zKJMLKGgLi0YfGYNz6Y7y/VmODZJInfFGqUQx - KqB7B3LPQNpTlo0OTN9fAkD30KEmHNBAVTzxHp1jN3mAemf2M9qTjke6Imno6O/MBwTEEUkJWl+2 - ULmVSrglihIPodwTgRnQsXwZoxNODlGnJgsgdqtM7GTqjswHl7RwXDU6NUiJLqAHyp+TNucOTBWm - oR8kFp1uUBz3BbBxgV2FOFVlg9EB+QEK0BJw6bfzgmRUaJVyZxJxl74Zxe0KUOvb6X6h0+qCoShZ - HpE4jC5zjVxzIsKHyCrAjYe5qJIbUpFxNLoZTjwtRyBJxyxRqKhgIzcGts5TuAmrpHSoSpCOA5hR - T0F/a56B8Vi+j28uJdlGqWmIbonvqQn+PcRaSWa68hXIYdZJzaiOk2b+/FLmz6eYH5aQ/Ds8m1/k - WTpYn19ccqYcIcVBNtJv/rV5+5eRBNNoP378p5gojvrOxr9+bWZUbiUtuKHxW7NFAhP54zS+L427 - +ih3NTWa9Zsf5n/u/AUT/4f+w/hx8+P2x48f6z9y/7o1wJBuGhhvMxFoO9V4YfArN8+3xsb0WMsb - u0o5HK6ElMq4kE2pXuTEdTjyH4EHrsxB+f5LuRXTAjp1XSRP0EZqTaCDFKyZGtFm4oi4iHx3EuM1 - nPre487U815NvO4YyB1gXBqdHiB1V87RRG3BPTeTaSMZli/lgZGwuharhoaR1pr4zZM4ssdI65Un - XnOWmXjM48rEY/6obZ5wvRKyNDOjTyzVV+Pn1XurIS5csCBUwghauQ90fcxzg5AOkXznuaPcIc99 - DnOPuTE8H4jcEDMP8TlXyOFpj1OeK2KhMTeMKQpTO6V81+80h4N4sv+RhMxVonPHxLscZ1autJGH - DlQVeXWJ/qjcLs9dzoZiIfbk6PlzEpT0Ca2khNXuHP1nM64NNlCJqQ1yep1DKwYbdLqQBH9zIyaD - 8zZmW4Z08oFtzGIwYt1Ov47IbjTfpk7um1tEYyRmwg5DGdu1l5I+e4E+sR+fQYhWwiXRzJtv/wvj - ie4nYfycCXQcCVrr71MI3adMSugEmodNZIR3PWv5ZpOca2zJoF0hEVKKVUpwnqQ0rBOePo51c6sY - 41RxhQqFnkaCnWDcNLtSlDIwXOJSv7oZ3bIRjr8iZxvJySbyA4o15dG2CuAEas/zZhqfTykaAMOk - pPPRUul8lDYJQNweLRo8dLONFyYbv9xFLxQYOnRmBuN2LRltK/25Wyi2zR0n2NBtru7M2sVbjcKA - HFNoLe88aXjMwkq8augVDFG1COhUA7PwhI7wWCj33Om6JTs05U5uAb1TloM6Q6B2/sgt6NIFWUya - oAvdCBloI1syblca9Gi6o+CS1zDRkZItPnZwT96iW6M8C2+NkkYZ2NN0+RddnmQ6CFVr08VN8lSM - S1a1stX4AnwuTeB5G662dEhqszZ+bdHGpyDWufSJlV1bsmAG85DHSyGP55hhPGcfOokdOJ9hJ/0e - /61+ny2FfpbWkj2TA0FR27RMx0VWC0yHYqZ1yyMG8MlVSY5a5tBFV3SfkI/XA/nKk+uz7EHWkIER - GNzikCdVdwTjyilccpNoe7o4DK/HAvY5W+JX0WUQgVwDMfrCVhEcDleuFcsGJIW6Au5scXjoSjAC - IjAChO9gqISQM0fYedKMyS1uAYJuqCLknRBDCFAvdpHzcUtmsXm5vR9YeNxITpPSLu2YCHLXqC2W - UF3jVvChRW9JgExn6cB00gNDbnlOFzBtRTBKqBvgHVIyqsLFTvhF8heJfIAo2A6igP73PXLwo3vE - wy503uOuuQxddx0ZUYLyA+0iWznwfRAmAQ39huubSLmAgla8gPawfDnDYWoHTAbxTCdoZxn9KJbH - UpeBAWtxv2Tv2JwT0fw8shm5fehQoi2DdwIynVQIE8ejDZO7oeaI21pK3NbsbG+9M9tby9gJg7IC - 4PrAtAK1DYz3w3lWwjEBN6E/Pm2hGAuNLBcNL0vRfJkTDS/vDd58xmTugNx2bHnIE3ekcRHB0xi4 - jwEzyUMZi/FrHtqi5C7LjrMqIgo9i2SPvix2YIl4eVrag6dZQj8tmeKwgHGYPDBJBcdNUl/IQLts - BELE97aR4NBJijaT1qvcQhWOR6F6IcXhoYABpB1bxY9ZnuRWKSQEMC90qECz+GlxVEmGP/1uoKTR - Q5uRux3QC8DyLDTroDKd4qnqiYb4E1VB6dLBUqBxolYoPfxBXp9xUXXBuruWO5ra7a9fKSXpiLxS - /Uqv02yed7pzubX5XIOlNawxZVcIucXKZ4u5oCyCsk167QzmUsVF1CvOEtSvlqLeSSH3GRqYy24t - ZM8i/5JCb0n1pyXZhP4baGEvKa3whU8dV1kuQB66nh+E5bsKaHSJxXqdRJpfTjfIQHHEHh+4qP+9 - giWDezTNXDQi1gC2wNwymofb25W/7nJnTKdDuRbdxYn2GnfUdh33xCSsD8Uo35M+ezrqauG1g0Zu - ptnipFlZ2phRMsspJbOcUrRTzrLKDe1aoYb71xPrG7dynxSDkBPLACPOVa8JZjeVmbvDkOjcs1Kd - 0TiXNwxQ+DOeB2RPxnRrq6FodYVeXQYQjc0GUgvz5qLubxq3KsbjFOBjA0nlqouVEwxUC7Ifl5QF - vfhF3fhEBlxqgjYM1vjn2V/YI1nhcLbCEeBFOweqVFNPO0FZM8UuzRkjgvpbhdpXMA578B8QhdIG - FM6dpKXJWMKhQ+rIgn2K1pm8ntAJjqepzwIT9yBxtLX1xJofVIuAVJwa5DhII2Vb6cojhLe1dcmA - X7aba+R8qKY6VOXT8zV41izhI65Dq/C3iYdlrmDW49maBkz/CjxjI9+mbXxLNwHWZ9IItI0oPLry - yMev/7r8AKYTFJXF0FuVclb9vpFvjjxr8qv54b/mGjmfNnL++0a+BHnlY55toTVtofV+C81/6Ze/ - /mu+bjPlLmqKqTCxHdsJXNcVSob4IvAD33Inh1ZAxbQEt/1QzSK8pVQdxy+ozT8V9OiiXo0WkeO6 - ls19ThuFgau8vH6gWKwRwfIVCld4jmz0QjqWPYynVTcbY/kCyZoAGnQ9LsLADqRf15HRaiVHtVeM - bBBNwncces1H0AXbhjVfdaIQgUrlhJblhzLhAK1LATjS2yGUD50w8DzuUcKQ0MnTTcoOIuQRPhY5 - mDHg2eccaebjDZ+mvAbAtFzU4XzT95NIE0AI9zYdubcppAYSqG1QEXh01auvDnCiIC3hSX3LtVW3 - xpHrw+Bw16XXR1mNbicmZZ4CVae393o29JG875ZpY6g52KQU20K1jzBWG3eVbQqFQiJbzKNdXjCl - XyjaD+8s5XQwFhRs5lvqYoLQk/oL1PCCECAhDLRWApMudKCLpH0zENRxOn2xgclyF3jPUxh8lAqc - R5Hv0MYW2l3K/scgb4F39OJ9InilBt36IO9o9kGdkyTFq2NhmGweONLaColgdkFBKEVh6Np24Clm - rkUucKFjuZb0Vp5EjiUC4Qa2pOjXyHO47TlO4NP7Ne6VhHMGo48qXOAz3+NWCIxC9GVo4quBDHcp - /FueFNb+ualteNzcxqtGBN6EuwO2Y6LVo2WhcG0DNSyL7CkhBPlEbHcHr8/1LUBYhD5CcsiatJNB - fOCR7QauDUUsSrjnkRcI4GvgNUr4xCO6LwKJq85E27BkozlB5oeHF46YatqSQ0TIsB0MBQodHyaS - I41Eya0u3e/rBmB55UvUwl4eb/VVCFVBiweu8z1b4tPgYGf4VhDC3JOT6xhKwGQPLe7JQchjHyDF - ddVkgyoBjLDNXU82coD3SAARYD57spFPeP8MWJ94xzLFx4OhyALyolg0GD5uheM5BOkpKtjEw5bF - GZ/cVW3Ji6J9mLjSgLVsi3xS0hhznR0rRF8AV1eWYHS8kldhJEILxIPv25LMT3g5CHTDCoBklFIO - IxfYAJqXJe6ghAMdCECrl9x1xIldHHcb975IoKi7iG2MmYLpawuXTtwEylDF6+AVCnFIQs0Dy0by - 9gVe2AKzAfg3lIQ9BQw8mBmeYwdSroURCg9ESSYUwwg64fiBrSZACcYi4MLjgezEYxj5HEY08EIJ - 5RUK+HYQAl/IsdkHhnNsX/i+kFVG0E/uhYB4wgMFwMxz/RBmoRpxSLBsz0V6Sfk7hBQXbH4YZYX8 - AeJqO0B9CfgrcgV3POheIJs9wkEIucNB0smULtFzr0CnnEK8TVmK3V2YkGQjmcLDhUleui07DGCA - EyXqNWzRDRwYJyGHqIbDCsIdJKmQ3Pkc0larAxPGNeWmqo/7nbAiKK+Ao4QcMpyTlx4R6RNSRTC6 - zuJyu1SQEPDkUawwZI7rcxcWNoM+DeDJUCF/IrTHgCEwGAgAIA2l9HCCcc6BNpbE8COU8T0HFoZQ - duIMOcNxXFhIbEncMkwoSbLPeLFOaFoUXmLiSrAdmqGHvheMSIIFEDAM6FSLwMhZQb5XhU0/BG4J - Xc8B/qCEb8BPAQ98L7RlQgfnqY3RPbTg7wbqrAmnq7Hz6FWg222Af0BMgz6w4dLhigCkrDoyBosW - mblaBa/i5yZ5oVDE4gLgmQ4uKj55XPHac3mbvsLvmSalhSMaykl4TqMnCgXaKS/kgd6mvPvGd5So - QIsGj9PgVwpgqk5wo4M9DnPlleESQCucAlCzPiqjd5yeH6KW5O77aO1cPn2K1p7lEOxFnXBiZ8TK - VGiArhiz8sRUiHPRk7I2ePRA9U7C6J4eXsLoEz1Uw2hv8yH6pj+we/aJ7bHyTZw7vWUDtvYtNDb3 - IGePyTzMeb5lV5yt9SHrE2RhBczErP4t63P2mRub95AjG3ugnNdbVoZKZ1BpHtIZQfq4BNJngtTj - i4D2CdDaOFyENJCQnpdAukNINb4IqC67VFvSpS8SUmkJpK6EdLQE0hVHUF+XgPrGJayDJbC+S1jD - JbB2CVaeQHVmQMFwfGZrBSJfZwYUEKnO1kZEvs4MIMD8O9unYerMgIFR3wMMXvkinM8E53EJnC8I - p7QEzC6CWSuGi3DOJJzDJf2pI5zTJWC+U3cuwkU4rwQnXgLnjuAcLekOjgP0544vAuoToPISQAME - 9LSEbjje2KEGdeh8nnBnbO0T9eh8BhBg1wVOIMqdzw/QExsSoPMZQECEjwAnzxfhPBOc40UwZwim - sQTKAKGsVRehfJFQPi2BgnQ7Y/d8Ecwp9eZhCZxXgtNehLNPcK4XodSpL18XgSChAcrJIpBdBFJb - hNGXfSkhkNa8iNsHwYNAWjNAgC5f2BGCaM3Pz12YAgijNQMDhxjF0SIMxHefDRdhvCKMtcNFIF8I - yMEikGcJpLAI5A5h5Bdh7BKM4iKMfYJxsQiDRpezxiKMMyJWZRFIl4CMFoH0EUhzEUZd9uMSYTQ5 - ALkgPofHe3ZCkw4eP7EXmjDwuMeq4dTN9wI1jBz8vae/n+gv+oU2zxxdzzt4/9Uj/c0ni+y5E90U - HXbqsAuH6WUndxliYEPDyd07BnuAtLzIVZzcyDFu2WkQPbPDIDpjozB6MfuggD0G8PARHkZC7ZWz - SogXxRYCtheyh5CdONE5ZwUeFThF4pUc/cXYHANCxzx36eSunNxukKvzXD1xWLw40XXAnpzoS7D5 - EEZ4vdvmkQN/nvGP2mF/hNWcDsykdtnlVbFnrspJRzOQphDO3Uv0KmZuKUr8NUUZlDV5H01iHirN - cr//ud4fmHhFY7ne7ktIBoZATDNlBITK2kznlKtVvSl0efFdDkPbzHbnWTcMjIVIOZFZI0p8mqS7 - VMif3FD+5HotieZM+UmNn5c3lVuTPi26F+YKgvylQFEd06EmYFxvD+PNt2k5uqvpjW5gm7lK+D58 - /zSTjLkAHpLd2/m7BTcwPmozPx3BJ+jTfTh3FOppZkiKWADL0tmENzaXReE28t+kAezLMEh3RpKU - PNlBfkloLubPXlA0oous8JhZcyZd3owB6FdSGDenhyewpdHKcORLvRC8d0NWb+kuWG92F6z3znbj - XDr5f/IFZpsBXYGJlkFAFrBlM8vYQH8JGQyFIgtN2yWnj2BOclvF5PpZW+7A0hV1cyCEZVETeboQ - FD/ShF8VohMVeGXCBsbQ46fQXBWvYbnq9jfHp6hR16OjXsbMXlmKgL0l8dUjGvCR2Wk3O+XqzEi/ - F4Y0mjBdcxLnnlwuiY3E1W6nO+ymojYPAhmLTHBivMw4DUjlbtLdwexggd0+vsduGbwXRnGkhh8D - f8EbeTWY7tMv+bKLSKNLXouRhl+611geEurthsYK84CuIg0/PqxtPk4mPrLt7AVAjyZ+gBjTD+fS - K71Ov3/cq9/X6WZNNpzLT85ysPESwApuvRo9EFQk8cfUxMCgr5kosd8ND83bxxV3zbGjmQL38UDl - 9ndfzmWwJZQrGjent5tjjBnW9V6IgYNFkbvIHQoMGbzAlW+Ix9kPMRirgGvLhw9HJsjyuDfYjWEm - xvojOzJr9V5/QPgZ0MslzEZi4zLQJemJwy6Nn3tCv+ZY452+Ps7JqmbUnDbxu5votCRFS8VLN6Mo - gpHCram334F8w/joZA58df7eHFBdgUnwuGwS/I2eJjNkT8xT7pN4VyKDZUhFjsJIe12jiwY2NNaN - tLvOYNBpwXMJcnoUJqmxWoizpUaPeBvzeFNjz5CGG+kaG4c4h1TRHuT/E7I/QqIMp9TYGTxPgihr - 9XFchQJl9LIJhu4bmzwilpVnMoTAUQE5eE8FOS59jDTth1Go/mPfyAtiW3gRiYuRPTuWoNs+LBKn - u7vGNp7qJI+jra7zphLyJBpdlRnJADeSlHt7TDVNDjBBGyVOAa9SBtzbnVqn2ew8Z9rAt7Va3It7 - 8NgBeYm3kT9Dj+XRCI2dQ+l///vf952OxlphZHNWjrRfGntID01vVn+YiK376Q7WzW0qGvIUdznT - etalDHO8oiMhlVi/5PrpNFqSPRupYyNTxfVSzoVPaVS6nDjkKcjrXQ7sy9r4z0hjtSd35WBhDvSn - kF3lyrlL+L+pxEk8I816iRSc1r/g+kRefQ+hieQkS9kwW+XuslDg6SkW9kXqHspvlC4LzK3k4SeR - DqQNZ1WFlxDU6WoYvbJSELVA0Qmj85ANeOrYw/SoA2vzSE36F3Po5GHiP/Mdetyohqybyj2Y5sLj - xkvI7sJp7udgkguPG6WAvYZJmOsnkCN34V/RVUhRzJImMNP1Aaf7hTeb4eQ2SexBLYiQhuxBRE3g - hFrA+gYbB9GDuEEDMsSH58nJiK4cylNq8RSyscWZq8v2oBEANQ5yXZ7ATRX7ScT+qID2AwL6ETpg - sG9B1A9u+gRLBkNAVhuB/aJLEGuw7n8LgIiGshJe3LxsPXeHXWxONeHeb1ehU7T7oWysd0JlQgUR - cPm3EKSAwVr08hkmFzfYS/qlSi+n7Mxgd9PH1+nj1+ljL4huzkIQVLlWkOsBQcLcCz08h7lqkKtx - EHu510AFkOe+AuBSmPtKOd3cHf0ehbnzALJu0/qUBgZIaYTRL2CNkIy41V+cJZHyS1lwJAlfIbqP - kOyNCE9KgMZSUbSnYAa64qAhCZtWBzCzgweVcRzkMLwmw5QqiRgUoyuB0U/lHoBnMafFqyixmz3F - Bdx7RVKLrAsw6N9ABuF12+1BMa6Vh00Mr7o0+7Ag4D3S5fuyFDCbGP7+jhp+vVQNv55Vw68XIh4p - 2JVc8XkZdu1YO4LTNWobGDbKXNpPwwuNsRBtdZoC62RL8lYP0LmZZWOsHX6TxZcnU8n/jtfzq+/c - kmKPcZIcdxYD+rrn5I76PZf5k01wB+9IwLBV2i/FbG9PhbQF8tIseSvA9Tshbde/C2lT45Xirusl - 2npPmmfqSlvQGfHAZS6613vB9C500E8mkrFnzvOo/pTi0MlpqWyrSd9MeRjQN1M6Vfpoivxmygt9 - MaVw16FvppSr9MmUvQf8Yoo+OdcGv3gCDi844XKlFeqbxHoSZRUW1a6zX8LLJnBDxZmMlciHdIsd - 3sKe7dIHWPoV+v7KHn1/xaLvrxTw8yv4MQIuL2fx6eIq+jRuoO4IFLssa8s2S3i80HMUVIGBx6Kg - InE91DpwV9bCsy1R9p9ZdhIBwlkkX8bmQEaNfY00Pauxa1DPY421Iw2PRGl4yZSGqiNeLaV1Khre - JaV1njVWBQUBLIwGvAL/ZzR2DDVJy2R5SBsONDbkeAQItIYD0odozxYDu0NpMJoO3vCibtPj9KUQ - YVp05Rz1YW9SFnmewoktx8MvwMqIW/YJv6MCkBvwm4ng4Ym2bncLW7pHo0AfecXrEglOT8NwZbu0 - rdsOk4cJiIwFDGwI5f4yfoxEktsM8dSjIS9DRHTk9jxisQfDJ8NlAIkyAAde09gd9BbocoSak8Zi - UhXBJAuB3nYBv6ryT7uET2CYySd54wE8Z9nprBrwyqXRFS6XpsVQitMSJ3laDFGgPoZRiePiCZXh - AWTrPj30b9mIJ8t0c1HANZcIOJm232rF1ToAn808DXXcYdjneBhlT38E6Jy2PZScPoHF+itfcK59 - lcnXPLlOYrbLI25K3ZN6ng/n1X4wY54m1+nsaJvpoNDplRWRVENz+iWdZN6EnqcLIgSQLJ0psruA - 1Ws4c96G/EALyCUw5L1iIVRKqzMHvyk/eYSKB6EuP1EPlfOoOBRCvchRdL1jCvXSRt/SzpxDdYCX - nJY3n3t1YJclJxMvQiOnx2HuiOdigdeq3XF06MID6ALlMPfEcw3KPea5L/TvU5gDK/gCrF+OR+OG - PJeHMgIP0kEZLJlrUDOQWc19ouag2j3H03RgPD9QCrTbzl3nvho5NTgnuSXYqQ8+1egTT+PJp5rw - Fz/CNJx8hAnLHeampQ8mn2wqpPKmn4wqLtR4pA89LUuv5EYyFd2qvxuT1Koj7dQ7Z55h8XNpXoAh - 73gEG49/4JcSMARLM+gIpfBUeBJ+u0PL5/P7u6fkusnnS+S5yed30XGj5T9DZh6kKDxCzmGkfXIh - Z4ifa1kHSxWSTzRYPTQqdRRpX/O7+X14/Bhpx0UweiONNz+ClRtpAAAkf+yhuKdQPu4xm0KpQNDZ - JG1pYfF2mXYvsVSnvwOHjndbTgk6Ir/nwLQqFvGkUuJ70BFYPVrle7l+bMjFo9ektUPZuLh6VOsj - XD7SE+ZYrfJ35UrjnsLA97EdkgVzNxImRV/30b6nEse/1btxv63Bddxcq9LWwQMxMcwByaWnyJ/A - wdf4wZmv6qDo1xAPiEIWTICTXEfkakJxCjD4IdTGM6XwB/4huw7RUXQIvPiIKXiiFL8mJvO7YQ4v - g5h3VqRuD7y0lymNkJq+RsDijoxMKeAZXQpH1PBgHS5v6i7LvYJcOelWrV38xpKw8WpbuaqpS7AK - dBoHG59RQYUMtBB2AGoNFLbonI/H1F2u8pSGX0p9SGOuiYnqN980fYGD44EPPvY9/JRRsvACwkzz - kYd8dQGdg4qpMD1XHjPCL03JszaiSEd9HDHn8ZU2x7FZaYIYwZmqK+fQNFp8hLSVZ67/1ldipjfQ - z11fKBnvZnQb4anNTbzKEMOf31LMB31f0GNnjt7TJ+OGjj4MjPQS1g5u0/JDLU71v+luGwZkgs5c - BmLoP/tgwjvsCf4K27dCXzA0+W2Gpr1gaMLbnH2ElxtQEeBH096Y9u/ywys6jLV/NzqvL/EraLWb - W+tSVdnekr8Z3OTIrq+3Or1ydWhWOq3ksrkdvCuvXo0IoMezmWp5UF6r1Mr9lzZUoU9ZZzP0lkkc - g1kJUjeyGeUrzSawIW17Avy/AQAA//+kXW1zGjcQ/gy/YitPCwQfB7bjNGCcGTtpk5nkQ2fST51O - RhwCFN+dyL0Eu4z/e3dXujfAdWkn8Zhb7eujPWkl4bsrn0qn6/bVzMwf8NcPngc3aomd+x7pKgHP - Q+qKP1+3Aa5wnAE+QJsKrGYE0ZrUTSILMjZI4B0sXBZk67HvbzabAVZfa8wXClAUQisTKW+WxQI4 - HXA1gStNHXt2W3G4vp+scRmi42WNIiDTGfG+VWmA7LTxo0Id5KgSlglWBykGqgsTOjCxR3Yoeo0/ - 8pqjxaSCQWGfw22h35jnESDmIlUyCVZ0KSBS2cogbW3STHDrIom+zHIyLyCWkWpSJKfeU8EXXC5i - uwV6/pJCc3ukFxf4uRq9x3kSdg/rwt9+qGeJTB5897o6P1MRLjYy5Wsa9VPfRuLNzL03GqzjZQ9i - 4yVqjQM7MKqTstvKPqUYnT7PyiNPiwDS8TrPQOaZQfvrUGUYglksBEAk790IK87OsZPo0ELQcUoB - 0TdRQ7ZMgco9StlZmGMS0876Sqf2/aPTaafT29auOzeMIMhvuR4MOq5yLGu2qifoyUWRprr8kXQv - kCPdV97U1qsb6mCy2Y+iwSXAb0BmQbERW5v1UAvKTsB5lplY+A5XH2G3KehT0lU5elJlYpmlbuSo - IK499E0wS4mGie/UA71qsjYkwpZ2+mztPOAVzACZaIqZ0ptFEG2wPv+CRhE9eIRH65obPVotvixv - IzoWSz0cF8hDoDaGhWOquGiEYAZo7zc64faz0ZFwuXWcRnmqkm4PaVvEkeYZM/uKy9cy/up06ubh - w7wr8JNHMrhcRwFkbr4FCEW7e0REZYbrjrtOD95Ah94x1IExOBqpQTQPCTFnD9vJtyc9kjhwbzzy - C6MUvYGOcSx///nTR1qF/3Ty+vJyOGErnOf/W9vLQhti9ggNNG2xd2vMnVZdumdPOflP5/Ih7YHD - WC+gawl0xZDjvKRQfe0xQdRC1PJpQXxRPTCINbw4u3hxOaT/9BbOnpXiE4P7tU5UiirFpLiYij7r - yMyvnz6XzwziOFot3rzekRSTOkwBB0VOYlh9gdo4tL4T6KOhtcShy0cxxKWOCoIyr2FSAkH2iPDu - N6cW+kDPwnJNgaynobXvzjU6kw67XhRVejqcaLhCkeLLJrrfr+EboKZA/qH/ZIT42Ae6QfE3h7Qd - 2AHMTWarPa1tdBqU37IlQeq5oHpkOLveg+kUhj0o/qKuJm4ZilOlhirC3EnQ+0j3IFOJTNUBzPYT - TIhTb9QrFFQDDI8DdDvVh4EgTXmqOiluYti6m21Mt9qkOKa0y6MJj9C2bvBe4YxKZ5HnZ/ih3SrP - Gosn0SDNTsQjnogjrEHcZPxqyBK4YE0WodmM7ZvIkFKboBM1R4K3UbM7nfFMm64kDq5j+Hl9zz9o - H8gJSJYz2R2e8r/Bq5cEpxeZv44WOpa/ci7Bks6zh7i2qvKw8NR5OoYLjvQwJx3u7jJav5nLtjhm - i/lzXHxc7Jie9+o5bx7bVVZI2GJXyWxMbBPbr6+HPxbl1VmtrhwTbkOH3wh5bAHKhSblnCdDvYyt - oiLXeNyfBCY0yfhksVhYRtqGSXhryiZjw+ExZpmes6GTi/PR28ubScPh8Yrya1tLKTjBMbFu5LE9 - +Mpf7MK7AAVzyEMINWyLQMjjJ3hkg6kWoYXm4vJAsO52pFtwt/4/qtLHSjxa2jXOfy9hQ7M0X7h4 - fYOoDEdYYocZ1uO7ZX/hIfFTjdYs9onKNUbheixtpRs9WNQIslJHA8hmhZyH9UskhLiukIVgkCe0 - 0yWexeWJFQp8iHWgDfuOyBw09U+q8zBD2FJMSLs8SveNUT1Ii0Nn8HcrUVnEyeJfGCrh3zewkIFC - ncr7rufKODPlKo0MkY0WI9lqHW2uWAFW6z4Vw61MMxWGMsauv65aKnIjvuNMepiNOjaHLH/kFnG9 - Szncf0f0o8J5WMWGOtILdKwq4+9cC8wV3GKLuN6lHB/q3wAAAP//rB1rU9pA8LP9Fdc4I/ghAlFE - 5eF0pJa22nZGZKbjOM6RREwbCZMAFZ3+6P6D7t47ISigfqjx7vZxu3t7+0hBb/XOy9tmp21usdN+ - 9fY0wd1cgqDR3XZKk2zk1XSjMQQndo4xfccJbaRWKzPwGpk+OPt79v3vad5GcY6cf+2Z8pVjWZrg - y5age4wf7NF0wYEOojigydYkDpuaGW+aK/B2r01OL8/OTD5gDIcUGzxDW0vumv409xxdTPowBo8e - yj5/fLHyG6U5p4zrUmtWdaRwMwd+jnPDIEC4tAu2JO3PSM7PCtSkZDhqq8V/k+6cLSyLMnWgBbYO - niz1vDZmU5MCGzCqeM5XHSNREp5/rRvu1wQMO0cxbhhNvOzl9oUtXu/KkYTkHjku8uMEpKeeV5ce - R2sDyxAW0nn8J2JCU5EjbynFJLod/6GxPy/HkI5YjZebuFi2anQAiWuQp6SMenps2Xrqkdk1Dc2D - 0zZGrZb5V0ZTy5KROyFdToCzbLU06wtVshyBYTSGiA/1LWrCIVzhMv+sZAvDRqTu+vhNzfU5GY/p - QIi3kYzoUKI1kiJRZ8eUGHFarW+CB4j5AQIA+3ErDRxhLTh49I8OAcDkkBXlW4lwhQzcFEraOTdK - EHUb1U0z9pbB+aLC4TvetfBjA/5OtSuMHsYJ/29Bso2R+KK+xUXkylkR1fPux+amAQxyJfjJVDjK - UBjpj0hSLFakYNmAnME2mufGk/t+YiQMSxiA1VoU8y8BLOP82FYXlr6WVsYmcNxTdzCDlNS2nXJl - 3wac59T9hCOkiCPbaeTC7NmjISqMQ1hl32DBnJ70a87Bw2EZZbnRCG5jrKK9kCsCEIQGgUe90m3g - 3oH77FOscd5wVDc0joM+vfH88IZdPtEOvi4ER4t9Whkkwfgt8RZhtHiOjt8XLq18QaI8f+bEJDZC - RKrP0/5snYin2LXdqj7Fh7yLRfGF8W5Mhwl7NcKdNa1xPOFJIOMOBCraAnCKGncV6RjXUqBTO6gq - F9kDNXYjDy6WEC8XOmKCYtlDRs0W92E5uaqUmChRYLVCuwhnl/kEdEFbw34yqvN/G5CmRMNBGhSL - ZznmxZc+B67JVQ5GYGMlBYTGaQIKfy/gNS2bdP37ETZeKXGIAidXnXa3d30Fgtlxys711UdQ0b8o - NHLJa/TwXCXoKZFAnoVzC80cgewiMKh4xote2T4o+ucqE6W+shioNFdZx4x9zFCnvrC3as28Ncrl - dD9xENNZCmUaN5ZEsLxIvcSGFCgIfd2tnC+cpoqugnylrKtt7Bn3gUywml85tSFlzrrJc1THdt0J - HHN8o3TkDz94SXG7zntqyBX2m0Q7HB/VUaDeFMwfNLvzMHssTZ3SwB/S4wGAfb64rPwsn57WDrcm - 2FLf3zM4MAS6gP83a8Zi7iCFmm3Gcs9C9KUueoKCSxki4fNLDUD+o+rxSoZy5kk+YHsBJDp+rmWm - JL5dN8FYAwXgEBxhPozH4HnBJIoFpZlCGkTdvM+Ry5qeRiF/YyPjvcK1/UR4B1jNM1rgyWNkT60z - 3kCr89nUi2gaX31jg4fmPpYMixZfZTLyN8tRav0ZbJwcEdFi0lCi4YrKKGamFELVAZEuy7QBeUMy - I20W4JAXCLfSZgEOeYFdnYX/AAAA///MXUuP2zYQvudXEM7Bp60tK3EXPriIu07QfaTBerFBezFo - mZZoy6Khx2426I/vN6IkUg+ndtJDNghWlKnhaMiZ+T5ynNDiTIrV+aKyNFsJvZ+0X4n14K+Lx/sv - q/tstn332/OejnzTKgWl/Vpa7ENinqQ2WRhCLSEiOze11CuUrCf4N+PLL5fD5mKu91JJepEHwTLM - lF8Wc/PI1e/m1FrOYWqJ6hMWgvkApaIlYk5/eiXj/FvQCNJsMGXsGron7DOPyhsfMvQtG58EOeAd - A/aLduqJfgt2xZ/kmv0dqlRtNmXPuyyRHi9bN0KmAfuknkU10Ht0R5zdSF4f+pYhi8Sp6XgvYPtU - lc3bzONg+zIMGXsHLJLQP5wo93AmDIpsgvQj2E2M4YUH7YWKfcHm8BdIUnvA9TvEZy94wRW7VkmQ - cTZTACaQtkkCTCH7M3zhEu1FFskQ+T4MaEsMn0cy5eyGI1wFnG48qDgWL+xR+QLKXIsIGJWzhReA - DqZfaSy2CHgERQRAcygqK8ZqnZHRq1f/fbZApg3Fk0woHC3SbA3mxG7RSHxEx2oyqGa5MkWOYgmT - PDxCO48mFUoFMWyDWfoHltvznXk2zrCQqvkpU3zBJQZEZ6yFkshIHRKZ9KfzkO3JZMo8Ews/Fgln - nIWcHQT4CS5Ba0AicSPfFUzplHktPNragJOILV8rUpU+Ny/K5pobkPSDiDGXfAuAK/xMwsAB9yQ4 - jILTUcjPh0ugDD0K6Xs0PKqxkXoUrCYiaOiWZIz7MOFXGhRoVUREHfR7Hgofe2Xc0xAp8rRlwMNN - UaeRdyngywnO2+WBdvJsHbrZedS1cUz7KV2JVDw2ttDLSD/X0My5pP+KvdTMCi725TeBUoGwckRy - 4ZrTsLFL/NY6AHbQbKL6XmXlH2UtyP2luyypou+noCvjYQs+nsZXGjOg22fRV0NciAcMvIKbXIyc - QbBOn0zp4Mahwj2nMkXjOL5cPc7Bqhgk3lOyHcQ7GEaquDdt3TJY60fIVk3RUaXoUc1OZWQd/ToU - ft1QwP1+Sy0kAhato97UDHRG0rdjxqtqhZiwZBEg+3xW/7SZErnsN4gSa/xUFjm6taGjxX+cU+Pj - GY92A3OsMhgOaaJ/2R784kDaVKQeoZgsVfnhcHVgraFcz6Hy3gLK9UbusPF65NTMGR55v2rvtDNE - Npad61aRTodZawT6+0bXQtTpR2vIfGOw3BLY01ZxQZ0fkb1SnkwMl3bfjt3LYluwrftRQQvi9UbK - 2+GQ3c3OF/NeINhackbuhePQxP9aymoLo3UJ6PUQyITN8ipNNpt/+OMj6zr9so2OYEzVo0CeKgSL - YWV7rb8ftsxnopqQWumStYzzhFfEaF024lDZiOu6R1Z3Y3RdWLqkI/iVUrtlKHcYdLOa0MUEI4IT - IAjoXh7CQKrdWkOn0wdIn4X4zkd9pfxQLA9hBkgE5fxJcTmh7RyserGW2f5M2fmrUDFN0T4AJxYm - 12GrJcJAw5b/EAnNc3Y92lgIpwZlLK8bk9f9PzuahSysnxXfqnxLk8JG5P8MGKEG0sZnYIQ2WGtN - TIcHzj9etfyvO4/Q7NS6NruZTbmqGrm7Y7l9reuu89N3ZiarvHsqANYG61XPtDbBGzGfDfFnVMRl - Ox6bi06F/gUAAP//7Fxbc5s4FH5OfwXrPtDMJMGA8WXaZsa5bbPppp0kO53ZFwYDjrGJYTHESWb2 - v6+OkIS4OKEOxunafUkTZCEdnfOd71zkzPRJCp4qK2TRQmMw06Gu4uMyyE7uGV8k4fx85LIh9AEu - KzBjNIFcN5Iqw3s0VG4cUs8YB5XTMFOKi+dIf0rhPhWH8UaJT6mNQ+Au36Zuvg2G5gxoja5I/xaI - Ai05LxJ+mMzoFvqFfiSH9ULcO8hkmsoVK/t410wNkhBEweaVD0IEejQL6yrxDneScUykYST0A3Pk - 3HuUlPxGoJaN/WsW2hYKV1GsasEBQAQOISeiMwIkuQaROZntCS7UqIGpdnBoiyLaWXamkXELeO2Y - E+jiub44/y7cfDm/FvonwiOazoI3MO5ku3RFB0J2osyGn7W7bBMvsSs5Malktp1k3oJ8NFz4/tDc - 5dPS3FNI6BG1xlnq/P0kyvp4Np8mhkx7EFPfJ8M5/S86LKTbTBxlLoWwkam0MFs4N4Blh3mJx1lV - SOpCd/0yCfeP3CtSyVCYdDf1lP0r+Ai9AY7vP3NrCaM7e+wFmOWnI0sJVyjwlTpcLkhCTiJMqdnr - Kl1NZ6FBSI9mX9mHsDN2uB933nHr+ZdfXDZvy+2C+hVOdfmcy09qspwocouj7Fl9ztc02koqqcIZ - BPYx2Os3EqTI+ii1CV8bmHVS5FpeHDBUwHjIW3jGQ45IfgucR23mZPgznOdF4a5WhMr/SYRZqyKP - GWLEvxP0yhA7zEkYW4oNVRB4b64Ue3OBOv6k5yP22gkXQj8xKXmXPmURUTBZpOWN/O2ENrt5oBFr - 5rI078+0o/ZRO3flIHUM4uGnUYu+gBuJq+TzWN4Bcs+uEXCFehm6f8TDk9Pr4/7V7/1r4eT86vT4 - po/4tiALX88vLz5JoxbPPaGFhPE9EUrJYio5CxttJF3/YrEKx/XQKentn0my0tORAk8gmcLERDUG - LTHXuoQTFhpePDnd9BoQe4T5Ih96zQpHqNA2na3rF45sNQ6hIaDwmZZwXbrV5L2xGzLnttft2ZGl - RRJ1/7rSVPTL0x/fj28OAiMQBfhWPPY1giLoocjclCjEX8D1WdQHaJGT5LyuYoZbsK42xx4Q5ZIx - YSsc2SE8Em0D3ooICFJ4//GrSHbF1+XFhADhe/MfFhwvXwp3pqYbWbZkjI0HxA9C/c6zDBdfGWUu - efb5FbLb62nNPU1r7jayUoyJmHjs+Q7iLn3hjxPSfGgHIokAQE+pvvHoxWdFxec02XfMMAqQIo8t - KOjH8zJytgFC/dPxvelj9fK8w/OmZUpTNgSEqgAeua1PjHDouHaV2EOmrBd46D5gn4/Rkzpsa/Z0 - ZMwXHTLmA1voQeHpa+RX3lI2DX5qE+waIahqHqTK+p39YFSJRTDfbIRb+OtEI9gpezXe7LTpDMZ+ - 5x/Zno+3TOhFq1lSgOXNZmPxaOWSXRMg4T9lQCkNInxBotfFsEFC2sQURJY/Zg+5nMQzp/FSaz7U - Z2wdn4XObifrMqEhSVoCCTbfiVggvzK99niPBQkGERIM4uLelSo5ZrepQ54TE3A4uopwnc5ZI6xD - XynbiulJQ+lHS3saX38Zng27W0h/HniWE1550NlMOF+1VNcE5SvhlqqO1moFzr09qxSI5tN40hqR - iGyXvRrvWFG7yvjhcRYY88426C1hPK+UYnkr2kxsqk28awSpCoBJbeuB4TvWrQFd0PC3KtEpmbpe - eErei/YeSpAAkYYDtaV11FbP7tqtoTlQtfbQULrGwLI0S7GMLWiVs6rqZVve1jYWytYp9DUB3C8Z - UCtvO6CumNUqHT2ubdlW5a6DTlyv44jcg9CT5HHHnz659hb1GQBlBFMePTYWspeW2JrwtiJCKcst - AgqBZ07ssMpqCj9vzbjA7wg8sOW7tx15ZA5uw4WF/C1zzFjE8kIsbz2bizd1SHeN2FQxd5GbnRVw - ltBD/6sbmvBL8Sbb0dM93ObqqU/yFng401ggovKKv8Gw8mrZrQk0fskAcluRXRJ730ZF9ubs4u9v - nn95dF7ocY17ZwvLC2uHJYRXHnQ2E7BXLdU1Qfl/AAAA///sndtygjAQht/FBxALGspzdKa3GRoJ - kYII4VDfvkk4KBocCrFhaC+8MsRNPnazS/xDIy0R8tErNbEQgLRqko60B4WemzYizFpKdyczFlrX - 9vqmDe+lFqNYcjFK83v9WpTLwrPiC89KHIc9k+ApMeUugEraPAiiktadQCr5fkAwHfBfgh8G0/cb - eXKPbaASMt8G024lopTr9GpEDrVTkfw6U4XVyXzJWQBmxBMv21BNr+lXEz7uku3QIs/IA7Txbcc9 - B+C8IH47SDOW9R6+VOPjLwbh/WrE15iwFufzG6cNSB1cUIKxNerp5HSMVebwX5apKMtuN/aUOoa5 - hdXdg+I8nLq/98hBxK2pyUdaFxFGrL3cABZN/dwPkhKAvoRZk+s8CfSLadak3eOzGPOeNSG+hEEx - PD4D2NjHURRiF1H2ST73RxlpOKJany3kP1U4DCh5F8P1FWJ2PVGevFS9amTKB14PLSsMkgG0c5IS - lR94YeHXsuGbOOGbkjhjmcboDXM5SBQeTqWbIcKyFk042SRcWyGmwXYjQlO8La0intk6+w0AAP// - zF3/T9pAFP+Z/hU3ddJGQOhmloksQWGbiYoBNmeMMRWKkiElbclk6P++995de9dvFKM/zERbenfv - vb73+u6umM/nlS+bsl81fYgBn6R0SYE8y8Pe21QB5Vai76mgevhGTHZ8HbweZ1XJI5oJRGVg7L0B - /o5YwhP4zsS6ocb/AXgnudp/Ce6Opiz50wPFCloimSoijySHEr7SHEz9MtLZpyOhhkjdo/GjPYzQ - i+Sxi+CbT6mFqwaXTaLasjhTEmI5GlYo8AEehKgkpQRSENTIcZl7KtpRjVJUxfVBfJ4Y3bIgNcb4 - JJmT6XJKxxTiaZHTrEak0OYsQgpdM+oJ0um8AS/pq4BNvtTpIpEVvmRkFopDVAYp9ODdraCmyYyr - Ujxz7FNooz9Ldui992xPyikc3JurS1Ty2VWpj86b3SY76pz1j89+NLvspMmC79vg5LDdY+1eH653 - 29+Oe/1us9U52L03Q92zFNUqsJtMRryBGPKTCg5160yG9Qjo5CyJORmkOIEo7mXfGUVNTfWW2Tpq - m2+R7dLtq7HZXftujC/VXC9OVnU7mdsIdc4n7Q0+aW986YoBvk2Y2gKjmzl5HNfWYGAPFY6klUqI - 6M1ino0sD6QGChXiOx7NwX9WcGshj4MynaunlvwObzBxPPvU9jyYWHVDWjF3PTBj5owpLBGaprCS - mkp1wvPkM4S1lZDHXfEAUQTC9WXgkt/jv7UqeSPOeISMYd4uGVnGc9wj4ARjie/YYrMLPxY08TkP - 1TLEsgQnXxA+ZMvyLd1YclRfhKykW/05hng5rl/idxt+fOzRnFxaiCN17ju+NRE96bzOpSHvEBri - jEAoYVGOccq/wDHsXYMVIdPtESyXhsXAAPyJGNBIDi3XPtVl76iB0e7fqU32J94jMCuwKuRUCk4E - sVLMOLa9zXJGVGCtDIfg1mKD1xzFqtluWEdEtldyRnM/qU7KDkcKD5V3uOhbd2ew/tGLt85wUTSu - qtcvNGw9aVFD+UGkZMOzJyNaLf/qjEae7bOnJ6Zn3jhfW55A9d8J+6A2pcGok/xFXP7l+vL7zixV - PFwX0uUD1Di1/PvKg/WYJ5RcWkoTy1siARNqlIdzbT3c2amKRFM0mEKVa/tzd8qu3qCOXEOkIcph - 0YLN9p/zzvnXTvdUN7SlRhC7F8dnrc7FTfukzRrxslbnXS6hRdd12fOqdr1rGuWaWTXYLjODflDO - +53zVZ13mH7Jykz/WK3CNcMgiNstfWMzXKQblZE1tI+nOqxlUS42yqWwUbGmUOh9W1/yRQdkwr7Q - +1zSiGhuOHcJsHcfWRzgWmGArEa2b++HUMS6gVvBJf551grPoOdZeik6wWlL3GmkmNiZI/xyAUZu - hZlgVJCSdaFLPejlLb24Gd8elEJxRaNCSNXKoCXL1MfIWPiVCMBaIUoo2xsjFqsbcMnC5O3BlWBv - 6vFW+q+oleN4vckYjDsVxv4BAAD//+xdTWvCQBA9x18RbCGR1I9Eo4Wo0MMeCi09mJuI2FZqQEUS - Wyjif29mZpNs7AZrMFZQD2HdnZ1N3r4NmUnYh4fkF7lr+u+wLkMuUdimmtGpKClVdDFkJvtySh8j - n94RPnfs7k4bPiN9LpYg0+qDQkf1TLb3FUJky7b/HCNnYLj7+Y9gRVWlfeCfBPsz2Rc4J/Z5oVcU - WjNS3GkdFQd58xIhF+5RcSET/eKwb10i9qX/RNy+In5ixNtXxE+MeOcCEd/7+HI8yEEGaxfy+7OD - vN0oGnLOb7wmMSn2FgQc7xv4BqG6WnzdUSmISytP3Qj5XZSj2pK/OjqMJiwaEEMN4W0OjzbiaKSE - p7JHdgYM8YBS474/+R64YUQ6HIHgC9S5L+7D0/jRZc9jbFlBxvZxudZ1bl2bT5cf61mlEvV4RbsG - /I2DRLjCgYsyNiQEHumNh5MKIjGkPhOGbzo0eL2G43VTIzueYaAIDqnfRF2Nnqp1515fc5Rf9UkG - WjP4uQ69URheG1ospJlqsaEFXEl8KUlONdXHQm9Itl7ZtOxEJ9LsNLnupHwQ2Rgzq58ybobG+DpB - c2TmAUgkpjq0sAPVSyGpT2S+8J021aPWOYTgRM91GG/DOta5Oc7yls80Dswy+cIkfGESvjA5X1h+ - vrCj8IVl8oXl4As7lC/sEL6wQ/nCCuHLVM4XROhWp2R5pQamQv5G3ajxDcKhu4fpRAxwiB4mpXIU - 5QcAAP//rF3fa9swEH7O/grTwWLDMttL3G5kzSCDgR8UAip7KyWlyWpI4zQ4TyH/+3SSbP081/Fa - CDSW7iSfv/t0ks6RhrzFHEMeL7GQt5i7yOP1XOQt5gJ5lwNvMbeA11hm9xh83I2k8RdzMH5yH31Z - VdUhHDKcDD9rJV/vo8a48Injx235elzD8W6r12Oh+9+S/MHMIIosO7CLriFETdcS7HpfUzBRyxZx - bLuh7XFMBnM5WXTD3cFxLlkqvEt3IlNMG8qL3aZkV5QHyZqNC1ln5qpDakNTAFwoEgfh1SJ3q5fV - p11VbJ9YXIIKZq7gLxbqPEGaZC1iSlxD34SATEWSByhKF3X9dFvUAZaIh9KxkfGQGdEW39DPIHEA - Np+vvCTS94n5CanXY8R31Ot7kPfRbKPq9yzOtEL6Y+MjaLHeJPPGp4hqPQsBEs+aA+O0+HTsj3j1 - tq8wtCKNChyhDbc3pmdBeIBYg9RvSg5QL4IuHFJYrDxsdjnSJEmQgETnRIpzIvVxIvVxIkU4kbZy - Ih7DSj48vUWCFHcp2kqCFPMeU6yNBOmlJEj7kiB1SHBglrSQ3TlQAWoPdBAcHcSHDuJDB0HQQfqP - mMQZMd/gco070ok5c+Y8Dp9vnamc4Lgjl1M5wcCo68KpfAT81JD5WCPz79pN8y+9yVw33/uROc6p - mU7gpAuB/xeLBgaNvnR0lDjWXWWZo7Fl7gktc09kmfsDy7wPhy7zbhS6zNGgJK+t7iZ/ueFIjkQj - SomXTiczp6I4p3FvFojZ194luMFZDX9Fp8emJldivU3fU6/n0HFcbEI257m9TSJY9DkN2PcgtEXv - yn0YRbNwkrFq0ameEE3FbCmdnvn4DKqWOVcVXKIKHvxUoKJWJfrFQgup7RS0KrtOlDIg26mcvZjq - SFd1N6pvRKgjHnW0hzoq1NFGHTwFPosN1InEg3ohT+YXOEt5LW8RMCVr/pCtnG71TsAHXiASFn6X - ZSUv/9jw/2ewgmmoL9UZ6u7qJ7yMIg+r1xY+7VzDlp8pkaB1khBB8WaUQu7hzwT+UulvUBCwBlR3 - jJVto3PwOu5ItmD00K1b7tYPm/J4qJ49FVnV5zGbiVXrv+WhgJiHfXXVqd/1kG2OeA/8CnWK+gcA - AP//pF3bcpswEH3OX+wPLAYnZNqXzsSxc+kkrWfsybtsZIeUIIeLe/n67gqQwYWOgJdMjPZIR6uz - y+KRcIebZBRuc+pwYjJW9caeBJZVI+cok2xoXAxUvokkinhPf/UeUP0t9heDMElF3yqsqEg+Chmr - FAOJWxJDG6NFacO/mX5LNtbEzoED+BlXIe8Fj9WJ30y81b0FT7rdmts5cBS31+C/KwkP83IH8wB6 - Mib4id04weFljel9san6NNTlfBi/y/ko7x1rq8pnsJQ+rVXjtco31Ez/BkOiogEf6UiVJUS4JX6/ - c8OA2D3DjaSXyiSUrVllpVusaRXmA1a1YNAIiKIvjoGjWdyeRBoR0JdLXV6l5MteB+mqBTuA21su - +bBny0p91S1Q/lC8Na0CZphcDBNQQYvvrKnquD+V/G5Lk4FEDX4s41Ttsp8iqd24lomiZPtO1MpT - I6vSxJpiBWiLRgtK1Y5XEdVjkTPbvNZSHkq1JlXHDhAcPWKF7YIrWqx5vGjz7kSlj8m2XNVPPf3q - skUciS15aqkOFGiJ7F+eWbsnVhkfBkqNf75VF2z9UgFGpnBdlW8zZYjcVhdsiVSAASLZ5CyKU4mV - px+5DATcHEX8hzKdNYd/kCO9Io5hqjCSexEZdjd8DZ74GvwmjUQhLYDgWnOZhEehd69YE7bpbIBD - 05Aef8ThJKtnceBeI1jx4S5rek3YSGfupAwMoTv6YC9ybW2Gh17B39hiXTb0ywdPdN94prz+ojIR - qGHZ4MLCQeIoMpGge4XuFKeu55pNwkZ6bADWbivtjeMsOGxERkOlzIM0SfFMckR+llYJhRP66HpM - ULPzmuxmGrriEe8rKMC6woJvT7yzK8fpMxnzegbUNdnkXSRHGaXIL77IUlQ7pJIRQ5QYYTDZigNX - Vgo915vUIkdj4EZjQO1g5Tw4j87CeXLmgLX5efbz6+601/xcH3ce7g+Y5clHHgpaFvdTc1FcH+48 - uF/CujABNrEn2g7vw1HEQaLeJWvnF2kmEnhIcrkR5OVCSO7nJmMDAAZAJKAAWHPu6qAP63PlZK8S - N+EeNzQa0gfF3zRVern2rk56Wb9KmIV7mJElrLVlQyXX9s7v7KqfSs7nIiPMQuaDkl8yR1V3Svqh - qrs9ABYRrLU5LNicKujCfKj2O/sbN6uDTFIalWJan3amFHaaz9Tza3W6NoTvO3gsDcuZOFP7SXR3 - 0msSvo8B1W60EPRw/yOM0fPRm+owPs+uvg/zsPjeY8mm1lTPgYbfXwAAAP//tF1tb+M2DP6c/QrC - G2r7ErvNC7LbuSlwa7dbgV0P21oM2GEYFEdJ3SaWYcvpuqL/fSQlJ85bmxw2oB8chaJJiiIZm3p6 - aBrdGN+aRf/CAf16Kk0K/T9m0hn+Dls130cc2X95mfqQhZzyo8yZShPzTBPDXKriW7kqBGl/Yanw - An4WcEVU+wu2k8MhwmIAuFXDYaKDMg3mibiTuGdkgTsIy5tViXGzGlK4SYFJYUm6v9g72Ry2XXSZ - yjILSp1gnSwLqkK6wby9ViVdI9VNBjeWCogKkGp/cXdyOETYmM6VYjgalfoxGGIRcx+orAiSJGj3 - gnabhO+sb/JznEPVwAXOge9pDnzKCri83F/2nSwOM/XoDjkrdOVCprEYyRTXO2i/pfKPrLEq9gUT - oz/WiMG7KuVcwftylCh/f/l38jpMftqQ9qnSiPxdzIaY6qh4/c5Yvru5Ne0jIvq98xPT7y/19umH - CEwVxoOYYoCeoMRiVCu6u8FJf+Ex/eCka3JEu7Pm9xgGfjcc0HyEylRL0Id4/y4+B66ADYHBDBOc - KmLM8YH3j8zRqUR+j0VUkutHf20VBPAcoMdoZg54f+AcoDlg5+yvyk5+NVUMJv+Lqe/l3Lf6vvRl - UpU9WvHgSj4QvhyaCo5oPKIw820I1wp/Y8KUPYlOueAF1hcyn9Nvz3Ap0ikh9wD3zw0cji/O2Ydc - 0LMgwMXCMEvtVHlKaZZI115vvqIH67x4BWxf5S6x3saL97yvnP5YHuHPpdDyXKn7RHqpmMnWXExL - 2RqJx8Lnd/vgmevGk2nXGBEMzwDQpeCC4AX8qNGgsbCQ+jqZSY8/TOwHv8nT33R6b/on9MeNDDSH - eMm/swStSK0fUfVh4DSZg1YfPl7/pnP0d7rHc4MhVdZmOVFjgRoRsxIkGqrRdJAPq9K05E28RSb0 - 7eDYiZ4X+hMKQU17UpluQdc//GJ5QROQW2SaVQTUkEnMLcMiw4TkuZGLcq40sMApTrCNMdy+AtaI - MXKJxefkTzTEw20yleDFYXwr8vfaO/EHAxdc3xCFRTksjBXarbhqsokavDJxyOexPo09I7APA8J2 - qZAx6pMNgZ1fZ/TcsNRpOZ3WLIO1RCHXTLPpLY7TCtp+9LwEWTjNGAiMIKYCrbINLDkYTlV8T1BF - VaD6msjOzBEFeyLBhIEMuS2rTt6hQaFwK2Foontwl0xiXrxj6KvuVHXpdhatY7UOuYBazd4RNBqJ - YIVeKD0miEXGmEB1ywFKygAZIQka1UBkODBGpg0kJHxZrx5uxyKWQzSSeeiHqypz/l8sJfokpk81 - kje/Xp4rDN4pMvNKv+kc6e3fafou+2y6JejcwGB7WM/26LUw5Awh6rQcIxdeaKWmQ5EPTlqFFros - 8MIcUul3+hYjZdDr9h0/so4yFrgTa0u+LeNsmsBa4GiqozKfHk105IBKYwOVVXFemr/2xHuWiVwn - jMb5o2XrvNDB9eUGMr51XN2EAbGqAzu9jm1M2S7PWf0p7Bf5IsGPVK7O//3HWbWqfkg0BvelQf9T - na8td1Z5l86SVLaURmPORruU7vQWSncZMW4NYLE6+GnbPdkENm0tlCKsX5ElRThRCqsIVuuuOCYV - CPElvCtQxOIxjTEtjzEXPqE3TN6BKwu3FpNWGqkmQUb/ZySVDuUygeVJqjRvczqmuhiuDmd13y6K - CKssYaBhWULJ/pUzlt94bshruQldI+fUwwdPBg+IrQQY7w0Qj7k3fuzxR3IToG9rrWc8A6MUloF8 - iVfH0EFiDKawTmz4IXVgz5z5lhh3oiHGGq7gKIeDKtMFD7o2ILRdaGI55tq44AJmRCuxGbe2QjLL - 346jLERN9FYsM04K8RdN4M7frxr1UIpCtcC1/u62gOSh1rmV8EPQPo0lts+/AAAA//+8fftz27iu - 8M/n/hVZzz2VtGZVUm8mUTJ+Ns/m1ebRbM6O4ziJY8dO7Nhx0vb+7RcAKVu25Xrnm2/umT2NLD4A - giAIgCCkot2Q+Ct6TijYbcn8TNSgWrt521TC3nwadF4GoLF1O5jTSE1Q5+9h96WLOochOEbZ4ks8 - UAZtHN4Ftj9+CysFdsaXHtX+YahKRIXVlUnXTBfUDSpQP5ih4aiXCVBmNG+MRHEF5paRE/kGMwDf - hgG/jV8A+r9t/ASYiWG1yL+rKylEMLcTUBXerRi2/Un9l5YOc18RU/igzDawMRIQWhtQRL+vG7D6 - GiegdE5SRa3QdT7KQtW/+6g6mCSpcjFJFSae+ld/UK83+n3obtIS9DPY8PoNlW0KVf9au9EDnSpR - nV8GK0gLaNJYSfJHggX6xx+Gui6XCRYTQbkqOZaqgalSxzUomHYMeI2cWBSmSXmu/vWvdKYr9Tk2 - ZMxaB3R/BlIRrOf/wuBamvJuv4mT+veIjR/Bcvivf00KYrNPabzVwsU0XyZ1BU9TFd/GFdVKUjUB - nK44t1ByhesebEZ75IuDn1p256n3fC5Zm/ACOoHfoL8M1HY/2fhvQEGuv3QxlAXVAIpqhZJ+3Oky - oFDzvQZ2HP6ghZvLT4YFHeIiT716y+dylCYstTbTy9CYWYbG//MOBvvAw/Og0XuzH7vXTcooN8AN - YeP/EPL1qN9ugkVoPzY7/2ew64P+S/dxATjavOq3tCnGORKWuUUCEHn3Qr77hVix1Tj8vugXVpod - VWb9aN6a8EKbDHEcmyYfObzAQmudj0TB2YTfYYlJa9UMXNuvCMZHQdXaiIXtSrfibgrbc6KKu2oK - 4dostHlYcSzrwwfsFa2eEqi9YPlgv0J4zPVtaz2GypL5gYW9iyBgAXQPT1EIvftgQ1qEibAdWXGZ - 42ALVzLXtUVFQKPADoKKw4SAdq4dVMQGti4wT0KhK2xmfDOgR99mOJgKNIdiv7oJ/0oE5Hg+C7nt - QWcLMK1WWRBY68LxNk1pSwnQIoVjUEUK+ECBwA5FxcFOAxy+ZwcwdObaMkIK6CF4DMsBhdBD6gHu - HPD2rFXAQiLalZD5EsdgbdKEQk+utF0gtPD8TPQEkhwgSQ690gSJsMiMzWcYcxhtxGbkItBCUZFX - AKFsAUi51mrg2+umcABHmkjhE8EC5tHYHN8hgo2xD+1AIJ1t7mLzDUeoMeBYPSzg0KfphCyUdjaq - TmAzHA/Ao2l37QioA1CKVYDsRTihDK3rVVNGhJVwPWsD70TA+CPb2gQqrLreOkymCKkl4SyEzzg2 - sn0khfCEnSAd+XaoRlcFxnHsAABueqCx4tAlDlC42IPn2xzhCa4mlpdwIqCXa7CEW7/G6+Vodr0c - za4XEXjM86z1yObIEMTJBeKXgBMuwg1xRpECfORFiFtUARwi4kHmRnYEqED9yEWWhYndgDkOfVhe - iKQDPMFtPyKWD21Hse3RNLF9HL3gYq7ANGUAnYahRaukSpThFvBt0Vs1PVsgAYOAugXmEXak6Azz - gEMpByALYJIjhnyjiAwLLwNMiFNme8AYKDsct7IZOjYtjJC4SK1j5EiiQDHEWeCwWpGJAsXzMkgg - hHMQuBohn52g7dkJ2k5PEGC6PYupS+zhSpJxURHQCAkJCfLJs4lOgWTAMThpm7ncKuiAMIQN4FGa - S4+kkABJExGnSZRfIJ0YLBBsYmlM50D7ikWBW2FRhTjn6zQnHiwlH9eWWrIcwAgQucAY8A6IFrgo - /LgudzxOBCwS45YkA7YBjuG24yH7acnMQlgTVMGlVV1GppklBTZHFPwC9ljWErkM8K1Vh9sbOF8g - nyMaP5DiIQesAEiBOOS24JOx+nN9q+mCYejpMgb9xgp6rOovxhrO27N/Hv/I7fiF3OrYdDpnZ9YP - bQycr8dnoFbmvkQzNVh7Uuc/Z/9pY6Xy4m4+UC/vs71MKvxJFT4v7gEGQlVuFveRVLn2loD5vrhC - 0sfb4iqaJN8W11Cj7SzH9Av2kbvJMWMkjIV1qWp1MWl+UoWz3w2Katwtp+7u0k7qv+EVqnC7uIsN - hcbiCh+pwuMyNnlcyq/Hy4daWDrUo8U1/tBVXpYxwdvvmIBqnP+G06jCwz9AA6Hk0Nv4upQ0z78j - jWKCxTU21BRe06hQVYIFuYwEJ7/pjips/QZnRYKn3/CU6mN/cR8JkerL+O54GeceLp7MBEh/Ke2+ - LltA+79hCFVja7n8aizlg4dl0rqxVAQOl8mkwlIsBktrfFu+lA+XLaGTpUNpLcXjabk4b9IybMAy - 7C5dZN8Xd6e48StWwOx5IFKXscz2Ull2uhShw6WcW1rOdqNla6yzXJidLUXkaPlUfF2Oa/c3y13V - aC8XKhfLBlxZxnrG28KtX03uaDEWCsT18hXyPK+/seGk2p9nf7b/HGLFm2WsdrBsPLnectKXl1dp - LmeU1+W9VJbyUm/pBl1curi2ad03Yd3XlgnV4vIt5HzpUi0troFWmFrwi7FWSlRrmdCsLtsOa1gh - 9wLDflu2xb8vm81fZI60vUI8rmX9wFeHca6TW0terhyZxLh0yB/noIcca4E159uBJItZoKdJgB1G - RlQxhB0mp4x6l5OdWAgti53ikWiOlePLK1aIwQiyQdqyEj2BbsN24vF3X9Zeem8/EjN3N25fHkQF - +yIqXJkWG6z9YRZicxDv2p3G6MW0LPveK1hr4y6tH2X7adC/Nwc2BUtYa2AaDz98wGLY18xyEjAw - 1C4PIEQdP9RonqkxjibkOLd+7MTnQMyHqXclfLf2YCYQ10bQdu0X4F5rt99WfiD6APSPwocPu5fm - aR7rwcTlW/QEimP+0LqyqKiOj2a6MTQsWS/3ve7ryg6gpqesvJY8Tc8ozWCcq+fYEAPacwxmqNPH - Ccq1c0jz2jXSPIfHm0D23McckDw3wJnYgb914KTdONeAFoM4182xEfx4fMrBgHO1HNuPcys59hme - obNKnBvm2G2c2wbmACwLmPrDbvbpL5Blwl5r428F4Xhh5Zh6AtnB9UOj/oKVx7WPaCCqyQ81borE - +fr21Kj0esAF5m2+kv9MtINVT3/BiMvv5x/GlE3+jsZP++OngX7GNrtTLXAmdvIlKD+EWof5whhG - OX+qZwv0C90e39fH7Yf5dlJuWbiWfsEsTs5C39hLxDqRmqCWiA3TYF94bLQN1oBfN/AHfhUMdiRj - Y81gF/DrpXaNS6BnsFOogsdSu4IcbRVy3/mJGwl9q1WPfHmOzYx7Qzny/CKLJCy0MjR+M1hP0hr1 - Ha4WqS+sDVPaEToxnInPxY2Y0Vc9wPwkLjmLlaAX9TlS9iWKjcfuoN8YPAGiyY+b7mvHYE34eXRn - sCL8/fJqsHMvNu62zkr7d2dFg53BrxHUOuDKYehI5klyZqPHjSsB4nNbkovHeDdWTYc8xzJQzusC - eo5dZgwQw8R1SU5PNsS+Pc4NVocnD/7ew1+dMttgdx6ADLAzX/vfihGL0NHj2w7SwODYZ4R+RiZc - W7rovxOCHLWbueMcOqQ5E1xY69LdNInUxwY5vJiDFGoBOGmwGvwJHZgz+Csc8lIZ7Bh+OK43CuC5 - jOgFET0XgKpQ9wFe+fALEQYawtwDZYvwZwRN4U/NYDvIAgbbA/a4BUaAl02DfUcuMdgLvLwGWkt0 - tnG2D1X1EQy7hWdmsFf4o49ZDPYZyzGMwWAn+L7fPx60G32DfYNfeEBusI6MA85GOE3CCZXcFi6R - G7jGVZ7MyHYD9IaZMGPM6NKUuEAW6eB8lKmxC+0Up0qe+KMLBWgjyY/HMCILDwE8d8P0aarDgj4O - KTDjE/QpAuCNwHaEYtuyb22C3CEOL5AfvALAuoC5ByPjseOyE/hXsGYsWZ/HImTPsQhYMRY++x7D - YvkGL112Duh51Ct62e2IXLPcs8kZC+MRDnIDnVqUAcAXIC3bppMM9NTiiQyxEbo+HXRKSuULDWw6 - xAlDWzHFXuyzF2zGXTs59PHId82ktGmkUnmWI3SGomt5PfYlvq+6gJCj1nIJ3dVR4jh2K7Aw8UgA - WoXoQcVpsNh1HLGT2GPvscvOgCUigz3Bn9Bgj0AeAez2BX6e0TEYzPZrLNiFjHM51o8dVgdWsg1W - Bdpx1oUfwHkxZ1/h6ZPBDqGDT58M2ohRgg28qQ2QfM6X237h6vIluqIdct9LaxGlKDYPhZW/l/mv - PF/i9h6IzEMP6lWme1JF8bn97BWg9HWql6qc7wUqjea6eMQuoORkEZr2++1drXY9bPTwU4i0fVPg - pxjXh2et/ZzB2pRc1G95GPDoBtZiOzZeH7u1d+cuqI2aHNbqMI3mIFbbmv3U67508VzSvq/1D147 - h73uU6P38mZjhL45YgNrc3Q5uFodAHi9Od56BfMhSlSS48m2WHvpXkPJ5fGVjsXscvzAFI6gYVr2 - Q7fZwVew9Si97ALQh13/QJh11LWK+LMcf8c/hbgHb1kLhHq8J8xTC7b+jjDLFmz9T1hhEG8Lc4eV - WIEdAw6gBPwYIwhGnTmU7DgC1Oj91N7eU6W7k9IhbIOI0UM87DZvVo6Tfm6iST9Yvj81Uw80Jftm - 25ruvxNN+sdWnzNafSblC0srgAEoKP9oNio4GxWcjQd2GA/yt2ua8G1hHlo6ytQ8ZojFHYyyyllT - mjuguOTrPL8LzPbIJ8zzyBGfRGXtpU5mLo+A/eh4ppc6nqHjZhQ23IXthaNoxIMVqU8kRRELIzoH - 7U0fL7hWHAtHzL13LH300ps/jpBRchiBWukErcse4aaYXsc6dwcvYy1mpW1OBrWXOai9qUEJx3Zo - 6/Bg14w8exN2Tfi9ijZCFc9zfBBxkVY+fKH2GY+EIY63guPdmzvGC+nERZ2LrpugojA8w1O7Bh4j - Wqt+BJuUQ6oLk+qACc93QcCqM2M84wIJjUdFydkN0XBvAQ335mloInjYmWRykuu4sBXiSR8dZKE+ - o462mOfjxuDAngJ0XxW2g4fIMPgIT7tB9SJNYxM2BSADjDyg6AGfzs6zZ2mPiD01Q20Q3OPg1bVf - 57DoKKg+KccVQVWUWo3lv36x55S4e1YigSb/NAY9ilZtGfaNp5E6pyqAykEfkFA/S1NLb1fH8oxF - 6c5MsYrZSUp349R4DBVzrT+YaFyZYEHtgDhaK+E/uzaGkRxIQBlWVUrMJozYyWTETooRvQ8fOgtW - TWfBjHd+t2pSuHdoAPjl+c5N6b7ZvgH0d4G41lrG+tEbynmcU5/xyK2ppZZL/QLj7V49DXWsZiIx - d0HqADFQcbN1pDnYrD9/YtlIzBWZ7fyZpYtP/UlTvJ1xjdfL3ti5Li5Qz136EucWTSPtPLs2fUHk - 5QvQALaax+6wQUPEAdbNhJd+V6ul+OwUue89xWzvAiT7DzVIV7NaPbH86VcLuZtuuILRniYgroV6 - IqPSLFYn5jqbGOHtZBGMu2kRNsPxQgFTn22n0IJdT7vlmAbRih9AkrO+lYe/Z/pvW/8d6r91+Jvu - 8iG1EVCz8VjP8hdyjS5DEJpvwhwmW33bSjwq89zCgSHi8/wQxkd017DQWdhLoQ+7egrWa8I32zC7 - Z6D6WUQ8ggu7aBuUwnmQQMch0bFu9me23h41epKaZ7o+/jyTVkKo+T5a5rs18VggtnspbEHzGPsr - DOEGgaG53hDS4YbmifEozn0cxTATXF2Dm0W5SCNPKHua0eaUUNQY1gHDTgrDTgpDITV2ItKYnSBm - Z+vxx+vfoXSSQgkrv/wOl72Zytuqcjmjctncnqm8pyoXMioXzJeZyieqcimjcsm8nqn8qirvZFTe - Mb/M0LxB83Ssab6b0WbXPOczjQrU6FU3GmQ0GpjfZhud0Oz2daNRRqOR+X2mzRu1eddtHjLaPJjF - 2RFRm5NMPbWu9dTnmTYDGtBeppZa11pqf3ZAr9RoWzeqZDSqmMOZNo/U5kW3uc1oczunRB/QgK51 - m8OMNodmdRa5FgFq6kZHGY2OzJOxgoF1LjLqXJif+fSCe0otuKfE5DpHb8WjkQhVNOUuUvXQthlv - /1/S2/92sv1/Scc+yQ8fvkzv58E4fGumIFIF3lyBp+J73LkCHd8zF451MYvX5ZcEuYsUcoDbxTwK - JsZ5om/PV54xR8UEeqHScguBCvrEQMKAdEyPQic3QOcUfhL8BLqtSw4rNCEkZ74dBSoodQYiuid8 - UDsxfMr0HfLT+ME4zko4EfND9NLICoZVRuTh2cTwLdS3oURSsCfo4nbgKmXYiTCyTpRBow0o9jEk - Lds0AztEfRnUZgqQAy3MU9ZO5I9jEB2vhF5AoQL8LubpjTGxwsPgLhmR0UBUqnDmBYiY72KAoPac - uKBOz0czHmRyzcFUSKOgKFFpo4Mx0AG3HMcnyVGYqP1chflRhLDHjK/kB3Mc5nuI/UEG45HvM3IY - 6PwYW+tjIB1OmReEOGN6Zl2bouGkosLB7JRhAGcZraQQqBgqH92mKYVNEZforCPrI+DjYEVvrhdP - x+FJplnMokg3CaxmOyHGuqqw2hL5YKlfWwRId2Fz5KWNGOe6isgL10N+y5VzFNTLQzSOtA0mkG8x - IFlFyqKdi6iHlYyRLVpPzbn1dJBMWzM1bdGHD815Ugm3xESg3We8CHgg/1K8McMIQ9OHFeVx5d8E - I26TrDeMCAU2AsMVvXYeC9Bjh3MdYfQfLiYy2aVmbRiQywJbEl1wBXoYto0EQjp66FTkFEAOhODW - BjT10PssPBUJ7Kv1TAazS3M+NxDHZy5F+qp5crwqE7QUhasdj7AcpIqPVVYtTnpznsB0ioCzGnAK - 8wxBOLjJeq9Ac+13pEh0MNEnCwin4iw29pqdgbYLQX0rYOKj5s1Yg3vtJ/obuRvVjxbYjwcn6vk0 - NvZr9eQXWJnNw+7NxMw8rN0kRib8uAcrSP3cof5KFfVrl8SJCl7W0fQqRB3ITEQRkc2MAH3IsMaQ - HQOQO5wiOE2J8jVS8qZAsd0UGr6O0fZOQPOG8dEOTLVHEooFvqVcWQNAqqNQGAFC6umBUHMd9Wuf - xhdEu+rn59g4LKnHCmxth+rxFiupx0Oqj4ZKW704ohfNzku3f6/eXMQzW8klCMYr1olnVsRlE1/f - 8/jyiB0ydVZmsf0rdgevHpg5yg/yu/musMAkYDtXbAteo6evfMVu4jJHrfaeTy5dW3/EYw2wxae2 - 9Bul43LzNKUrbC1oe5DR9IAssqTl3YKWhSyoBW6a9fyI54dWqotPmhE/2S+N/ot5kSiUWT0M+JRi - 9MfNhw+fiKt1445uvJPVeIeTS0XrJzegnxyk9JMDMhwSwfU9LbiKicz6Pq0DfJ/XAUg9mXkf0ns+ - 995MySP0tQFPi03ju6G2QBYJdYy3gZ3iTQ5Bmxcxv1ulixhKWoTpZd6Ou1yv6AnylwD5KjHKjv20 - afnJ1GcLKwIk6c/kx5ev9NvSdE1MuGmrs62tzke8aT/VV2SLdFeB7c721MroqWWCaTrb03Q/zmw/ - pxn9nGb0E073I2b7KWf0UzafZMoYxljtYopjimmN9jzI0k3g7VQ0P/6e8Wipew8zBTrWPgpt1Kki - FWwfks6BtzVIjWO5rRwxgw/bJIg90AJBHwzoRMtzKbpf6WbSpXa4B1Ic/QwsgbCknHvPFQ6+ujnl - 0SGXG2w6Lt6LcMiBW0CojlQaJV3ysDZzMZ3zOYKjPuK4JJ8DFNaOlygnjltgqCaTauJyVEFA85Fp - 9ynRNC0mAburS4M8ksZV2sj4npqS7xNjJJUIBF+cxR/Pk+wf77A3HZDjzLQ+dWTSGQbcHMiURJAT - y6Z2O6BLp7ovfVR72e/V/4xztScqzF0le2vaT0r38U4abbrIaFyhCNILcctDb0yZT86LxsLpzR56 - hc02elHtXuMJEwybnzSYT3fs3FqlMkD4LJogfBahCEvH3QyDLDfrMMWVAphvOMMQnMSKP1cgyYXu - KPMFb16USyzEM00b9mq8RofGBvIZD4Av0CkOmhEwr6MmXSvJ8FRGzkzuAg3n2Y7UWVJxiiwKbK3Q - VjTPeCrWQKnRoCHgWgi5uu9i0tGsBwpvRWlDjojQFFABEVOCUkvJxIGJJt5k2gCpq8nirmeSsT5D - xnowI95dz2aSJ1I8lLa6d6NOV3Bl4n06V19MoiuDnqOVz6I6p3a5By9cjiQAowBWCR08rLqOjbfK - cMnQykS9KUyWFF4vG0VFABn5dOqyCeaah0c4sImgJBB04a0+P7m0e9Xn5wM7ntHs69MEuaxPEaya - SbDqDMGqi/iuugC16m9R08uqBMsqhVgV5Ub96vKbuGJnizYf5WY/uW80XvpY+URcXb5fXX6GP6/i - iramJMeKtZYEnOEG88fkOk/CSL/acTuV4OaVTh9H6HlN3MavWic9Tcs3Aw+LQT6AfnMan+rz4lvY - WROaluNjVoiT776tkcscQ+FYwVor4yeo9Pi/w/hPL0EzVJ0bSbIYA2Dcd/svxpWV5Ugcakfi2BWf - DHPiClYRdlD31y/WTsmddpTyCs9eKNbLLPdXbvfzd3H9+IXXzuRgt9S6a7j8Cf6Gf+VyU8GCrUzm - ac0wTyuDedBc5XijFgwsOm50QyU8HCH16gC7kKyjAK0GB6OGpLVpRAZZDHTf0XaVv6W1gAlb/2h9 - lDMHUU4NAoy88rw6YBIW66AaOmrP5ngSGaJfwUGnkGf7dHvVkVpCROh+iFDEenTRjWwgLWcdVxns - ZHj6RTKYaAtWcTxApTDUcpJsJ58E8gxW4+O18vzAJ8dr89phyabb3chVNKszErY1JTBqmeSqzcx5 - bZHAqC2Yq5n3aEFHnOlTZmvd8+kBL/OSYg3kDMkURe0JI+3c5NRaKD5Sly/LJXQ+4H7m0ya2jpFE - ziZY4w7edw1CUr4cik/SOvocf5zOyM/aFDkameRozJCjsYgcjQXkaMzP4Lz8vPOn5GcD5efptPyc - VpZbM/LzVMnP/tWl+VlYiQQtL5KgrawzkJY+A0HXeStuzcnTCxByrVl5WvrtAfW+wBPQtqq6k1H1 - K0guPBCFuhlyuQVASnbq0NjcsdKHyuVg/lC5NMlNlYwN18WCs1eo/WtayJ6lDiXP+FT4937t5d6+ - bXeBYZAe71HBpFe9Glg5j6bFzLOP55aVP4dOWTOl1Tbl5Bh3HNhzhqqo/dJN8tqlKKvtvvF3Fdvj - MdX1ucFUQ7VvXUjLBl6u1GAoU5sMac/jvs7HfQ3zGMw+/glI4sz/Yv1JMNhK3zP19QuFUm5tRR26 - t2LMg6d21Fxn8Hjd6KmfKT7FDW748+ePX1ocTbNbsu5KmeuulFp3pGDSxeegCLIABCBI0wonPx7K - U58kcBCRYmqTqLY5GEModsPQxm0GZXIJBW1p3ugjY3Dmvad9f47ngiTSd7xRKlGMCujekTozUPaU - 46IDMwwzAJgBOtSEBxqojieu0j12m0eod+b20J70AtIVSUNHf2chIiCeSGrQ/rKOyq1Swh1RVngI - 7Z6I7Iiu5asYHTm+RJ1aLIDYlTaxk6U7tO990sJx1+jewpv4FEag/Tlpc25nnNJxJ5XPEdn4FNi4 - xM4lLlXVYbxDfoAS9ARc+u1rSTEq9EqlUy/xlL4dN+aT3WmZsRuf5Vv59liED5BVgBt383E9P6Aq - o3h4ORh7WvZBko5YolBRxVZ+BGxdoHATVk/pUPUoHQcwpZ6C/tY+AeOxdte4PFNkG6aWIbolvqcW - +HeJrZLCdONzkMOsm1pRXS/N/IVM5i+kmB+2kMICni3M8yxdrC/MbzkTjlDiIBebl/9Zu/rTSoJp - jL/++m8xVhzNzdX//Fxb0aX1tOCGzq/sRxKYyB/HjbvK6Mkc5s8nRrN5+Zf935t/wsL/y/zL+uvy - r6u//vrr01/5/1xZYEi3LYy3GQu0zZvG3OTXL1+vrNXJtZZf7DzlcDgXSirjRjahepkT1+HMfwYe - OLdfandfMC3lmZW+YJE8QR+pPYEuUrB2akbbiSPiNA79cYzXYOJ7b3QnnvebxOuOgdwRxqXR7QFS - d9UaTdQWPHOzmTFUYflKHlgJqxsN3dEgNh7HfvMkjuwhNnq1sdecrYw95o362GP+YKwdcrMuWZqZ - 0SeWGqv143zRbogbF2wIdRlDL3eRaY54/kXSJZLvPL+f3+X5PZl/yI/geUfkB1i4i8/5Uh5vexzz - fBkrjbhlTVCY2Cm16363PXhpjM8/kpC5evzVs/tdECppxNNGHjpQdeTVGfqj8kWeP5sOxULsydHz - xzgoaQutpITVrj3zB2VZRCXm9iVvNjn0YmHSKngF/+aHOkPW6nTP8F6lLpzGYEgJvhDZ1faviZP7 - 8grRGIqpsEOpYruqKelTjcyx/fgKQrQuM6KZ1379f5hPdD8J68dUoONQ0F5/l0LoLmVSwiDQPGwj - Iyz0rBXabXKusYxJO0cipBSrlOA8TGlYhzx9HQugKsY41lyhQ6EnkWCHGDfNzpOUtRgucWaeXw6v - 2BDnX5Ozg+RkY/kB1drqalsdcAK153Utjc9WigbAMCnpvJ8pnffTJgGI2/15g4cy2wQyOfjlPnqh - wNChOzMYt+uoaFvlz11HsW1vetGq6XKdM6uIWY1kRI4ptJY3nw28ZuEkXjX0CkpULSK61cAcvKEj - AibVmTulW3KlrU5yS+idcjzUGSJ98kduQZ8SZDFlgs4NQzLQRtZV3K4y6NF0R8Gl0jDRlZJ1PvLw - TN6hrFGBg1mjlFEG9jQl/6LkSbaHUI0OJW5St2J8sqq1rcbn4HNlAs/acLeZU3I7bePfztv4FMQ6 - 835sZd9mbJjRLORRJuTRDDOMZuxDL7EDZwvcZNyjfzTuk0zoJ2ktObA5EBS1Tcf2fGS1yPYoZtp0 - AmKAkFyV5KhlHiW6onxCIaYHCrUnN2S5nZylAiMwuMUjT6rpCca1U7jiJ9H2lDgM02MB+5xk+FVM - FUSg9kCMvnB1BIfHtWvFcQFJoVPAncxPD6UEIyACI0D4JoZKCLVyhFsgzZjc4g4g6EsdIe9JDCFA - vdhHzscjmfnu1fF+5OB1I7VMKkU6MRHkrtFHLFKncSuF0GOQESDTzZyYbnpiyC3PKQHTegyzhLoB - 5pBSURU+DiIsk79IFCJEwfUQBfS/V8nBj+6RAIfQXcRdMwWm6XsqogTlB9pFrnbghyBMIpr6VT+0 - kXIRBa0EEZ1hhWqFw9KOmArimSzQbhb9KJbH0cnAgLV4WHE3Xc6JaGEB2YzcPnQp0VXBOxGZTjqE - iePVhnFuqBniPmYS93F6tT8uWO2PWeyEQVkRcH1kO5E+Bsb8cIGTcEzEbRhPSEco1lwn2aLhLRPN - txnR8LZo8mYLxmsH5LbnqkueeCKNmwjexsBzDFhJAcpYjF8L0BYld1lulNMRUehZJHv0bX4AGeLl - OXMEz9OEfs5Y4rCBcVg8sEgFx0PSUKhAu1wMQiQMNpDgMEiKNlPWqzpCFV5AoXqS4vBQwADSnqvj - x5xAcasSEgKYFwZUolX8PD+rJMOffzdRyuihw8giJp0Gy7PUboLKdIy3qsca4g9UBZVLB2uBxola - ofLwRwVzykX1BNbdhTrRNK5+/kwpSfvklVKZU792n2ZKb2dLLZbWsEZUXCfk5hufzJeCsgjKNum1 - U5grFRdRr3sZqJ9not5NIbcHHcwUP84VTyP/lkIvo/lzRjGh/wu0sLeUVvjGJ46rHBcgD/0gjGTt - ug4aXWKxXiSR5meTAzJQHHHEOz7qf+9gyeAZTTsfD4k1gC2wtIbm4cZG/c/r/Akz6VKuQ7k40V7j - nj6u44EYh/WhGOVV5bOnq64Oph208lPdlsfdqtrWlJJZSymZtZSinXKW1S/p1Ao13D+fWd+6Uuek - GIScWAYYca5HTTCfUoX5awyJzr9q1RmNc5VhgMKf8T4ge7YmR1stTatz9OoygGittZBaWDYTdX/Z - utIxHscAHztIGt/42DjBQPegxnFGRTCKnzSMLTLgUgu0ZbHWv0/+xBGpBrvTDfYBLzo50LXaZtoJ - ytopdmlPGRE03htofQ7zUIX/AVHo3QuFcyfv0mSs4NQhdVTFPkXrjH8e0g2O54nPAl9W4eVwff2Z - tT/oHgGpRmqSG1EaKddJNx4ivPX1Mwb8stH+SM6Hm9SAbvjkfg3eNUv4iJvQK/zbxssy57Dq8W5N - C5Z/HZ6xk2+TPr6luwDrM+kE+kYUHnx15ePn/5x9ANMJqqpq6K1KOat+38k3T901+dn+8D8znXyd - dPL19518iQraxzzdw+Okh8fFPbT/Y579/J/Ztu2Uu6gtJsLE9Vwv8n1faBkSiiiMQscfX1oBFdMR - 3A2lXkWYpVRfxy/pwz8d9OijXo0Wkef7jstDTgeFka+9vGGkWawVw/YlhS8CT3V6qhzLAcbT6szG - WL9EsiaCDv2ACxm5kfLreipareLp/sqxC6JJhJ5HPwsxDMF1Yc/XgyjFoFJ50nFCqV7soHUpAEf6 - tQv1pSejIOABvRgQOgXKpOwhQgHh45CDGQOeQ86RZiFm+LRVGgDb8VGHC+0wTCJNACE82/TU2aZQ - Gkikj0FFFFCq11Bf4ERBWsGb+o7v6mGNYj+EyeG+Tz8fVDPKTkzKPAWqTrL3Bi6Mkbzvju1iqDnY - pBTbQq33MVYbT5VdCoVCIjssoFNeMKXfKNoPc5ZyuhgLCjYLHZ2YQAZKf4EWQSQBEsJAayWyKaED - JZIO7UjQwOn2xSq+VqfA1UBj8FkpcAFFvkMf62h3afsfg7wF5ujFfCKYUoOyPqgczSGoc4qkmDoW - psnlkaesLUkEc0saQiWW0nfdKNDMfBv7wIWe4zvKW3kYe46IhB+5iqJHceBxN/C8KKTfF3hWImcM - xhBVuChkYcAdCYxC9GVo4uuJlEUK/1Y3hY1/rxmrAbc3MNWIwEy4m2A7Jlo9WhYa1w5Qw3HInhJC - kE/E9TcxfW7oAMJChgjJI2vSTSbxnseuH/kuVHHoxR2Pg0gAXwOv0YstHlO+CCSuvhPtwpaN5gSZ - HwEmHLH1siWHiFBhOxgKJL0QFpKnjETFrT7l9/UjsLwKFeqhWsCsvhqhG9DigevCwFX4tDjYGaET - SVh7anEdQA1Y7NLhgZqEAo4B3vi+XmzQJIIZdrkfqE52MI8EEAHWc6A62cL8M2B9Yo5lio8HQ5FF - 5EVxaDJCPArHewjKU1RyiYcdhzM+zlXtqETRISxcZcA6rkM+KWWM+d6mI9EXwHXKEoyO1/JKxkI6 - IB7C0FVkfsbkIDAMJwKS0ZuajH1gA+he1biGGh4MIAKtXnHXPid28fwNPPsigaJzEbsYMwXL1xU+ - 3biJtKGK6eA1Cg1JQi0Ay0bx9ikmbIHVAPwrFWGPAYMAVkbguZGSazJG4YEoqRdlGcMgvDBy9QKo - wFxEXAQ8UoN4kHHIYUajQCoo71AhdCMJfKHmZhsYznNDEYZCNRnCOHkgAfGEB0qAWeCHElahnnF4 - 4biBj/RS8ncAb3yw+WGWNfI7iKvrAfUV4CPkCu4FMLxIdbuPkyC5x0HSqTdPRM9qiW45ScymrMRu - ERYk2Ui2CHBjUkm31YABDHCiQv0We/QjD+ZJqCm6xWkF4Q6SVCjufJV01OrBgvFtdaga4nkn7Aja - K+BpIYcM5xWUR0T5hHQVjK5zuDouFSQEAnUVS0rm+SH3YWOz6NMAgQoVCsdCewQYAoOBAADS0Jse - LjDOOdDGURh+hjph4MHGINUgTpAzPM+HjcRVxK3BglIk28PEOtJ2KLzExp1gQ9oyQN8LRiTBBggY - RnSrRWDkrCDfq8amL4FbpB94wB/04hvwU8SjMJCuetHFdepidA9t+MVI3zXhlBq7gF4Fym4D/ANi - GvSBVZ8uV0QgZfWVMdi0yMw16piKn9vkhUIRixtAYHu4qYTkccW05yqbvsbvlRalgzMq1SL8SrMn - SiU6KS8VgN62yn0TelpUoEWD12nwKwWwVMe40cUej/kqZbgC8CgnAPSqj2voHafn+/hRcfdd/PGr - etqKP76qKajGXTm2MxraVGiBrthgtbGp0MjHz9ra4PE9tTuU8R09vMl4ix5uZFxdu4+/mffsjm2x - KqtdNvLHV+yFffwmrbUqlFSZKsOS1yt2ztnHPhRtQRE2wEIs6l+xPmd73Fq7gxLV2T2VvF+xGjQ6 - gUazkE4I0ucMSHsEqcfnAW0ToI8jOQ/pRUF6zYB0jZBu+TygphrSbcaQvihIlQxITwrSfgakc46g - jjJAfeMK1k4GrO8K1iADVpFgFQhUdwoUTMce+1gi8nWnQAGRmuzjkMjXnQIEmH9n2zRN3SkwMOtV - wOCdz8PZIzgPGXC+IJxKBpgigvlYlvNwThSc3YzxNBHOcQaY7zScUzkP553gNDLgXBOc/Yzh4DzA - eK75PKA+AaplAHpBQM8ZdMP5xgG1aEBfZwl3wj5u0Yi+TgEC7J6AE4hyX2cn6JkNCNDXKUBAhM8A - p8Dn4bwSnIN5MCcIppUB5QWhfLyZh/JFQdnKgIJ0O2F3fB7MMY3mPgPOO8HpzMPZJjgX81CaNJaj - eSBIaIByOA+kiEBu52H01VgqCORxVsRtg+BBII9TQIAuX9g+gnicXZ9FWAII43EKBk4xiqN5GIjv - NhvMw3hHGB9354F8ISA780BeFZDSPJBrhFGYh1EkGOV5GNsE43QeBs0uZ615GCdErPo8kCcCMpwH - 0kcg7XkYTTWOM4TR5gDklPgcHu/YIS06eNxib7Rg4LHKbuTEzfcGLaw8/HtH/27Rv+gXWjvxTLPg - Yf6rB/q3kGyyX734suyxY4+desysefkziYENLS9/51nsHt4VRL7u5YeedcWOo/iV7UbxCRvK+M3u - gwL2EMHDZ3gYCn1WzuoSE8WWIlaV7F6yQy/+ylmJxyVOkXgVz3yz1kaA0AHPn3n5cy9fjPJNnm8m - Dos3L76I2LMXf4nW7mWM6d3W9j345xX/0SfsD7Cb04WZ1Cm7ShV74uuSdDQDaQpyJi/Ru5jKUpT4 - a8oqKGv8eziOeaCPNu41+y82pmisNTt9BcnCEIhJoYqA0EVr6ZLazY3ZFqZKfJfH0Da70301LQtj - IVJOZNaKE58m6S518ie3tD+5eZtEc6b8pNaPs8v6FX02Ma7KfEmQvxQoauJ7aAkYNzuDxtqvST3K - 1fSLMrBNpRK+k4tvM6mYC+AhNbzNf1pxFeOj1gqTGXyGMd3JmatQz1NTUsYKWJfuJvxiM0UUbqP+ - G3eAYxlE6cEokpInOypkhOZi+XSCoiElssJrZu2p9yozBqBfT2HcnlyewJ6GS8ORz8xStChDVi/z - FKw3fQrWW3DcOPOe/D+FEnPtiFJgomUQkQXsuMyxVtFfQgZDqcyk7frk9BHMS7JVjNPPuuoEllLU - zYAQjkNdFCghKH6kCb8qRDcqMGXCKsbQ46fQfB2v4fg6+5sXUtSoH9BVL2vqrCxFwF5GfPWQJnxo - dzv4yeWpmV4UhjQcM117HOeeJJfETho39E3FVNTmTqRikQlOA5MZpwHp0jXKHcx25tjt8yJ2W8G8 - MJojjVqn23nDjLwGLHd1habehx+nsUFJXsuxcd+o3RisAC+anZbBSrOAzmPDxjZrD+OFj2w7nQDo - AWhBd1vZ7sz7eq/b7x/0mndNyqzJBjPlyV0ONsoArOE2b+J7gook/pxaGBj0NRUl9rvpoXX7sCTX - HNufqnDXeNGl/eLbVxVsCfXK1uXx1doIY4ZNsycxcLAs8qf5XYEhg6e48w3wOvsuBmOVcG/58GHf - Blne6L0U6VOi5gPbt2+bvf4L4WfBKDOYjcTGWWQq0hOHnVk/qsK84NhiwVgfZmRVO25PuvhdJjoj - eWOk4qXbcRzDTOHR1K/fgfyF8dHJGjjy/tka0EOBRfCQtQj+wUiTFVIVs5TbEgslMliGVGVfxsb7 - R0o0sGqwp9i47r68dB/huQIl9AF2eL6VuFpu6RGzMY/WDPYK7/Ag3WAjiWtIV+1B+b+h+DO8VOGU - BjuB53EQ5W1z1LiBCjX0sgmG7huXPCKOU2AqhMDTATmYp4IclyFGmvZlLPX/2DfygrgOJiLxMbJn - 0xGU7cMhcVosWht4q5M8jq5O50011E00SpUZqwA3kpTVKtNdkwNM0EGJV8JUyoB7p3vbbbe7rysd - 4Nvb20av0YNH/CArZiN/hRGrqxEG+wq1//7777tu12CPMnY5q8XGT4Pdp6emN60/jMXW3eQE6/Iq - FQ15jKecaT3rTIU5ntOVkHrDPOPm8SRakr1aqWsjE8X1TK2FrTQqT5w45DkqmE8c2Jd18D8rjVVV - ncrBxhyZz5Kd52v5M/h/W4uTxpQ06yVScNL+lJtjefVdQhfJTZaaZT/WnrJCgSe3WNgXpXtov1G6 - LjC3lodbIh1IK6dVhTcJ6vSNjN9ZJYofQdGR8VfJXnjq2sPkqgPr8Fgv+jd74BVg4b/yTXpcvZHs - KVW6MymFx9U3ya7lpHQvGpfC42olYu8yCXPdAjlyLf+MzyVFMSuawEo3XzjlF15ry3E2SRzBbRQj - Ddm9iNvACbcR61tsFMX34hINSIkPr+ObEU9qKo+px2Moxh6nUpdVoRMANYryTzyBm6r2g4j9WQPt - RwT0MwzAYt+iuB9d9gmWCoaAog4C+0lJEG9h3/8WAREtbSW8+QXVe/4ah9ieaMK93+5Cx2j3Q92G - 2ZXahIpi4PJvEqSAxR7pxx4sLm6xt/SPG/pxzE4sdj15fJ88Hk0ee1F8eSJBUOUfo3wPCCLzb/Tw - KvM3Uf6Wg9jLv0c6gDx/BIArMn9EJU/5a/q7L/NfIyi6SutTBhggFfzYO1ojJCOuzDcvI1I+kwWH - ivB1ovsQyd6K8aYEaCx1TXsKZqAUBy1F2LQ6gIVdvKiM86Cm4T2ZplRNxKAcnwuMfqr1ADxrcNq8 - ygq76VtcwL3nJLXIugCD/hfIoB590b7cuK0N2hhedWb3YUPAPNK1O/VddTCgI3ORGn6RqYZfTKvh - F3MRjxTsSq74ggq79pxNwSmN2iqGjTKfztMwoTFWoqNOW2CbXEVl9QCdmzkuxtrhN1lCdTOV/O+Y - nl9/55YUe4yT5HiyGNHXPcc56qs+C8eH4B7mSMCwVTovxeKgqkPaIpU0S2UFuFgQ0nbxu5A2PV8p - 7rrI0NZ7yjzTKW1BZ8QLl/n4zuxFk1zooJ+MJWPPnuVR8znFoePbUrnHNn0z5f6FvpnSvaGPpqhv - przRF1NK1136Zkrthj6ZUr3HL6aY43tt8BdvwGGCE652WqG/SWwmUVayrE+dwwomm8ADFW88V6Ig - KYsdZmHPPdEHWPp1+v5Klb6/4tD3V0r4+RX8GAFXyVlCSlxFn8aNdI5AUWQ5V/VZweuFgaehCgw8 - FiUdiRug1oGnsg7ebYlz/86xwxgQziH5VujT8gY7ig0zZ7ALUM8bBuvEBl6JMjDJlIGqI6aWMrp1 - A3NJGd1Xg92AggAWRgt+Av+vGOwAWpKWyQrwbvBisAHHK0CgNeyQPkRnthjYLZXBaHuY4UVn0+P0 - pRBhO5RyjsZQHddFnqdwYscL8AuwKuKWbeF3VAByC/6uxPDwTEe3xdK6GdAs0EdeMV0iwekZGK7s - VjZM12PqMgGRsYSBDVKdL+PHSBS5bYm3Hi2VDBHRUcfziEUVpk+FywASNQAOvGawaxgt0GUfNSeD - NUhVBJNMAr3dEn5V5d9uBZ/AMFNPKuMBPOfY8bQa8M6V0SWzpWlZKnFa4SRPyxIF6oOMKxw3T2gM - DyBbt+mhf8WGPNmm2/MCrp0h4NS77cfHxk0TgE8XHksTTxi2OV5GqZoPAJ3TsYeW04ewWR/xOefa - kXp9wZN0EtNDHnJb6Z408oKcVfvBjHkep9PZNNbSQaGTlBWxUkPz5hndZF6DkacrIgSQLN0JskXA - 6l1O3bchP9AccgkMlVdMQqO0OrPzm/rjR2i4I031iXpoXEDFoSTNMkfRtcAU6qWNvszBfIXmAC+5 - LW+/9prALhk3E0+llTcbMr/P8w2BadWuOTp04QF0gZrMP/N8i0oPeP4L/bcl82AFn4L1y/Fq3IDn - C1BH4EU6qIM18y3qBgpv8lvUHTS743ibDozne3oD/XbyF/kjK68n5zCfgZ3+4NMtfeJpNP5UE/7F - jzANxh9hwnq7+UntnfEnm0qpsskno8pzLR7oQ09Z7+v5oXqLbtXfzUlq11F26rU3y7D4ubQgwpB3 - vIKN1z/wSwkYgmVYdIVSBDo8Cb/dYRQKhe3iMbluCoUKeW4KhSI6bozCHhQWQIrCI5TsxsaWDyUD - /FzLJ7BU4fWhAbuHQbX2Y+OoUCxsw+Pn2Dgog9EbG7z9Gazc2AAAIPkbAYp7CuXjAXMplAoEnUvS - ljaWoMiMO4Wlvv0deXS92/EqMBD1PQdm3GCVQCklYQADgd3jsXan9o9VtXn02rR3aBsXd4+b5hC3 - j/SCOdC7/HWt3rqjMPBt7IdkwUxGwqTq+zba91Tj4Ld6N563tbiJh2s3dHRwT0wMa0Bx6THyJ3Dw - BX5w5khfFD2SeEEUimABHOa7In8rNKcAg+9Ca7xTCv/Af8iuA3QU7QIvPuAbvFGKXxNT5U8yj8kg - Zp0VqeyBZ26W0ghv02kEHO6pyJQS3tGlcEQDL9bh9qZzWVZLauekrFpF/MaScDG1rdrVdBKsEt3G - wc6nVFChAi2EG4FaA5UduucTMJ3LVd3SCCupD2nMdDFW/Wa7pi9wcLzwwUdhgJ8ySjZeQJgZIfJQ - qBPQeaiYCjvw1TUj/NKUumsjynTVxxMzHl9lcxzY9TaIEVyppnYOTaLFh0hbdef6H30lZpKBfiZ9 - oWK8y+FVjLc21zCVIYY//0oxH4x9To+dunpPn4wbeOYgstJbWCe6SssPvTk1/6G7bRCRCTqVDMQy - f/TBhPfYM/wr3NCRoWBo8rsMTXvB0IR3OfsMPy5BRYA/hvGLGX/X7t/RYWz83eq+vzXeQatdW/+k - VJWNdfV3BQ85cp8+PXZ7tZuBXe8+JsnmNjFXXvMmJoABz63c1F5qH+u3tf5bB5rQp6xzK/RrJXEM - 5hRI08qtaF9pLoEN7zbGwP8XAAD//7LRT8pPqbTjstEHNabsAAAAAP//AwCNPhQVNvgBAA== - headers: - cache-control: ['no-store, no-cache, must-revalidate, post-check=0, pre-check=0'] - connection: [Keep-Alive] - content-encoding: [gzip] - content-type: [text/html; charset=iso-8859-1] - date: ['Sun, 26 Nov 2017 18:49:31 GMT'] - expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] - keep-alive: ['timeout=5, max=10000'] - pragma: [no-cache] - server: [Apache] - vary: [Accept-Encoding] - x-powered-by: [PHP/5.3.3] - status: {code: 200, message: OK} -- request: - body: null - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - Cookie: [PHPSESSID=r1j49v1otvv3e63b36utuqlnm1] - User-Agent: [!!python/unicode Medusa/0.1.17 (Windows; 10; 87a3c54f-d2da-11e7-b715-1c1b0d9d2a41)] - method: GET - uri: http://www.newpct.com/descargar-seriehd/macgyver-2016/capitulo-22/hdtv-720p-ac3-5-1/ - response: - body: - string: !!binary | - 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 - headers: - cache-control: ['no-store, no-cache, must-revalidate, post-check=0, pre-check=0'] - connection: [Keep-Alive] - content-encoding: [gzip] - content-type: [text/html; charset=iso-8859-1] - date: ['Sun, 26 Nov 2017 18:49:32 GMT'] - expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] - keep-alive: ['timeout=5, max=9999'] - pragma: [no-cache] - server: [Apache] - vary: [Accept-Encoding] - x-powered-by: [PHP/5.3.3] - status: {code: 200, message: OK} -- request: - body: null - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - Cookie: [PHPSESSID=r1j49v1otvv3e63b36utuqlnm1] - User-Agent: [!!python/unicode Medusa/0.1.17 (Windows; 10; 87a3c54f-d2da-11e7-b715-1c1b0d9d2a41)] - method: GET - uri: http://www.newpct.com/descargar-serievo/macgyver-2016/capitulo-22/ - response: - body: - string: !!binary | - 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 - headers: - cache-control: ['no-store, no-cache, must-revalidate, post-check=0, pre-check=0'] - connection: [Keep-Alive] - content-encoding: [gzip] - content-length: ['7284'] - content-type: [text/html; charset=iso-8859-1] - date: ['Sun, 26 Nov 2017 18:49:32 GMT'] - expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] - keep-alive: ['timeout=5, max=9998'] - pragma: [no-cache] - server: [Apache] - vary: [Accept-Encoding] - x-powered-by: [PHP/5.3.3] - status: {code: 200, message: OK} -version: 1 diff --git a/tests/providers/torrent/newpct/newpct_daily.yaml b/tests/providers/torrent/newpct/newpct_daily.yaml deleted file mode 100644 index 39f59b8ba1..0000000000 --- a/tests/providers/torrent/newpct/newpct_daily.yaml +++ /dev/null @@ -1,1323 +0,0 @@ -interactions: -- request: - body: null - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - User-Agent: [!!python/unicode Medusa/0.1.17 (Windows; 10; 87a3c54f-d2da-11e7-b715-1c1b0d9d2a41)] - method: GET - uri: http://www.newpct.com/ultimas-descargas - response: - body: - string: !!binary | - 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 - AAAA//8DACqLx2Kw9gEA - headers: - cache-control: ['no-store, no-cache, must-revalidate, post-check=0, pre-check=0'] - connection: [Keep-Alive] - content-encoding: [gzip] - content-type: [text/html; charset=iso-8859-1] - date: ['Sun, 26 Nov 2017 18:49:29 GMT'] - expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] - keep-alive: ['timeout=5, max=10000'] - pragma: [no-cache] - server: [Apache] - set-cookie: [PHPSESSID=r1j49v1otvv3e63b36utuqlnm1; path=/] - vary: [Accept-Encoding] - x-powered-by: [PHP/5.3.3] - status: {code: 200, message: OK} -- request: - body: null - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - Cookie: [PHPSESSID=r1j49v1otvv3e63b36utuqlnm1] - User-Agent: [!!python/unicode Medusa/0.1.17 (Windows; 10; 87a3c54f-d2da-11e7-b715-1c1b0d9d2a41)] - method: GET - uri: http://www.newpct.com/descargar-serie/babylon-berlin/capitulo-26/hdtv/ - response: - body: - string: !!binary | - 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 - headers: - cache-control: ['no-store, no-cache, must-revalidate, post-check=0, pre-check=0'] - connection: [Keep-Alive] - content-encoding: [gzip] - content-type: [text/html; charset=iso-8859-1] - date: ['Sun, 26 Nov 2017 18:49:30 GMT'] - expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] - keep-alive: ['timeout=5, max=9999'] - pragma: [no-cache] - server: [Apache] - vary: [Accept-Encoding] - x-powered-by: [PHP/5.3.3] - status: {code: 200, message: OK} -version: 1 diff --git a/tests/providers/torrent/newpct/newpct_test.yaml b/tests/providers/torrent/newpct/newpct_test.yaml deleted file mode 100644 index 3554afb07e..0000000000 --- a/tests/providers/torrent/newpct/newpct_test.yaml +++ /dev/null @@ -1,39 +0,0 @@ -daily: - search_strings: - RSS: [''] - results: - - seeders: 1 - pubdate: 2017-11-26 00:00:00 - title: Babylon Berlin - Temporada 2 [HDTV][Cap.206][Español Castellano] - leechers: 0 - link: http://www.tvsinpagar.com/descargar-torrent/98411_Babylon Berlin - Temporada 2 [HDTV][Cap.206][Español Castellano].html - size: 524288000 - - seeders: 1 - pubdate: 2017-11-26 00:00:00 - title: Babylon Berlin Temporada 2 Capitulo 5 HDTV - leechers: 0 - link: http://www.tvsinpagar.com/descargar-torrent/98410_Babylon Berlin Temporada 2 Capitulo 5 HDTV.html - size: 524288000 - - seeders: 1 - pubdate: 2017-11-26 00:00:00 - title: Babylon Berlin Temporada 2 Capitulo 6 HDTV 720p AC3 5.1 - leechers: 0 - link: http://www.tvsinpagar.com/descargar-torrent/98409_Babylon Berlin Temporada 2 Capitulo 6 HDTV 720p AC3 5.1.html - size: 1677721600 - -backlog: - search_strings: - Episode: ['MacGyver (2016) S02E02'] - results: - - seeders: 1 - pubdate: 2017-11-23 00:00:00 - title: MacGyver - Temporada 2 [HDTV][Cap.202][Español Castellano] - leechers: 0 - link: http://www.tvsinpagar.com/descargar-torrent/98285_MacGyver - Temporada 2 [HDTV][Cap.202][Español Castellano].html - size: 524288000 - - seeders: 1 - pubdate: 2017-11-23 00:00:00 - title: MacGyver - Temporada 2 [HDTV 720p][Cap.202][AC3 5.1 Español Castellano] - leechers: 0 - link: http://www.tvsinpagar.com/descargar-torrent/98284_MacGyver - Temporada 2 [HDTV 720p][Cap.202][AC3 5.1 Español Castellano].html - size: 1610612736 diff --git a/tests/providers/torrent/nyaa/nyaa_backlog.yaml b/tests/providers/torrent/nyaa/nyaa_backlog.yaml index ea4dcba01c..2df049f2ac 100644 --- a/tests/providers/torrent/nyaa/nyaa_backlog.yaml +++ b/tests/providers/torrent/nyaa/nyaa_backlog.yaml @@ -5,105 +5,118 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - Cookie: [__cfduid=d31b020b259be3370f989f1bead8ae0851510936371] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; f4209fa1-cbb4-11e7-a59c-1c1b0d9d2a41)] + Cookie: [__ddg_=57258] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET - uri: https://nyaa.si/?c=1_0&q=Dragon+Ball+Super+115&page=rss&f=0 + uri: https://nyaa.si/?page=rss&f=0&q=Dragon+Ball+Super+115&c=1_0 response: body: string: !!binary | - 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 + 0vv37eHtN29e7z59evsXX9aHAwSmAAA= headers: - cache-control: [max-age=300] - cf-ray: [3bf416b429e01ae1-DUS] + cache-control: [max-age=300, 'no-cache, no-store, must-revalidate'] connection: [keep-alive] content-encoding: [gzip] content-type: [application/xml] - date: ['Fri, 17 Nov 2017 16:32:54 GMT'] - server: [cloudflare-nginx] + date: ['Fri, 15 Feb 2019 19:55:17 GMT'] + keep-alive: [timeout=60] + referrer-policy: [same-origin] + server: [ngjit] + transfer-encoding: [chunked] + vary: [Accept-Encoding] x-proxy-cache: [MISS] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/nyaa/nyaa_daily.yaml b/tests/providers/torrent/nyaa/nyaa_daily.yaml index f10a1279b8..1bf1b12aeb 100644 --- a/tests/providers/torrent/nyaa/nyaa_daily.yaml +++ b/tests/providers/torrent/nyaa/nyaa_daily.yaml @@ -5,199 +5,200 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; f4209fa1-cbb4-11e7-a59c-1c1b0d9d2a41)] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET - uri: https://nyaa.si/?c=1_0&q=&page=rss&f=0 + uri: https://nyaa.si/?page=rss&f=0&q=&c=1_0 response: body: string: !!binary | - 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 AAA= headers: - cache-control: [max-age=300] - cf-ray: [3bf416a428f91a81-DUS] + cache-control: [max-age=300, 'no-cache, no-store, must-revalidate'] connection: [keep-alive] content-encoding: [gzip] content-type: [application/xml] - date: ['Fri, 17 Nov 2017 16:32:52 GMT'] - server: [cloudflare-nginx] - set-cookie: ['__cfduid=d31b020b259be3370f989f1bead8ae0851510936371; expires=Sat, - 17-Nov-18 16:32:51 GMT; path=/; domain=.nyaa.si; HttpOnly'] + date: ['Fri, 15 Feb 2019 19:55:04 GMT'] + keep-alive: [timeout=60] + referrer-policy: [same-origin] + server: [ngjit] + set-cookie: ['__ddg_=57258; path=/; Expires=Wed, 01 Jan 2020 00:00:00 GMT'] + transfer-encoding: [chunked] + vary: [Accept-Encoding] x-proxy-cache: [MISS] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/nyaa/nyaa_test.yaml b/tests/providers/torrent/nyaa/nyaa_test.yaml index fcdb541690..6bbb3d4d7d 100644 --- a/tests/providers/torrent/nyaa/nyaa_test.yaml +++ b/tests/providers/torrent/nyaa/nyaa_test.yaml @@ -2,38 +2,38 @@ daily: search_strings: RSS: [''] results: - - seeders: 0 + - seeders: 4 pubdate: 2017-11-17 00:00:00 - title: '[Sick-Fansubs] Boruto - Naruto Next Generations 33 [720p][EA92D113].mp4' - leechers: 4 - link: https://nyaa.si/download/979570.torrent - size: 364275302 - - seeders: 10 + title: '[PuyaSubs!] Mahou Shoujo Tokushusen Asuka - 06 [720p][1FB3C050].mkv' + leechers: 15 + link: https://nyaa.si/download/1119253.torrent + size: 392481996 + - seeders: 2 pubdate: 2017-11-17 00:00:00 - title: '[PuyaSubs!] Net-Juu no Susume - 07 [720p][073ED4B2].mkv' - leechers: 25 - link: https://nyaa.si/download/979569.torrent - size: 337536614 - - seeders: 8 + title: '[PuyaSubs!] Mahou Shoujo Tokushusen Asuka - 06 [1080p][5AF71C7D].mkv' + leechers: 8 + link: https://nyaa.si/download/1119252.torrent + size: 878811545 + - seeders: 1 pubdate: 2017-11-17 00:00:00 - title: '[PuyaSubs!] Net-Juu no Susume - 07 [1080p][CB41FA09].mkv' - leechers: 17 - link: https://nyaa.si/download/979568.torrent - size: 567594188 + title: '[AniDUB]_Yakusoku_no_Neverland_[06]_[1080p]' + leechers: 2 + link: https://nyaa.si/download/1119251.torrent + size: 454557696 backlog: search_strings: Episode: ['Dragon Ball Super 115'] results: - - seeders: 18 + - seeders: 0 pubdate: 2017-11-14 00:00:00 - title: '[SOFCJ-Raws] Dragon Ball Super - 115 (THK 1280x720 x264 AAC).mp4' - leechers: 5 - link: https://nyaa.si/download/978757.torrent - size: 678323814 - - seeders: 27 + title: '[AnimeRG] Dragon Ball Super - 115 [720p] [Multi-Sub] [x264] [pseudo].mkv' + leechers: 0 + link: https://nyaa.si/download/980046.torrent + size: 227331276 + - seeders: 0 pubdate: 2017-11-14 00:00:00 - title: '[SOFCJ-Raws] Dragon Ball Super - 115 (CX 1280x720 x264 AAC).mp4' - leechers: 8 - link: https://nyaa.si/download/978756.torrent - size: 620442419 + title: '[AnimeRG] Dragon Ball Super - 115 [720p] [Multi-Sub] [HEVC] [x265] [pseudo].mkv' + leechers: 0 + link: https://nyaa.si/download/980045.torrent + size: 178362777 diff --git a/tests/providers/torrent/rarbg/rarbg_backlog.yaml b/tests/providers/torrent/rarbg/rarbg_backlog.yaml index a2e4539843..15c5d533b5 100644 --- a/tests/providers/torrent/rarbg/rarbg_backlog.yaml +++ b/tests/providers/torrent/rarbg/rarbg_backlog.yaml @@ -5,39 +5,41 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - Cookie: [__cfduid=d0ef242b77da9a14958ee9374ebe44de01510935073] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; ee483911-cbb1-11e7-90fd-1c1b0d9d2a41)] + Cookie: [__cfduid=d864a98965fd17d1a3a7521c48cb377471550426712] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 92c2cfc0-32de-11e9-a385-1c1b0d9d2a41)] method: GET - uri: http://torrentapi.org/pubapi_v2.php?ranked=0&sort=seeders&search_string=Lethal+Weapon+S02E05&format=json_extended&app_id=medusa&mode=search&min_leechers=0&limit=100&token=l2esh1av76&min_seeders=0&category=tv + uri: http://torrentapi.org/pubapi_v2.php?min_leechers=0&sort=seeders&ranked=0&token=5632edhvcu&min_seeders=0&app_id=medusa&format=json_extended&mode=search&category=tv&limit=100&search_string=Lethal+Weapon+S02E05 response: body: string: !!binary | - H4sIAAAAAAAAA+2Xa0/jRhSG/wqyBF/KmjNn7pbQCgTtVqWrikW7UpeVNTcTi8SOnAlLi/jvnYRL - QhdzUekHUCzHI8/12POc128usth2XWhi2YXJdBgnWfH1Iot1HIasyA5CHJhh/iWYcdvknwD3gecf - 9o4+5+co2Lvffj042D/89LUzXTz7lm1mzsRw0nZ/paFHn9f2x/Wk9WGSGnz7vRm2xqeGkTlpQize - n8ftadcUNtaDAipGmNfGGsUqFxQE4zxY7QwFaRzVQTLlLN3wzfbTYlrnu/Oo1vneRuy2BzGO1+nO - Ov6cztgZdxq6/Lqs6vPctaPUrCC1mqZpp40Ls2FTvxil8zShPclHIVWhJNDXIbY9HdpxaHIfRm1T - 19crEkrl0prpTU1C8KFL24AENrNhCG4wvyUitdV/p12hhIDkhJLNbDy1Pr3y9FYRiHxHyDtQa4AF - qILLtZ8gHWnKcLUPZd1UbVZcZPXI2zQkRk4EI1qkLvGsMydpnmY6HM7u5h3SQlLPJoiDFPRZHea1 - QhIyG2Lq7t9ry/lizXSUKvn8Wcykba7ucTbPAqu1Oq4d1j5kl5tZZ5rTkNBIDzQLsRzPQ8lmezYp - jreOt64RNeM6b7uT460u+LoLLpaxnT9UPh6M38f2NDTbQwyTATFnUmyMt0nJSihVKdOVl+WCsrTq - I5BLhPHTSf+w9wzYpVNQSbQaAqWAnnMmhFdeU+OVBBOEQ5TM9MJ+f2yvn3jC6P3EE2TIJEdCH0Be - pAEr5JeRp2W5YO1x5AmoxNWX/d0rrI52XwZ3ZXlFpPLSWKSWSGmQqcpZqJAFRAaEh0qC6sX9x7je - AOqIy6gvSBeIAoQC3kc6KTgrcCXut6SLUqdrucDscdKfwvgzzIvQRAUvCEdVeWs89UC1kELTShkk - FrXFtLG9gL8xtIHcizYVAohG0WtbEtlQIFuRvUz2zLbc8vVE2/LiEk5kYMxqDiSVjloRdLCEsSoJ - Oa+MslZwpW142LG8Lcx1j4CnrxVRQjL9AOakQLXCfBlzUZYLyJ4k4If1+Iqmw53D3V/+g3xLSLLk - lNSGMVA+HcyjCswohxyNIdYLjVW/Hf8hmFdKtNR33De/FW7N2Cy/+8w3EUm1C1gJ9zXRusRUkmS+ - b8l6nOhUmdcxn4V4bXh3fv/z4w1be3t/JB98hdjHI/sioq6DNEZX4EAa4qoqBGoIw3SCYg6N06EK - 4EQv988K+fULvrjz51TdZAcKqbWSXLP+9ABesJXgL6UHTWW5APB56TE3E/93dlSEW6BKWUVBEMuN - APCaO2CKmIpSA8Y6XvVbnudE/PqTA8Wdb8etG+IUkFFE6EkOxAIw+f5VctwkB53/ygV/2eW3y38A - tjF9M6YXAAA= + H4sIAAAAAAAAA+2Y7U/bRhjA/xVkCb4MzHPvd5ZQBSMbUymb0qiVVirr3kwsgh05F8aG+N93NpRk + LQaitR9AsRyf7v2x7/e85ToJddP4KuSNn80nYZZkn66TUIaJT7Lk2IexnqQfvZ7WVfoe8ABYenQ4 + +pBeYU533v52fDwYvv/U6CZcfk62E6uDP6ubv+PU0YeNwbSc1c7PYoer/6omtXax40KfVT5kb67C + 3rypMhPKcQYFRdQpbbSkhfUSvLYOjLKagNCWKC+otIZsuWrveTJtsoNOqk12uBWavXEI002yv4l/ + iXdotD33TXpXFuVVauuL2C0h9uqqqueV9e20uVvMUmlc0JylFz42YYGgb0CoewbUU1+lzl/UVVne + 7YgIEUt7xi818975Jh4D4tvJxHs77moQe8p/4pkQhEAwRNB2Mp0bFz94/KYYkNhBaAfkBuAMZMbE + xk8Qr7igvz2FvKyKOsmuk/LCmTglBIY4RYrHIeGy0WdxnWo+mbS1bkDcSKh2gTCOIl+WvmvlAqF2 + ii6br/cW3WbV/CI2su5N9Kyubuu4XWcB1UYZNoal88nNdtLo6txHMOILtSLm006UpD2xWXa6e7p7 + B6ielmndnJ3uNt6VjbchD3X3Uul0PH0T6nNf7TFOsHfjSzvfmu6hnOaQy1zEJ8vzBWNx1ycQRyBh + mn4cHNwyNTroZfzocAXMpWEFEtIJbTAxSAiNqSysgQJTjzEFxHwhQPZi/q1cL59z8SDmiGPMgUtg + fZyjjNEMrzm/55znKj7zBWRPc/4cwlew4lwh6R1HDMvCGe2IA6K44IoUUmNksDI4Hmwv3q8LbPqw + /eYckMK8135HriHDdM31Mtet/b6n61lcD8vpLUvD/eHBr/+DagHxvKwUSlMK0sWLOiw91dJihrVG + xnGFC/0Y1f8V5oXyTJZ5Rvc8K0o5k4r08Ix4hDmDNc93PKscxxLl+YKrp3kW+EeEI0h4So1igGJp + ieFeeYMoLWJQwgotjWkP1vhesr8R6+Ubbfwg5DHmlkhyQdUjVhtlWK4pX7baPM8XjD2T8mdnlyuh + LqyEQmCjwBMC2DFGOXfSKaKdFKA9txgL2m/EH5btlfG+iL4xxVQwjPqseptl8hikr3lfzjJJtOr3 + oD3Ne2xMy5C2It5ldvvv/jz5Ei8cHv4RE75b3E5G5ruogfJCa1WABaGRLQrviUYUxxsktVhb5QsP + lveqwUoivzLtuPcGmAulpGCK9sc8wDK69gZLMQ+JZb7gbzXt6Kzvj1aOAjEDREojCXBkmOYATjEL + VCJdEKJBG8uK/nBoFYlfmW4sPAeL7pUSjKFHN3D0HDimuGvd+KIbpPvlC/ye1o3yZDQYnuwfL/0h + eNSC9W4w+vn3k++iDcaDVBxZq6kh2iPDKRATQyZLhZeYWqeZM7w/YnpcxpfPPzycKTBFEGfAv/YN + cgfoDsJdPkzWvqHjn3W5MI3RU/QNC+CSm883/wKhL3JymBoAAA== headers: - cf-ray: [3bf3f738b7601a93-DUS] + cf-ray: [4aaa2edbca88c4a6-DUS] connection: [keep-alive] content-encoding: [gzip] content-type: [application/json] - date: ['Fri, 17 Nov 2017 16:11:25 GMT'] - server: [cloudflare-nginx] + date: ['Sun, 17 Feb 2019 18:05:35 GMT'] + server: [cloudflare] + transfer-encoding: [chunked] vary: [Accept-Encoding] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/rarbg/rarbg_daily.yaml b/tests/providers/torrent/rarbg/rarbg_daily.yaml index 5b874f3b9b..0016016778 100644 --- a/tests/providers/torrent/rarbg/rarbg_daily.yaml +++ b/tests/providers/torrent/rarbg/rarbg_daily.yaml @@ -5,22 +5,23 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; ee483911-cbb1-11e7-90fd-1c1b0d9d2a41)] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 92c2cfc0-32de-11e9-a385-1c1b0d9d2a41)] method: GET - uri: http://torrentapi.org/pubapi_v2.php?format=json&get_token=get_token&app_id=medusa + uri: http://torrentapi.org/pubapi_v2.php?get_token=get_token&format=json&app_id=medusa response: body: string: !!binary | - H4sIAAAAAAAAA6tWKsnPTs1TslLKMUotzjBMLDM3U6oFAE7gksgWAAAA + H4sIAAAAAAAAA6tWKsnPTs1TslIyNTM2Sk3JKEsuVaoFAH87Ll8WAAAA headers: - cf-ray: [3bf3f6f072331adb-DUS] + cf-ray: [4aaa2e4b7889c4ce-DUS] connection: [keep-alive] content-encoding: [gzip] content-type: [application/json] - date: ['Fri, 17 Nov 2017 16:11:13 GMT'] - server: [cloudflare-nginx] - set-cookie: ['__cfduid=d0ef242b77da9a14958ee9374ebe44de01510935073; expires=Sat, - 17-Nov-18 16:11:13 GMT; path=/; domain=.torrentapi.org; HttpOnly'] + date: ['Sun, 17 Feb 2019 18:05:13 GMT'] + server: [cloudflare] + set-cookie: ['__cfduid=d864a98965fd17d1a3a7521c48cb377471550426712; expires=Mon, + 17-Feb-20 18:05:12 GMT; path=/; domain=.torrentapi.org; HttpOnly'] + transfer-encoding: [chunked] vary: [Accept-Encoding] status: {code: 200, message: OK} - request: @@ -29,196 +30,193 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - Cookie: [__cfduid=d0ef242b77da9a14958ee9374ebe44de01510935073] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; ee483911-cbb1-11e7-90fd-1c1b0d9d2a41)] + Cookie: [__cfduid=d864a98965fd17d1a3a7521c48cb377471550426712] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 92c2cfc0-32de-11e9-a385-1c1b0d9d2a41)] method: GET - uri: http://torrentapi.org/pubapi_v2.php?ranked=0&sort=last&search_string=&format=json_extended&app_id=medusa&mode=list&min_leechers=0&limit=100&token=l2esh1av76&min_seeders=0&category=tv + uri: http://torrentapi.org/pubapi_v2.php?min_leechers=0&sort=last&ranked=0&token=5632edhvcu&min_seeders=0&app_id=medusa&format=json_extended&mode=list&category=tv&limit=100&search_string= response: body: string: !!binary | - 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 - AA== + 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 + bxXr7HtAvw3ost+vwPbon//7z/8P8SpTU0MrAQA= headers: - cf-ray: [3bf3f710112b1adb-DUS] + cf-ray: [4aaa2e715ad8c4ce-DUS] connection: [keep-alive] content-encoding: [gzip] content-type: [application/json] - date: ['Fri, 17 Nov 2017 16:11:18 GMT'] - server: [cloudflare-nginx] + date: ['Sun, 17 Feb 2019 18:05:19 GMT'] + server: [cloudflare] + transfer-encoding: [chunked] vary: [Accept-Encoding] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/rarbg/rarbg_test.yaml b/tests/providers/torrent/rarbg/rarbg_test.yaml index f71248cf70..ce4c739246 100644 --- a/tests/providers/torrent/rarbg/rarbg_test.yaml +++ b/tests/providers/torrent/rarbg/rarbg_test.yaml @@ -2,38 +2,38 @@ daily: search_strings: RSS: [''] results: - - seeders: 5 + - seeders: 1 pubdate: 2017-11-17 00:00:00 - title: Ghost.Wars.S01E07.Whistle.Past.the.Graveyard.1080p.AMZN.WEBRip.DDP5.1.x264-NTb[rartv] - leechers: 11 - link: magnet:?xt=urn:btih:6dc059d532bf54ce5d4ac61aef31f2d601f5d328 - size: 1506137088 - - seeders: 3 + title: The.Voice.UK.S08E05.WEBRip.x264-ION10 + leechers: 17 + link: magnet:?xt=urn:btih:e40b39d3ff9301f18ddeef3e6ae5c0de1d7d219d + size: 675478909 + - seeders: 14 pubdate: 2017-11-17 00:00:00 - title: S.W.A.T.2017.S01E03.Pamilya.1080p.AMZN.WEBRip.DDP5.1.x264-NTb[rartv] - leechers: 12 - link: magnet:?xt=urn:btih:72736a12e182980ec2e4c8b4902874793ff0a71a - size: 2459813388 - - seeders: 10 + title: BBC.Williams.Formula.1.in.the.Blood.1080p.HDTV.x264.AAC.MVGroup.org.mkv + leechers: 55 + link: magnet:?xt=urn:btih:a8a153c0390e6357b49a41d28e7b04150be9078d + size: 3586064806 + - seeders: 16 pubdate: 2017-11-17 00:00:00 - title: Pickle.and.Peanut.S02E31E32.Gregazoids-Meat.Ballers.720p.DSNY.WEBRip.AAC2.0.x264-TVSmash[rartv] - leechers: 11 - link: magnet:?xt=urn:btih:0e4241041713a8b058f4733fb7dd946c76f8b001 - size: 566841009 + title: BBC.Williams.Formula.1.in.the.Blood.720p.HDTV.x265.AAC.MVGroup.org.mkv + leechers: 42 + link: magnet:?xt=urn:btih:ead53a320f5c6dd012f8b4cb3cd70f5e70b8bc31 + size: 1225778158 backlog: search_strings: Episode: ['Lethal Weapon S02E05'] results: - - seeders: 210 + - seeders: 16 pubdate: 2017-11-08 00:00:00 title: Lethal.Weapon.S02E05.HDTV.x264-KILLERS[rartv] - leechers: 16 + leechers: 0 link: magnet:?xt=urn:btih:0f414d9aba84fce80eacd0b9ca307ac39e748cb3 size: 311075131 - - seeders: 143 + - seeders: 7 pubdate: 2017-11-08 00:00:00 - title: Lethal.Weapon.S02E05.720p.HDTV.x264-KILLERS[rartv] - leechers: 16 - link: magnet:?xt=urn:btih:7c80f72b90e3302d55466d8d93ad870ae6c2274a - size: 1242475213 + title: Lethal.Weapon.S02E05.1080p.WEB.x264-TBS[rartv] + leechers: 0 + link: magnet:?xt=urn:btih:8b5f178d7ab23b177a248fcb0f24e224015ef708 + size: 1622606805 diff --git a/tests/providers/torrent/shanaproject/shanaproject_backlog.yaml b/tests/providers/torrent/shanaproject/shanaproject_backlog.yaml index 7545055249..d6cb93b0f2 100644 --- a/tests/providers/torrent/shanaproject/shanaproject_backlog.yaml +++ b/tests/providers/torrent/shanaproject/shanaproject_backlog.yaml @@ -5,247 +5,256 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - Cookie: [__cfduid=db770aad206624f57b3a5fb7f762e360f1510860221] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; a6672f0f-cb03-11e7-9526-1c1b0d9d2a41)] + Cookie: [__cfduid=d2815e33bbd766bf988330f5f03f8be3f1550260506] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET - uri: https://www.shanaproject.com/search/1/?sort=date&dir=Descending&title=Yu-Gi-Oh%21+VRAINS + uri: https://www.shanaproject.com/search/1/?sort=date&title=Yu-Gi-Oh%21+VRAINS&dir=Descending response: body: string: !!binary | - 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 headers: - cf-ray: [3becd3943ba51a93-DUS] + cf-ray: [4a9a54bcbe55c4a6-DUS] connection: [keep-alive] content-encoding: [gzip] content-type: [text/html; charset=utf-8] - date: ['Thu, 16 Nov 2017 19:23:45 GMT'] - server: [cloudflare-nginx] + date: ['Fri, 15 Feb 2019 19:55:15 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + server: [cloudflare] + transfer-encoding: [chunked] vary: ['Cookie, Accept-Encoding'] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/shanaproject/shanaproject_daily.yaml b/tests/providers/torrent/shanaproject/shanaproject_daily.yaml index f5c74e311b..669b49f8a4 100644 --- a/tests/providers/torrent/shanaproject/shanaproject_daily.yaml +++ b/tests/providers/torrent/shanaproject/shanaproject_daily.yaml @@ -5,264 +5,265 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; a6672f0f-cb03-11e7-9526-1c1b0d9d2a41)] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET uri: https://www.shanaproject.com/search/1/ response: body: string: !!binary | - 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 - 538AAAD//wMA3VHlzz3tAQA= + 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 + AAAA//8DABCJ8S83CAIA headers: - cf-ray: [3becd37f3b891adb-DUS] + cf-ray: [4a9a5485694cc4d3-DUS] connection: [keep-alive] content-encoding: [gzip] content-type: [text/html; charset=utf-8] - date: ['Thu, 16 Nov 2017 19:23:42 GMT'] - server: [cloudflare-nginx] - set-cookie: ['__cfduid=db770aad206624f57b3a5fb7f762e360f1510860221; expires=Fri, - 16-Nov-18 19:23:41 GMT; path=/; domain=.shanaproject.com; HttpOnly'] + date: ['Fri, 15 Feb 2019 19:55:07 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + server: [cloudflare] + set-cookie: ['__cfduid=d2815e33bbd766bf988330f5f03f8be3f1550260506; expires=Sat, + 15-Feb-20 19:55:06 GMT; path=/; domain=.shanaproject.com; HttpOnly'] + transfer-encoding: [chunked] vary: ['Cookie, Accept-Encoding'] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/shanaproject/shanaproject_test.yaml b/tests/providers/torrent/shanaproject/shanaproject_test.yaml index dedeef5001..cf54ee9cb5 100644 --- a/tests/providers/torrent/shanaproject/shanaproject_test.yaml +++ b/tests/providers/torrent/shanaproject/shanaproject_test.yaml @@ -4,22 +4,22 @@ daily: results: - seeders: 1 pubdate: 2017-11-16 00:00:00 - title: '[HorribleSubs] Inuyashiki - 06 [1080p].mkv' + title: '[Erai-raws] Mahou Shoujo Tokushusen Asuka - 06 [1080p][Multiple Subtitle].mkv' leechers: 0 - link: https://www.shanaproject.com/download/162660/ - size: 621165936 + link: https://www.shanaproject.com/download/188184/ + size: 878916403 - seeders: 1 pubdate: 2017-11-16 00:00:00 - title: '[HorribleSubs] Inuyashiki - 06 [720p].mkv' + title: '[HorribleSubs] Mahou Shoujo Tokushusen Asuka - 06 [1080p].mkv' leechers: 0 - link: https://www.shanaproject.com/download/162659/ - size: 251333181 + link: https://www.shanaproject.com/download/188183/ + size: 879199518 - seeders: 1 pubdate: 2017-11-16 00:00:00 - title: '[HorribleSubs] Inuyashiki - 06 [480p].mkv' + title: '[HorribleSubs] Mahou Shoujo Tokushusen Asuka - 06 [720p].mkv' leechers: 0 - link: https://www.shanaproject.com/download/162658/ - size: 99530833 + link: https://www.shanaproject.com/download/188182/ + size: 392828026 backlog: search_strings: @@ -27,13 +27,13 @@ backlog: results: - seeders: 1 pubdate: 2017-11-16 00:00:00 - title: Yu-Gi-Oh! VRAINS - 27 (1280x720 HEVC2 AAC).mkv + title: '[HorribleSubs] Yu-Gi-Oh! VRAINS - 89 [1080p].mkv' leechers: 0 - link: https://www.shanaproject.com/download/162646/ - size: 179914670 + link: https://www.shanaproject.com/download/188069/ + size: 1428076625 - seeders: 1 pubdate: 2017-11-15 00:00:00 - title: '[HorribleSubs] Yu-Gi-Oh! VRAINS - 27 [1080p].mkv' + title: '[HorribleSubs] Yu-Gi-Oh! VRAINS - 89 [720p].mkv' leechers: 0 - link: https://www.shanaproject.com/download/162593/ - size: 578289664 + link: https://www.shanaproject.com/download/188068/ + size: 566807756 diff --git a/tests/providers/torrent/thepiratebay/thepiratebay_backlog.yaml b/tests/providers/torrent/thepiratebay/thepiratebay_backlog.yaml index 24dd35381e..6dc40e039e 100644 --- a/tests/providers/torrent/thepiratebay/thepiratebay_backlog.yaml +++ b/tests/providers/torrent/thepiratebay/thepiratebay_backlog.yaml @@ -3,237 +3,232 @@ interactions: body: null headers: Accept: ['*/*'] - Accept-Encoding: ['gzip,deflate'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - Cookie: [language=en_EN; PHPSESSID=c497dd81ef6decd6f06e6c316d72c5b5; __cfduid=d1ebe62a518d70e0ff8ac8ed67684a3c41491845305] - User-Agent: [!!python/unicode 'Mozilla/5.0 (X11; OpenBSD i386) AppleWebKit/537.36 - (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36'] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET uri: https://thepiratebay.org/search/Arrow%20S05E07/0/3/200 response: body: string: !!binary | - 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 - S1NMaGqapoFas25D4Kwc7ulrmIsTfUb2Azw+vDD0wwBZF+Vf4IWhnWDyARoZNNaX3r3M+ELzQeaz - 7snbFyf93QEy49TMc+QSjp2dyLcPszu6Q76AZENFrteUumI2ZEltKrbVrJum4miWCpugsfr2esb/ - mdeg9Lv2jOjwcBP+r4bN59AHz8nI/c++gCTvfgEpscwKaM4tljxsfQSv3QKo/4aXhP6xi+1Kk9zX - yZ/F2eWcC3RQefnpsAvj+OIeLwetY9K5i2L714JsTVMl2VSVmi6BWkPXGs2mCvV6zdaADSUdSLpa - a9gr5+yc0N+1Z0TsAxL+hUhYtWxfNFF8JcYXVfOK/tM6iRKG+eWlb3qfpffnzZp9IMuWV9O/+ccB - OMDq6cEn+fD66dW388PJ0cG3y28nf9aOzj/V3p+Mrk9PvqlHr/6Uv305dg8PToeHB9+ujw6Go7fe - 8fjDp5cTy2uq79zDy6NPny6PJtqb45fHX965QwV8+jM+dj8fvT35/Pz067Fko0/y8fNTyTqX5dPX - T91D6YV7OPrmHo5OJct7eQ6Uz5N33pV7+uUIn359e/3u67Oh5b0cga9H7juvOTmdfLr+8+SbdnQ+ - 8uzXb5r2l+PLtydHz96evH1F/ge9z5PDV8dD+FE7B88J7Yvrw2trLa2pPnNNpI1Ov8gXpucG77yj - C/Pj7XXs12+H35TYtZB2bqrPLomO9te33unXN2P7VUTao7w/+aa99Y8nH75+HllEh4+fJsfo0+TY - +1wzlWPZmmij069Hmukdjr8pzZjwPzofKe//NIwnwHGQbdBBijzbNApcDMIBjI3CmemCDAx8cMGE - /BtTybh6huKvu42qiI0tOlAWL39RtressGT2/me/lVtriNo9QoPEMCurK7MW+bv1FY3b1tVf9fsF - /+RaKqvSJifNTzqILBww25xD7qDe4bavJCtm3VZlU1FrAKqmKVmyI2lOHTYUU5cUzVY0pXGLz+bh - FPJwCvnrbv7WxMY9Xh372ecQWXk4h9wbOyVFW3MOIa+ZVt69f3fPE8i8emdz2dYoqOgyMGuNuqba - lqYBS1abCmhoNa2hmJpaqysNxZQcR11/6kjFPeDdw4sOP/oFavmXftFBe9gZLqNbvVnXb0G3H/Ky - LDHp3EWxNd4BRyZeFAicpmpJsmY1HVk3pYZUt5Sarmo1STdrjmPfjncPXpZf1csSDE/PXyiH13/W - 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 - x80yVq6S5ZD8kg1B5/8DbCC5FXHwAAA= + H4sIAAAAAAAAA+xabXPbNhL+HP8KlDdJnHHFd1IvltSxo7TpTdJ4YjfN3RcPSEISYopgQMq20ut/ + vwVAUi+WYlJxptdePIlEENhnF7uLB2/qfzd68/ziX2cv0DSfxcODvvhCMU4mA40kmnhBcDQ8QPDX + z2kek+HFlKAzynFO0CleoBYSLyY4xreLpxmasSxHnGQ0piTJUUDznHEuHjOak76hMBTejOQY9OZp + i3yc0+uB9pwlOTRtXSxSoqFQlQZaTm5zQxh2jMIp5hnJB/N83OpoRgEU0+QKlMYDLSOYh1MN5YAw + 0HCaxjTEOWWJwVKSqNqIZCGnqXh7dDuLNTTlZDzQVlro8rU0daCdy1dovdsa2qI7X8QkmxKSl/ql + 4WGWVSqMfEpSCRLghc74xMhyMC8UjQxV4etC4C56lGStFFBILvpX4mWLJCp6qJNbFkJ3r/SQzQyt + JsAM0z0lleWtLIv3k7ddv6NPmB3GbB4JX9QVTDnLSZi3FmzOoZpe43ChJ+D1mvI4YclixuZZC4SE + ybUFo0x0NePXTaQyR8cz/Ikl+CZrIpdzPB7TUMfRbcrzT9tFQ9EZSID4cykmE9g44ZzdPLbNc9N7 + YbYN03AM2zSXiSzTdzNxVZ340xXMKbv9vXon/maYT2jSQ356e7xWcUOjfNpDjmlu1lwTngubWzim + ExCd0SiKyXqbFEcRTSY9ZG9KBzi8mnA2T6IWneEJ6c15fPh099Cis4lBgUtagmkyfULHT5/tROQk + JTjvJax42tkwZcBnMOp6iNPJdKXdH0uPRSR/JSK17rAx0Foro59ID1m6TWbHd2tviMDsIdc0dwGP + gMQ2gEMWM95D/3CJ53r+ZwVxb8ogCjsATPjrdtftEhnRikjIOFbdBicQDolItirKGM+DxQa+xChi + HpPxhnPHMQPPb1Ss2/4LnpENzCJPWjlLIdc2c6WsDRhMQ7ONZFrBvqbkJruhMP62BkuMjB5KGJ/h + eKvRGzmw2dkt1Wtx3kRWlvUNqbgcnnLOQhkPPzePfMiMDx/nhC/0GfD6h2xtJvqAr7GC0YYALp+a + oudp0ABWzvAJRA1IbjnrrkztxeQ6ZhzhJEIRu0nAoxEUFqhcOIw5myEwCSmbYBQu0DyDsCJFSUh2 + GEl+Q4rddDSiHOaIJeA1xUBVE2B8JNhTr2bYFROvyOKG8ShbsW8VFEUbmKWBBS64BlVuK2wTatY8 + LJZWc2Ctgbbitl3epGN0CImtx0xN8ei7AeDG4+rFM/T7ar0OpBXjkByuNzr+YxmWvqEWdAf9gEWL + wgcRvUY0GmiiinCtMFlWQWRmCHw0ZVA/EUsb0fCjhnAosCFbMmNllpAyuJyLwJExzrKBBhwMuQGf + 92WYIGvwY8wm7DKbXSYLwddK58XZqXgNmmMIzN3lWN/AG3YEw1VTNpZzKnYww228EDB9Ixg+SYIs + PVaf/1FfBytdCyAvMlKhnsriCurGC4F6DyLkFrSsEN/KYgmgDdfLdQDz62WvL96hbAoWacPyqQbA + DEZZWEG8lqWh/KqjnaVL7SxFFqw1hsXDllBxEUGapPO8GAzlSr7MIFEVsNsKswj+edFMjWDISzkA + piyGRK6CPSWc6LquoWscz8n6qNaWiovaDeTCnHkwo3lljioGc5hWgM4EhOzBWp9iHJBYUBtsROYR + ZZXpJ7JUahW5XdSrThQFlsg19SpR9PjsJI4Pnx2XVoVTEl4JrxhDCdo3pNIN564Yck0jsjTknSyt + GlLUK0OKQiNDkHwiUfGKRGCaVHOvabBZy5YuWu7csnVPyVaFo+RzUz+tIN9r0wT0LI36SZZWrSnq + lTlFoaE9EvReQ1LGk2Xqi8KqGapWWaGeGxohEO+1gQFp88qIN7K0akVRr8woCg3tkKCVIeuWwJwm + Zl+hCcJHJowvSmXLMuibwgy7Nr32MpIXGtc7J2GZXJKUYx84Cpr2DfV2e3OxA0iRtLEay3cabsG2 + TKuiz134W8VsTY1uFDB2lTUUdmCGEzsWYC6aNhV2teGPr06eN5PqdrUykDvdaJR+rOHigqXq6Lal + ixks55v11BY+VnJo9G70tqGwU8QVScZsqtotVO8RIdv0Vmf0RpK+NnwJa+4piaOGkm2QHKEW2svR + nUJ4T6sht5xRM5mHzsf1uamOCY5Iy99oEjXtryPzEjcjDEfk46+//Py+oZS7Z0I4Igl/fnOODukZ + jgx6NmUJedYQArLxJIk4ow11V8FFb84fKL7FNF9HvSsCe9aMH919YuqKmJ6d3zYUgpC+P33z3vHN + hoKeyFfaUGhfRnEFo3xZArmCV/ZJIPeh2UEtzuqo9vacrLwvmaw8mUg0zOe8sVrIpmK12kjM23+6 + 8ERO7Ts5eg8d2mLJW0e3L2L7otV8weaL4D5nMxo2lds3rr6I63NxHNxUDgJ7Nl1kNIibqvyCyPQN + tRHY3B6snh1MaRSR5Y4IT0i19V9eeNSQZDwiPFhUwmD2qnTfEKdjxRmaEdHrYf+7VgsZBoLnnjpM + Q61WeQI4tYf9LMVJeeIEgZrHedZbO7mE7okm6jxlRLM0xgtx1DmleaZOQk2UM2S76BC2v5zdisex + WOADYYKGg4PqNE+peau0wE6tfF8cbkIiP3r0qHqbXS1a8pxavX8Efhlzcd5+z4ldRs0XdGbODXLL + LhNsAI6ti8taTd0AwYbAB6dP5VG3yBooSOBAeldGBPZpLI6puHROxHmEoVQrA6VjDx4dfIFN4uSM + 8MKqsrPqZWVl2+4srew2M7JyorhNbS39288xjA2lcSUYwsP9XOSHrJKNXkJJer6f8/KQqTqOFW7I + pyunmbuu9KziTq/cowvjUbBA8kJ9KD7V8SaAVaDC9vJUS97aaHUUbdcjLmi0ofgUetBhWdFD90O6 + 2yF/TcVZOwHnlE8C+vsagN52wHP6CWwUnwWQGHBIXrUMtBsYZ6QFb0J54XPDcXpcyx87HPLrKxIh + 4dLiQblfDvE6XWjv6AIh8CTOrl/UdUZ3O9IrQsKphHoloZ4VPLaSFMu7MW2I3kFhLZiyQjTR02n6 + g3gYCLtgmMQqBww0YnNIcMVoBfxaAuIg4MvT+aJnD+Ub+A/wn9G49MCDOXFDJ3xzMeKNXF29iCGu + RnpU+Zjw/GJajHRFTIqFNy8c1gx4zTgpb8dohqpTsPLAFRen0hLpcAtU536ojb06ZIgi5aWR0K+o + 6M7wYDVxigtbbbjWj+LSzLB8z/Ecu6u8fKl8fDma4/jy8gSH85xcijOvy7Ztppe/vThtjV5daivQ + 4ma9Mn9EckzjTN4jrl3ZCTz0ROEdyzM0gYcUHoItQ/3G8tKimI2q7qirv94Pt/lgzpNekNNpb4wx + jtoWCUjHdh07iMbYI52gQ/AYu07g+d3Ibnej6EmUDKT+I6X/SOg/emz7yoLHzqmw4UjYcKRsOHqS + 88E8Sh87J4/tH+FfznF4BTNbXGRgK8UcRzQjYjaEVn7X727KfCLcjGC+DKfwynKc9mYD8TsoPSIz + llAqfnWyo1mpO2RpCqrnfAyF/GqHVpiJo3kGsNkiCQtU0W4ZwupWVSRgebWq7nmVl+vfIMqfeygh + dX8orwxfL69/y/vCuoCWdWtZqZ4mE3VdtI+UHDfi2n8licWPMZYTG7LsltVRRGmblv+9nKuQ6/m6 + o96+pqffl3OKYOENpHKMzTPCjVdznLzEHGKzvAYsbiWXVUBZ1bOiLmHhxrBG8mcMA61YHpq7q6yi + qqS85VoGq2XP/z3pOZbjdex10ntHJzTGAH1pmR1gu5PX//5FUN5bml6+fPHu+eVo5OnW5a3te80Z + sAJHEhwJcKTAkQBHEhxJ8OG+krW50cIdx2rDwB97vhlZXcfxI8uJBGW2TdPtWI4Ztp2Q3OHGypgj + acyRMOZIGXMkjDmSxhwJY76R5AOTJF7jlQQvpvm8gaJrmq4oePfz2fL+WTyXK2/5c0Hgy9tjDRXb + rqfm0y8i6jqUa7Ws7h3K9S1P9zvNObfwzR3CrXxWPDwA1Zp3qPYbvQK9mo7pe4pe9eK3YJIwdLWC + 0v3nL3VBErogjdbZ+Ul9Rq2JN2zQuDZvRp5rtn0PW5EZuF0SWmE7GPtWxw9dO+oS37M90wQSrXiz + nv5vVPlVqXLE9ff//BsRZfsOUULW6abfnCilZ+7QZOEv+VWXIq3dVfZfYDXarkmX5eXJg5OlvU6W + YrdZ0oX95Vz5ebhh/ba1mZKETpuYmJjtTtDuBoT4rofblm8GY5OYbtCFlWeEXfsOU35W/Tei/EaU + X0SUtmXq7e6fSZT2X28t6d0P9bWWkZbbdbYwo+ADyQyt1+SnOaTJnpR4F2cLF95pVJsEu8Tp2C6x + HOy7poVDK3C6xLRME/jecbwoCsfOGDud7SR4R+839vuq7HdxfUHw7O9Nf23YirSb059yzR3+Kz2m + vr/Kbvp/b6n4p7KhZ2/bVD8AHe4C2raN3p8Qg27YdtrYsp22FY5hQRi13XbXdgO3Y3mh7fhREPld + t71j//yNEb8yI/4XAAD//+yc32/bNhDH/5W+9DEaeUceyZcAbRNswdAOWINhwDAU/IkGbdohTvb3 + j5brWbYkW5bs2VnpF0MCRRK08PHdfe/u+yOiJFGhPDERtzjP52oTnjq+yBGoT75patW1cJP9yMmy + TVODrmWXPOl2uab3ieEyjc5+s2HRKwKyXgYeknDeRUbcSm89EbFMzS0yTVO2rgWavIkizxR55hDs + RMBKj4g6Hlqe2Quf52dQnhyl3OjtSniTpYcUwZtwHKx/dz80mKkUGDPIlJdKee0SsxSlTiYaVCHQ + PEvIKh/NTum7CdWiehesHgyriukKi+r9PFGqN8KV/1JjTdjIpBDVq1dv9vfTd8x3ucfg4ZmUmoE1 + OhAmQT55tE5yCE6hZ9Yalt9llRzwlte+ff2CyqOicr7+7PHrlwifOPyvgYnaVHpEaubaCbWwuXF+ + a5dDEYrFMp2EU6apM955dftbjZE/5i9T/HN0uHNzns5o58agwdhUkoyUoAXniqJJRAmMYQoES9bl + G4wwCIx9wc7lui/l63rll/KqIPOoyHx8uEtfP4e/HuIsL163FtijX9bD0+wxhgXNFs2xFndW/ZeW + 1+cI0fyWVnqEMt5xZi2Udp5rx80DYLWd+n4eKD2hasQMqT6j9ID26FBTdKwV6qTmSkrNUhQJvIMQ + HI9BCmvQc6aUIatSYlus0GKAFgP0KLK6EJUYISId3wAtodFp6FTQb4D+njFycXXz9vrd+5tf3k2y + QTem6jVD18cNRicqiICCW+UAkES2RjlLiqHjBlNAS1qK4N02S3R96YLOIrxPZGYlYHHzxyK7Px8g + kuJd+ZiH4GHvTF05mRNoKFyEKAxHznUmYmLW28gCUxmCyB1naENi0C7i6Vu5wLDAcBoMdX67hHhO + WUjFVmyhUfBlxWP+ZWEJjZoXNTnqShZ487H6KfuecPH+6cvd54ufb26vL95e17/XcGKOXOByytPD + s5akAhOkk9Yxm4yhIBlGyeYdOPI5KSLrCWwj7jluQwW7x5Xa72ZP8wZx30n8k2P+gx+RGr84prbo + /u30Ft9HqaIs2OUEGS9SbM9emhPl8LlL81n3zFzqemR4LZHxTjqtBaEISlmVgk5kJVMgpdXazPsZ + RSV35i3Nd1Gyls6jodF8wg950/d5T40Zb5tb/WhnL/iLb4Nm1YqmWwf9cBaZU+NzoDSNKlQ6dA7U + XtWaxSZuwVnozi4gtZHXaoNR3X/6e1IYtXvG3mhq5/DhQNbOI9MJFCAwTCQ1MilZ9M5HoASeC1Su + t5apdwcFxqXIfVpNk5AVjYgm/CfdQEpktQeVnLO+yGqrD8Y4Uu6asC/O2jl6OCcJvPJEkbPAUXON + +TIEaRI6F5mASM473s4e3bGBgsmCyWkKFKNKnrQXSIm4TkKmVmajBrSu/Fz5+3Wp+K/3+wVXl957 + Xb65ctmbc10OHDi8KClTEQglJm3QekAHEYWX4KKT+WOFUSHa1HLu6/LOlUffWLvgsRQijQfkPwAA + AP//7D1rd9s2sp/v/grF524oRjStpyVLoX3y3HavnWSTtN1W0vUBSVCiRZEyH5YVUf/9zgDgS6Js + J82mt7tJeyQCGMwMZgaDGQCUhYOEZOX/wYtI36PJL3CN3a13OnN7ocXT68vhx7+/+vgZd+gTv5fb + 1CxirAiMp58F/vDze+vYwl9WMmmz0W1D+q33GvXWSdM0Trq63rQ6RouekN7uW/G5/c8iB7W/dp4j + D99v2P8n7IS+oC55gbPnT7ET2lTbjc+/JyXGuOOC07GLh6+wD/pn+HnPP+z2PXjiTnvrlVB+g+jG + fnn4+qeLIQ3Dmy94gakMyel9EA9/dcnsdFr1ht5qto/rpN077vROTlr0uNs2O2Cr9WNSP261e+ZO + zl4gCl4VyX73qv/qYBSl/G8diYKtqZ0vOA5Cwez4QC4t/Hyo9+t8f9/oczxeo1Xfl5Z/pdAzS7kf + EnneA/0ZF0frjabeNVsNvdlqE9rS9brRsOodq0t7Tf243uyYzU6zd0eW/j3u/GM85B8S833zS6Rt + tfcFbyF9w1jxz/CHif5IzwkepCRWxPcVD8/fnn9hlJh2L4kPk7YH+8DmcYPo7V630zKNTocYDUi8 + CcS4HXCAnVa724TvumW1yiPDhNx3b/f9xvzv/SXjxh9/Y/6z/gTbf7x36550j+/wbr8rE95Ccoen + +8xMmFgNzHQpsU5aRr3RMU6gQq/36l0DcuNWp10/1tuWtScTToh+z4S/Z8Jfy+/V1fYXHFp/pUy4 + 2f5+ZP37fOBx6d+z2H2p8Evd4T34HvYu5Wc6yV6vZ3VIw7CMbq9ltDtmS+/RRg9vq/d6Xdpom92e + 0Tze93cudul/95ffyF++Cn94+W/tL780KUbB7PhLLi38/Ao7h0V3CfMsJLpDswmHfkX04K4H9MSb + UBY5r0PM4KBim9pBMFsd6sR1EZR5wMpT2/LBId0n78Cuv7Ln9egIbPbSJUeAqKFOw7lzUGHK1A4a + TXDCU4qcawfH6JEZYqHdAygHhu85YGkT7cD1kFVOmnOb8Q1g9iKshKsFiDWkt+HRFbkhvPbgwXwS + 85DTU6/wL8Yf8f5MmPwP2+NnUnh0eFg5wsc+TJIQ59jhIQicyxDlZnlemFov8nTI5N7nYh/MiT+x + 3cPQW/QbdD4A2T5N6FUqN8SvzG0QuebSZeXF+/OP6jPXc1dzLwqqUqtLLROiRLNOjUanbdK2Wdcb + XdNsnHSahLT0Du31iGEe6zqVlMoaEFbAHfgUdNpvK/DkhWCA/braUSqGZ7v9ysHt3D9QAHAjD+CT + 0VZBPn5YhYpMFH/5HfrXgao3L1oAZPaZBZx8pgH819MFV3/qfRwPZJrOr3NWOmVfOLUqcaUI7tOJ + HeAcSHq8TypOk6fSfg5xJxGZ0LTfB+pQA1xiUn96Lp4qR5WtNo6wiI/oXhSmyJ6x0in7KoPWYZSZ + D8HCKX6m58FprII2mnVDMyVGRuYFL8PScHCaPXOCaMoFmgvPsY1V2venAMcmKk/zpRKGp2G46B8d + RVetJfm0mnWi9tS9CWcqrItepqyPb99Dkvj2fdmITc8zHRrk1jhePhUP+4lywwwOIaCJ5sw4UySv + sQpKMA8pGN+lDhqaHZyyaoawIMynRwt0p6y4TUS3Q5xFiD6H782rX0AxH9lPkfUrT/XT1g/Gq+fH + ut3++PqdeTNrNd4tP3W7L5fPPlnPfvvUtC7ASPXTLyFRqT6HuKXVlFNautG4Prlt1T91/U+dpnHS + vVoazavuybJ7vOo6LXfVabvOjdmmy/00HTuk+4ie58Z1/qHbI97fQiv624vfut3ubeuHuX8M/P7S + +oX8unJvT/bTAJQQH1HfKyPyz4v3KZH28asOnf3q/2Z2fnphzN9Ev776Z7P9+v3VLz9fTH5reHr3 + xHj/s72ybs5f/3ZlrS6m717e6NEL2mm/vj7/x83PLybv/+dd+6efLi5+6Vir1m/Tn/8xfdn4+/l5 + ZD0PoxyHwZw4zunzVYX5aQybPr57Xll5UYVMfEohpKoAYxWdsogKHKUpoisA8Ssv3v2kVn60GLzp + uVIoei0cSvDXtyi5oRXXW1YgwrZd8JSOUyFuhZgwhTEMBFfL6AvD+8t/5RYUvgoHB1tz0w+CNKBn + z4kz+/Dh4UEYdLxklHOhGCLILpoU1r0KLnwJQ2zlK2uHFZCviunShgvb5XJ+GUAgDjILKhpbnhbe + InLB5ffFYhX5Tr8Cg5TQTAKwEwiSLcs2VGLeLvzwEwa+R2cLhxgUL+Rozd5Jt9177FPT9sHZSgpf + 8uw5DRBPk5enoCBWbjTVOvvH6w3Pm9kUGqRwoQMrortFglC3XbMf+hHFpfEvm0EyAG1tu3Zow4r+ + ifatyDXwhyar8hqDbjUiatZalTcK8X2y6q/t4JI/pR2IvPZpCBlP5a1+BYyrC1iaPQxj1ND7EKL1 + qQYoBQA1TZOGHoPC1IysxtJGCTw/zGFTdMWQ10QjKjbAym1bVV3Gsk8hNQ4orwIY8IdVHIqt1Qf2 + UwKJjzsJpwO7VpPXWG9qZGiPEfgexswCYxx4LMmmBkJSeS1nxgTmUJDygDowET4XsxiyQMzEuI0X + OdbMzUZIlGwUn7imN7+8IU5Ey4ROhhcknKqW44E4EiE8YXW8a1WWx5uNwnlgChSPv1eDiaA2yoyu + ggI6FP+UBG+X7jsfUkg/XGk7qIvtChRfwgr+yo3mz6OJ9qi6Tmj33chxNjJ2ZaA/BghEfUwKqlIC + JcmKKfoH2jCrVuDx3AP2aVrBZPnWgqciD1BhB+8SBhlAGU2ohjgkAIUZkJpK44zuORO+lpYTk0Rx + 6NqQ2SKi9qwKeQSS5IKUHj/OVyZylOKYgLhx8LJQjz5IbN4Ax1sBQQPC4hiEomAOybq6iIIpzJQN + h8qJd3vybI2Az6G9uFNoMNaUTKEyNWB9d34biskNhG5Pg9x0Q4sCQxJTnWo0N/u5NNebQXEMdMcB + WOAAKLDD5G6yAeVIpBOhasmytTPXLWC0ONczbhMnmPXMjSLtuNE5dc3KSQPiEVi9PD+TiC48LoTY + bB3QB/kiJ6Rti0aXOZQRsb2RS3Dx9BbEwCpBa28gV9NyPl0wsNvnqbZLTQjysLHh+NwtZGjFOTrg + YJi4iTbcxTXcJTlW8mAP7ANK3K2t1QapoxQPFgFtbR7iNjO15WHLjHC8UbhEyhDtwgvxARMR6d+1 + xs7JItDWfAfW7689xwyIRXy7v56TKzCRtdSQ+kPpqAce56iBHy3wNlJT6ktHbSie4QO4X5wYgBbh + 1TrWYYeGyuAa7LGFjy14bHKAdqPJCxyo3TgWxRYvdkWxzYsnGTFcSYL+egnyB7b764z2xSuAaKsn + dQB+87HSUhvAPTy11E6DV7UZ8Tcf8RvwQ+zCipUOK//zHQ6WFQV8B7iD8f4MSSzhkMcMspsUEK6X + FHBEPbWRFHG07z9C6dn7C2Rb2DKky/SW5sQ+HB5V0b2RUQCBsC2PjqrVkVmTz4aj5Ug9HNfkI1tJ + QYZzT7cdGhIdGtSaGP1dffZBFYGGo6NRMK7tAIyVoeSSOa45Ags8MesAyQyhD/T35RLM0Jr2fIsk + UJJlKKozUKVDy3AAd07kksAgCxrPyW049dzYpaHlg6+PrwgKjMaQc36ivhjB2RaSJwwLuSFuOApi + m3LxxYFjz2Od2GYkV8/6QhXYaxfHE87IWX8exKOqXLWB1aCMVZ/OPPdargLo6EguMmBMfW9uR/PY + wgwl9uFjTp0wntum59sxpBSLKXFXcWA7sziYrSwIwWPvxhacxboHwDYMu9Q87lFSFeIOE3wWWIJ/ + M+zDCLfYV2uOPaOjYEKNmVdU3Y+v9uptRRK53aP+Xwn6yr14IA3xTO/S9MlkZ3zbuI4ujyaKVNmP + C+UMkpu79pLqMfE9n8TDEJyf683IeN3ZjIKzjO2bbXO5X5am51j2fWxKLz1nMbXdvXyCjYBQfM82 + 1Zps+HMvhtzOC+5D+4INbx/WfdNcrZ1xswfrXtbAeLmXF4PdxpSN/4J1qnxg0NL4HhJVQSM44+jj + u6lwIogTFDWzwzswAK2jhFBBQ8MEGa6BkDDCerZgW65+riZQhb7VdH1TWbcCW5+LQXQccw8G8z6i + YGt7nBgfYTzDXds9Kr7T5lxyY08waEPnx7zhPjeQ4nkjAPdaYLC0rdDybjmHtkH5/IvhaYm7LE5s + EHCvYJhTG/OO2KKuSw1ww+BDR0HimHDJQuv13BkTQIkHHdUSOaBXA5JxQMkcO6zi2SG4QcrJGiTE + L/T1CKjbvhkvph517dt9i+Lc+2Q7DtmVKXq6UV+tMY8GLJk1Bh8Z2fSPF54DmgxiZ+Xexibg8YA8 + 0WP0yEFM5mRF4mVrzmQe+VZ8fZ04jvKlhq9XtjuDaRyMqmWtEy/zPeUrFQjgDg91mQ08ILYhGPks + expj+IQxh4iggFdcGo9HanMAroH4c2GzvHkUgApcimtaAP7pSZzWi5U0QTOEMR+BTIZuCEMwQe0Q + ToyWW/P1gfPNC1SBtzjRoLJ6prXik9iVkfIoOLkdBTISRZI7s+AXjkT6jKm+hzToU9flaqMuD4ok + njvEmD2nvr/KTzXGrY5NOjbJo+UT1HhR12xZQtst2IhYF2JwGl4QL4gzH8H3NdioTkwS+/Z8FLDz + yBA1Es8pnXjcEA7HBQolVsBn/mqu2wRkdwbdsYBfx3UQ7EDehyjF9IF33h6rmIhqbSSc+EDMPbUm + Jn0RzWteWXn7YUdqro0ngaYXLxyyCvhfn8GIa7i0zaC1gAwXB38TpVMB4DnboyrwDSucEO+V59jx + cHbruOOzSI/cMIpNiszHQ7xVMH4SRAGNJxAYeR5ECsYUokJQ2JJA6GVREyOHOSrDviExnjeiNgyY + 39EtPPnUnIK/AgUuiTPbEtthquJpBE6M9YEhbOt/4kbbtft0ZvgYHAQAOcYFXPRIplcxPoAws0yu + QeQyHCm9kbmjXO4Rt7siQQuTXm9hHI7XdaW90QMz5guG5aweOgh7MURfQkwAA4eiPvHAjTypskHJ + T0YBD0LnxIjBE/G0pMifzYaVm8o8HFR5bFKFnjglRkEm7ECI6ckeN1REMCX2DFXCjIhPRlx7WLQP + HGsjNR7J8SiQk8yA6xHo2mgeU7AXA8AuF96S+gtDRhNGH8VWSZi/FAwH+DtqwuoCCzrOXs8H/wrm + ZAeMd041Ykve/UIdb/hOhlgu+E7KhIZJRVVs0nhB1uQFuJkekb7w8I8f8281DTJ2a1S8d/EMZ4p8 + tr+tL0kKUOinme3u9k/R9fqTWxWenBXbzUm8sEiQkzHILN//fahArrgZEtpOfz0lQWGzP0Woq7hP + C4p7QXCXT2UbPG+tKinWy4807bCxURysKmyq5PZ2il2ANmezvwY+82NJNhCJYmt15UqZKQvlGoBD + Y0oD/q0QfxJo8BGxt6bxoAEqsq1Grck3v3SEwb1PBbeMA1GqNXJ7vmL7HA+JLDxyk/CYQ2xjLnA/ + l/WU19caexgu8n2vWV+xYQwdh9fD+nispcg2uEuJ1fm6zQZxX2kzrT64eqonXF/hBqkYpaYPr8Yq + qMmoCq1FhO26PnokILiYFoBi8ZQxlqBZpGg0ATqs1Wbjwf38P358LZCc1tl2YlLUUJy5TsPGWM5v + iWcDxya+H80sjjEgp0JIQTabZPc2I9EqIZGj8fjxI1bLhAKc4mNIg1DOiDNqZ2UsKNfD5lju76ol + 1499wuRgR3+M1E6vEq7bu+RbO+RLsO6g5UaSYyUPoPuUzDabgv55XXYiBSHb1hRON+LRivW8eHU8 + DShoHmtyyk+6XnETzRq5lYptdzRLcB+448xQgs0qRE4mfNVGCmeSfJaOpG9vMiGWYbi/ezpg8B/i + dHWN/rU4dHYYw244vSQhnk4YakDDj5CzVQ10+OxJ5ocWZgaXa6tBVFuvPzlm/+uyDM7rbxcf+WGV + OO2gmukZzAGpnBM1WDh2WJUGEgewNEliD5PkYaoN64o5vvOMxNLwfCLBpQGuiWaBhaVWdPS/o6AG + C27tv3GZlphfmGgaeFr9kjNyaXkgNA3PO7DRSjTbkNdTcESUJcFVCydZQifmeKapZTfkKbRrZiLx + 6cZip14DHExWqQR095x4Sy4aqcE4aoKsXgNiNUOuSQN6u4CQN4A2A0oLAnRxM1tx8IKUi0sDvUH/ + 3h+CZZjmFh2FMkukWuZbZcoHzfUqgd+o6fnjPRWwvEKU54LCo4Ln322vcjrpaVOGKAyJMWWwOziy + pqoJ4mCd17nOQ3P8KO8+sUIzOBg3LKwZkKHkOealVINWOmBAuVUSrVpowcDVdIPzKRGcyuXGzwDT + ZRKiBp/OvRv6FQTJEd0pyxKQveI06V5x5pr2iDMV065UmcUyaqyYg914UYjhWGEmlskwPzdtvJXS + L3rHkj57/OUuFHhMiJxSBUFRxst0kBrRCuOvTKtaGZeQJ4BrqCu2DJPONUhYRlFAQQAEvo8tIIIK + +FKHkkJwupxCwlqKJF0mCo1c2yLeTBWolI27jkfRCkgR1rL+OjkVLAlnc3coClcnnjTYHZsGoBkg + gfydGFbBcavJ5R9tndwK6gujyd8UKiyE+Ya0fxyzA0xYcFzLnvQlfsVUqgWGT6mrsmJNUpLrpmkD + L0MLODn7E2bomuspkFk7OvHx0fEMlsrjM79g5Pk2OEQoYpIfsScwjUjAG95iBWEFQK0YDLvCCm2B + tqKBpNjBcwzQwVEydu3go29PJtRPa0JevgTkxgy9avk5KAYaJWJUE8FA0ONQH1aNd6KlwiUT+Ww0 + FZdSE2+z6bRiUgPS5/QmW+GGFswhG4UCIbbt+dhB3LbGGC9CTKqUOLkNP8tGrsRiC0t19S4mBZxy + Jwy7uJWc2vPFar3JF1V21Ut7ZAdvyJvqm2iugxcjaMLyWb7Urxd6JSub6IfRhbogeFOC4Korn+FX + PwtQtsIL4TD2sp1cIJPLoKYEjw59FQGqmbtMF2W8rb36gH+hGwzf8OYLh4ZUejCqwoyG9TJFrEgv + 31684FfWz9k7DpKSM6oSb3FX19KJvMXQhgPt4cZz2UjZ3yI3oOOEFvh5gEju4bmEwIO4LmOb7yAo + Er4cIpXabB4JrvcKXmXMjSebIHvNBnrkF3EYayBuaSVhdWJ5WzdqICzP7TCU3M/g2Wn5RR4iQ/L2 + gFko797dKKGxhwTTJ78+sk0mP5Fhuc1inMKlkzt78RDiXv6SsJhdjVOEwvprdtWzaHllFBPvLfgq + taQEJo3t72P99G6LYDBs1btHO7DcC7bSi148ydqxwCyaqecTnSbfpOFNxaDKqtp/bcpZP3us5Qs1 + Sa1LbPODbF1PrObBwMp2KRw2IA7MQ42Rc6SYC7v2w2alhrABGF8RJs1Ic8POLsGZmHuX6ojgwm3M + 2HSm/v41dwtwWwKmnEaMg+z63j1IMLvgCaqZ5H8KuK6E6QkybXGWrG2Cky2CU0hOJ2m62hep75WW + yyTPhhLQlxTIYUVsOsV8VnS5lGS5z2uS3UWse6QdNs624Ppb5QQdW44z3I0CbtT2VW6b6YpnRXWI + gDVDxKs4YZWhrtCUwysZfKy+c/+Q3wgWVxBxoLNkJjjaUOxoeIGKe9JbO6eCowpwHUxtK6zKCgsI + fnTDatZR7GLLcVxP9muTY/Yvw5n0ZgediJZrfq5B8Ifvh1LuvAK8B4sNrqYXdydOtTpOLGfnHqen + VfMI0rTgrFB75dkuM4safPQl/JZqNupkNvTGHNNCw+dNmv8u2I5M3tGL65lVVx4gqLZg4eC1xqLa + AU9VFts3H31twS5J8ngKfczjxz6YylONCek1LLVh1WG3ZeMYmzUcahVBNI3VxzEvaMx+ZdwExopB + th93La/n3J6AtcLAWeW1PIDYfngtBlcE8BZVbJ6LJ/tQazKcYnl2C/ufsosnFCJ+zxYTmt+M228p + eIPZplIcl1nFaU+mKuQUix/nc2raEMzgZCcTwt16MVZheSKXaKm7Sl58E5lHVc4vG0SoqjxMKSQn + iUGXhqWpOxNdhiQBH+8koARzzaQDX4txTZbmxOjzayuXx0pycZLflLpstRVszkrssDIrS/2tuPbu + oTBTGEoh0S9FgzS+M3I1IE2f3R0FCkTl8aZnGNFihQYjbY+sURhZY2tkjS8bmeWQYPqHj63Zy48N + SoWxNXtfqDXISB367QcnbghcNppKMoIv1I7pRfofMQLIgR3PB4pfxDVuFwDXJnXI6tvxLO6Z9MFf + KLYX4PfvYf8exkMvMqbUvSfhK/B+FyaDuAZ1vu7cSi4H/wul8DXV9y9V11djNFvI1wXXuZ3Om7kT + Jgg5QvqKv5BRlUz7BiLttFX3zBWufGBLL2CFBaahUWW71T98vDjXpKfi7TD+Owa4Rtp85/Ho9jCY + elJNwjs+N/QQ+IFCMD2omCQkAIrvivf5G8zsXdHl/NKyLhfRZat1aTkHFYBOfnMhe9++cXD6FH/o + ZF7BWAQ7eSY9qLDIRzuAMMgNoBk4x/fuOWun/ISMZEOe0FCM9/nqR7MqFSnD8AlI2IiCKj6xX0NQ + TTvAC1Ka5HoulQbiWgZebCpNlCPfgZBZApRSDduT/eVSFfMtTrmAVMIcxPHYfQYlt77v7svsUyRh + 42Dv2+7lEIdHw2chINejEN+uYy8zQ87GXy0HFBC9iRt66n6jILvnlpwZdrYiXXhRwJ8DwEjZrnpW + V03MP02ARNSk1NP/WC3faU72m6GirrC35WAUqB48vuYIKQ9oc6tr4fwhL+bsNzf6ol5oHmUQUMcS + aedSK3TLGa/0uWp+iNqKWkElAhmcN332SyF4s1nBF5RhjuA7yoI3YTAD9tsXoknaa8N/InVu8cr3 + S1Nec5bJtCOrS99GuWUS2vMzK4ng0tOSA67H0slSkw4GT0dF0eZIp7O1GBVtT9iiIX013wFZ0xJM + W9WdiN1D81fimtJS3Wu48kBPuTZQ3FVbXm92sj7I8MT9UUkWuPAXwS48kzgvbeJ4k+rB7jQSiA+Y + TpUDkwHiL8eciH8DXuVQK0zrkspf+A8nidIPzPf3GwepixRzFJa7fDD3jUSdyIBf6ABxVvNcKd1O + /V6YHsIwlSUaS0ay81r1t7GXHbnie38sqCgwxLZK8RrbUMKf9aHQh911x+doIY03d72jvz/+wbfg + lW+587DBIW5tKDxoHz099pTz75/u2VBPge/cU9/ZDc+dRAYPPImslXqt/G79HmPIHymmtz6Q281m + UL0n3C38XoRc/M2l/wMAAP//I/J0KywnZCSmFIMw6nFWCvjNs1PITFOATz4VZ6WkJhUn5WVkVSjY + 2toqIC/6UKhW4HKyKPAwSMx0DnEHullBoRbppCgbfVD9Ajp5DFTD2gEAoaUdTo3sAAA= headers: cache-control: ['private, max-age=10800, pre-check=10800'] - cf-ray: [34d76c352fa81ae7-DUS] + cf-ray: [4a9a5517d92cc4d8-DUS] connection: [keep-alive] content-encoding: [gzip] content-type: [text/html; charset=UTF-8] - date: ['Mon, 10 Apr 2017 17:28:28 GMT'] + date: ['Fri, 15 Feb 2019 19:55:30 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] - last-modified: ['Wed, 19 Oct 2016 08:34:06 GMT'] - server: [cloudflare-nginx] + last-modified: ['Thu, 01 Jun 2017 13:38:49 GMT'] + server: [cloudflare] + set-cookie: ['__cfduid=da85e582cbea096193c16201e58b531681550260529; expires=Sat, + 15-Feb-20 19:55:29 GMT; path=/; domain=.thepiratebay.org; HttpOnly', PHPSESSID=ff2f3db1a851a454595c7453ac4a3e18; + path=/; domain=.thepiratebay.org, 'language=en_EN; expires=Sat, 15-Feb-2020 + 19:55:30 GMT; Max-Age=31536000; path=/; domain=.thepiratebay.org'] + transfer-encoding: [chunked] vary: [Accept-Encoding] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/thepiratebay/thepiratebay_daily.yaml b/tests/providers/torrent/thepiratebay/thepiratebay_daily.yaml index a7b5093b5a..7e0e6c331b 100644 --- a/tests/providers/torrent/thepiratebay/thepiratebay_daily.yaml +++ b/tests/providers/torrent/thepiratebay/thepiratebay_daily.yaml @@ -5,269 +5,252 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; b26754d1-c49f-11e7-ab95-1c1b0d9d2a41)] + Cookie: [__cfduid=da85e582cbea096193c16201e58b531681550260529; PHPSESSID=ff2f3db1a851a454595c7453ac4a3e18; + language=en_EN] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET uri: https://thepiratebay.org/tv/latest response: body: string: !!binary | - H4sIAAAAAAAAA5xUTVPbQAy991eo7oF2Ov5oCBkwMQegt86UmXLpUawVW8N6d7urhJhO/3tnY74S - CBPYi9eS3tOTLHn68fzn2eXvi+/QSqdPPkzjAzSapkrIJNFAWJ98AACYCoumk8uW4II9CsEp9pBC - NDSocdnvBehsEPAUWDMZgSsWsd7Ha2ChaT5wDHwdCUIr4lL6M+dFlZxZI2QkvewdJaCGtyoRWkoe - hR2DatEHkmous/Qwye+INJtr8KSrJBB61SYgvaMqQec0KxS2JreOzOCtKSjPLlq/LjudQOtpViVP - IrKVeSW1Sn6tTLBedgIv5JZeU2iJ5D7/SrgK4SFFLi25FckV9pn1TR4EhVUMygfHJIuA5+y1Canz - NCOJ9d3zhd7UdxVmtLRKs7rOlO3yZEeCDvmdyEF5GoJ+H340nhxmjR0pbed17MWuQOetkJK0t3Of - Os8LVH1mSHbFo7Gm7+w8pIYkSt4ZWIdYavCLt6DCfoYd3lqDN+EtOPE4m7HKsF46L7cvQ1UshhXq - V0ZMFrlGoSCPQ7sa1c0hHXzxZMManNrl3wdbPB36hk0JE7c8XnPccC1tCftFselZkJeoL0XNjSmh - 47rWtB7jsK7ZNCWMNtFXqK4bb+emTrnDhsq515/3tq8Rd03Oypo0/lVC1vBs78tWRk+OUEpj725b - A50NHDesBM9N+yTu32PHapIf8ausN2xmjaSBb6mEb9mIuuPn3huKnCWMi2Ib8TkFtUGsrLa+hE9j - OhgfTF4FYtnaBfktBEVRFEdH67riRKT/AQAA//+sWUtz2zYQPtu/AsGhYx8kyhKl1jaFGT/SJjNt - rIlT1zcPSEIibJBgAEq2pu1/7+DBZ+RKkH2RuAD22w+7iwUIxiTiAptpL7OYCEYzstGQ5KII1x18 - jWFjzsi849w547jodrS5f8Ep6WDaPOkVPD8Do26ulL0hLwqedpKpgb2i5Fk+0yJKNgZLrYwzkHGR - YraRdCcHupPd0N2KcxfZMAs8bbhcnnp/AlJE/7dnPErv8fuSiHU/pVn/UbZ2nUe8wgYGosAzT67o - RR66w6qzwxIvyBQ2xr4GQefgqOB5n3Gzh4EPUyAJm1cNx+DvZn9fkJzhiBy1B53/W3MJPHNiOQxC - Hq9BxLCUU1isytoZ0xWg8RSqUURAdFhFIphzkYKUFAmPp3ChtnE18DsEOFJmptCTXqNKah1c1l1Y - mqLpAqKApottHlbFqshDxhf8QaYP2VrVK2Pz2+xSNUOAWTGFPx49Ag93eISoSaVzdDEnMAlRp0HB - BF6IfspCmZ+b33/M32FjaqHgz5JUqJdabKB2GhTqFkRBIpIVFeJXLZYAELXlXQCLVT3rb3dAJvxZ - QlQ+7QCQLiWNKog/tIT03y7WeV5b5zk4GQwgsg8bQiVUBGmWLwu7LspTa5lBqivkLxWmDf6tHZbh - lOi81Gsh4Swmogp2QgTp9/sQrDBbkimEtTHb0kGzFJZhSouKghHDZVHwDAIFoVm35sFwSBiYczGF - eBlTXtG90FJpVeWz7TfErcAzfWZs1okzkV4wdnR8XrKKEhI9KU94SIMGnjbacWiDyIrGpCZyp6Um - EdtviFjBkYgG3UoE57msHVK/h8i2X/Qo6xb97OqVBvJWTguckprUb1pqsrH9ho4VHPlo0K1Eci6y - OrmV0KRheg0L8+xIQiFu5cCLhIiKxI2Wmixsv6FhBUceGrQi0mYiCSORsRThgiy4WJfGaplnUYKz - 9l56JklhLbYnp2G5fq0tV/oAogvGAs+0bh6uzrg50ByrlfvDwA3YJ4OTqkC+hr9RbQjNWgYh50/S - UXkE0a06k4OI0dxV2Yfo198vrty0Tk9hGchX3eiVftzBxbYm7WJ7qF3MV5S4zXSofGz0wPXd9VdH - 5ZGNK9D10dW0b03vEaHhYNzcs500JxB9wlmcEBY7av4M0adr0AN7OfoXq7wn61OIRtduOu+dj+29 - aRcKI5WWf9Esdp3vSOcljhyVRhD9+eXzvaOWv2dCjFQSfr65BUd0hmOPzhKekWNHiAlEF1ksOHW0 - XQUX3Ny+U3ztNr+LeV8FduZWH/19YuqrmM5uXxyVfIjuL2/uR5OBo+JY5St1VNq3oviqorwtgXxV - V/ZJIP+9q4M5nO1ierznZjV+y2Y11olEo2IpnM36sDytOqmN998uxiqn9t0cx+8dWnvk3cX2RMX2 - Y8/9wDZRwb3iKY1c9faN60TF9UpdeLrqjSGaJWtJQ+Zq8g2RCTzzItB9PWjeDiQ0jkn9RoQXBNYH - /PJKfwdNLmIiwnWlfHra0g48df9lb8m8mK5Q8KHXA54HYro6M9dloNezTINkiAKZ46y8/RkPgPnK - EHi62dySBF4yVHdx5a2b/aYH0eHBwUHVKp/WPX1vatoPQEDnQt3/brlBk3TwkaaDpUde+EOGPfm0 - HvbVh0JovkhM4clkAEGir15VjAcQaOBQ+0L7T0aCM0bVB8+MQ/QfAAAA///sWltv2zYUfl5+hWDA - bosmkqgbJddWECMpGiwBuuaGYRgGSjyKhDqWQNG13V8/kJQsx7EdpcHQAfWLIIjkdy4kv0Odw4Gh - RCsFpRsOfjt4hU4ikwWs0qo2Vn1caoktv9EyeJmSSyeKSt5R498BJ9EYlESZ6fkC5XQsPTzgYjZl - k+z0CQiVnh9wVieAlulR4Qaeho9SbWqiDdNAtmE2/9BCXS1aaLJ8G4qnSjDytIER2tY5Jlk36GyD - 3oQsigKdUDwFsva2buhrm0E2qndTjHNCgXbC+k2AHW6BcDdBXGXfoROKZzVULHlNpvCHnVmacTgq - CxLLQsKMkeLDVis3mnlzAVQTrqlelBvlttqmJt6oJgAFJvK+Z7tMDDaNvQCIUzn4Qg5+V3HCygQ2 - lZROqN1mMFudBtUguuhFWhyLl6HQJJvcj9XsGdppPo3GUDOFhH+0WEgUsSaXXdny4/YPDAG4Q0Zj - 8ysctSZlYHAm9pzBVV1CbDK11+jSj8D4dVrtNUUNigfXU/CGZTYKXOYMtITlDxpPs1JbZo3qBCWp - crYS6e0GKPd5qNUE+jvFiI1+A4PTypLwYHVdVNW7TvjIhOoeiIH8IMDINo3zyVf9kpSCHU8m9zAu - 9SsTnZmefnc20ueW5xxdj67+As6//d1ZgRZl1qXmp8BJNi5FSk97CV74gs4yg1+FgqU5D+R+Arx/ - POfDKZv0I56lfSs2fcvCnh9bDgLboxibCQLPpLHrJNQM7NjzXSfo0cmwlfyuOxIadN3THmfDKS26 - 9knX+ti1PnJG4q/A9HG1+I4KwgjNShChqGufeIEXrI/5DsykZKHHadc+QbaN1zuICzA6hYd8kmXi - usGWbrXsOC8KYOWUJcB0/nWLVJjndFrqFMrFJK5QRb9mCvPZRNCwWnv1baFpmU3uNeXl9uU0WftX - g1QxTdbPLuUHbSwXjiqeNctyWgIzhJfbS/mWFSvot+efm4KDeK/DgLwTgVAx/9DRqlj+xnxTK9BS - FkJzhAq9mNx3qr08EOXklf0givxNKNOuc0oWilKR13ftQxmsNNeydc9S3y+z0WEdYwRjr2E98Yyx - XvpT7hJPRXhCozVG0GQ5fNipjnXm8001UTZnEKKOK786VVrIuE5Bv82zGPQrZJ8h50cpsg1O2KJT - a0pMkBdH4CLTCnwAMGPkYBy5DsaUOqbver7jBxHEghJ3yt1T4X9OheLOVN8wZrOZHmV8nDOqP4BR - poSBccxAzI8qHY/IoheRYeQHGEMvzodJkvTKdOjfLd7f/PH7n3h6Ovpi8xsaoJP0Lj1/eD8b9qZs - uOtuWi95ZgHUq5wTdg982PknGpOVVf55TBbisF15a6QMeJm7SuW0KONzRbjSZRL514sdqG95dewI - kO44Py12IMvZ3oj9J+FjHzKQZcqQcUkWOdMtE+FXHq1bg4Vte7aOIIHjIJSIH4YEUYTNyAVAtmtb - hEKAMKIepYCpU0eQ3cL3YWR/on4lK1oVKyLs6PjnnaidHaRoof2ZejdBokARpLyNrl+ZwWvJ8Tmg - sE2v9sdq6oAbuYFFkwQ7LoktFPsxuGYSBbHl+xgjz8EmXZLiVsF7QtwT4usIEeElIdq67/4vCRF5 - +1PiExI0fc+4TrNSPy/1G5F/tM5MrH86vb5V7HB1e9KS/3ZjhM90WGW9fwEAAP//7JpbS8MwFMe/ - SvA1WHM5ue1hD6ObVZQNN3RvJb3hZVNcZX59abOKOJjZ2GSMPqWE8D9waH7nlo3UU5SmiSVEgTYk - 0zpLAAiFwoKQhcyIAsmZtqtUcKPNFnZ7ht1OrPkXQpEONCkbAxawHQrZ28X4wy5e1iC12j/rrj7a - bujhoQVwMZ5VPaJhEYyaS1pXevrHFR88RZN7L3p5i3V9T3rzLKMguSGFUinlBpjlYLWlhnHNKdGZ - ShUoUtiKZ77GW7AdNIubLCe5nZ9gHkc6QBpKShXo7SHpXLPGyMZjbt0DIY+14af/lvr1VHy/aJRa - iKqojQczWz7GYwJ9ImJKNBnFD/3eeXgTh6GIaRzFTIJvZYtqNeTUUK2GnBoKQ4EoilCl1vU+6k1H - btOE5xkYrqmRiTQ5AZAmAWWyLE9ybY1KqGKrGhfX1rGzjmvr2FnHYSgwxRFmElo8HuvwaFiWmF4P - e7OFzXt9m9wJni/f3qfl9Mp3eOT5rx7fCOl5bl8/i5OMKvy7XRpI6XYvtwgqzjNrQaVxmFu9B0lC - bxgkqTbzduHlCwAA///snVtP20gUx7/KviMmc585fYgEIcC2AbUJou2+rOaaeFVi6oRm00+/sqER - WkoycaoNaOfZ4zN+sH/nP+fm59wLlp2rcjZBuIkjUo0UxbfovH/dq/WnOLwIZ3ezuUnzLCmGuimr - 0qMHShoLArhUjGkFkTmFwUkpOLesjicY5qlWjT9J2Di7kqy0WzLxh9ImQBCQPUttwp6/xnLY9AkH - heKd46o0HvWK+RI1akO1zR0lGeqmrErmYAjBGewgGOMkGCFDAKu1j9QZh6mP0oEjQdYcXL9xzh29 - fFmt7pbjZfg6M+b6TtriUs+qo0G0bxfhc5KsTnvTc1HWf+U7KHnwHYxQJPZXfqDIGo+is5Te4EJI - 5+gmVIUzU3ReVlVZodG8rOpvTPUJRsXlVX94eTTYRWLvtEF3l7uTXRGxWkZtVLRRRa6lrcuCRbSe - SuYjU1QHrh1vEnq7PFB2T1mqt8TtKiiOGVL7luqUJcj4rNUfgVaoziCYCRqGm2JaoJGrpxKXX8rx - EpmpR/NJQEdxHqobM580hQKEoE/fipPDo9OzJMq2t95tfWt67ay3WEjrSGRCS88psQK8Elxpi4Mx - NBIthWykfuunyXDNcG0HVyIe4MoB9p5xJLDmWq6n3cRZ3jk1szm6RIN6mnfdv4M5qlMwbeXrFua6 - 6WvTpWlgjlumuHPAKBdRCwGBaw9Ku2iEDkQGZWKNzvTtMyszK1uykq/yaIxvn0f7pajkOWC8FRw5 - +0nAeIeTfbKxburK9CSaswwTjr2B6EigwnDKLPbYKOeVCgGi1SqInweP8+k8Q/GXQnFV2AsC7f1w - vqZmLdcWrEckV7xzYr4FdFb/HWGKLkofqikaFDHURfxnZemLWX3yFH1MmwzEpM5AfDSDCzO8SoLm - Dua77e/dojqBaMMNMCkZl4oEZ7mzjLIYfCQixhCp07gZlND+cTJqM2rboRbrB9RKihGV+z6s0+ev - iSxBn/CVAe+M7m5DNS6qL2iEWR+LnU7nyca6qSvTuyaEEZpxIqmBYMF5zJiWGKixJhAtI7fMK4ab - ronEzTMXMxdbcBHDG74akiIAAds3F3UCM7MIfQaSWnZOzM30/k9TTXsVedRe9e73waA/HP2ZqDY3 - 2fmtlpUbF6XHKyOOgDVmMliFjTaBRWwiM4xGwTD44CAI8qAfN+17kIH4Ugu6zhcHH8YntnLvirv3 - i+p7uYSrnldvxTBtyFbKm/kS6rlebENxDf1V3EEpBHL/DcWE4nVBWcazJn6Ke8XXF2FtPwlhC3Pd - 9LXJPkAK7LQT3EYViIRaDXstDRZOWEUMWBcx5lZvLKfKoxJehSv448Py4noAB6e31eSvz2b86XT+ - 91f7fXE8GCe5gm3e/uwR1nsEsmqelojSF+ARtJbPX5X6NUSk995RzRh0TnozNAjjMPUzVEZ0Vd7U - H8viR0DhPqX1bwmVdkZoZbnb6rZkH8KlphhjQj1o7AxXEIMGFRTXQggKhAgfBW1mUrR6kuxO/i+T - dzC8YfCARQ2AqHplk3cyBe8pSFmnNzHTei7z/Sit5sv+2D8eFreI9s6bUGoTVD18P0pTytvY626x - +DHn/gEAAP//7J1Lb9tGEMe/ii5FDwaY2Zl9Xgi4cg03aFO0TtCiF2GfsFG/Wjnp49MXpExFTmR5 - uWpMp13oYEDkDseE9ONoduY/uzkXgnMUNQMXFPngXWAuMdQgPOfeJs41JNPHyiOuX+n2SRPJR783 - P7/8T+aRSa41yqDhBaTsb81HnLy7Yf2f7EIGmVElW5PI22GJSrw4bE6jXV5fNX+c3541r+y7v5rj - 6+tbZy8uBtWuUT0GY+y1I07Ol5v1UgN2pbBCW+FVFAK5S1KbkGzCqDWQw9UUhxHXr7Csu25ltHw/ - mgChkVO3DuDjh2ridRORmNn9Oo6S40y2487P34jzkRFGo2LkEFHzyFICo0yMnDCR7/KwhCq/p7Xi - suJyT1wOjVaE2DA+dZGC2nGM1/hyNzxFVnzZFX6e9Mn71z+eH389QpGm2HhbujJfuYaRVwaMM4lH - 7iWTkIRXwUsunJfK6kRaIcsMQz9wpqrZ1EkIe2J2rc0CrBF6Mm0W+vzi0cmTnCionwhzen55s7y+ - WjanaNabGCsR0cJU53ir7egl2QgVTERDwIyONlp0RiYghkobTYxIYExGKpOGwTGjvKjcrMnPMnAO - KisGG8kmzX3yMcLjNTS9j1AoCE0/UVBaEo7mbx5FklwFr8EZZOBSRMuNDwoIyQduEgEkHsoC0YrR - +jt/T45Sp1alnu8Mh5oW3YJPYh/oa49Kfz6wtN3+fjbqLKrotQQfWfTRJhYES6SSVlLFZAVhYiKu - JPq2X6rirOKsDGdrfSg0qkExMc70GNWTGhneQ1s3j/oeHDZFhAvwdm95+/Cx/IiOR0ZcWxWCZQGY - 0g6FU1rabjvHhMgNWIhbhgNsXq6irqJuX9TRM2iv/wwTiJPije3C25hJ0o8ZaR87Ixt46LWAqKyF - ZI0H4ZgDBBulN9wyjlGGFGNKu4FX90yef5fQt9+8+T7+diSvDn/6czmfv3UvT89+eOuSeqfzBms9 - +smu6v9P9pig4TGBuqHJNpgkr1qp5U8L0C+O7eX5RZ8IDM1xd9+awzerbKDcRxiwwGw7fk2+ppXV - WgQd0ETXvVJ0pCQaboUUQWqeuCWW7jRUx7pRnzg12C6kKFtrWVHRPPCnSpOyGmxvwafcoqY6KlW6 - Y3n78LH8MqWEwmlGLHljeIrGe5Y0V+QgOfConUrEotmukVrTphVv/xLeOMhGTy1JhTt09WVtQn8c - eMzofqz3VxfW/3pxvrxd9OKesh/tfbM4/O6XV8N8bzk/WXQh0qKvyFnay78xe8732vxsZb6fn3wz - 68wPQ5Tl/GTWmZ9tmG/L1+bvQYFWMjnPuAFm0TtyZAmEstba4LRNziZCMUwCX7tzsHKnnwZ+c9C5 - M4wEl/OTg86dg/fuVOBO05jeGVz468vLeLVp8fWmq2d2OWOzu5OWzfof233Sk7W5w9DmLpRpdEHh - Z/8B/Ai4d9+w9Zdl3013VYs/H0Cs6HQ+FplqFmVloEfzL4vtt3sszqYsGKlZMjag9uCCReKCKw9e - kFUESUgAQiVXyh9foCr1qIK2lomWYVYN2U8mGj1pj/woHZH/c1D7DwAAAP//7J1bbxs3EIX/St8L - UMPLkMOgWMBJbAfoFRGKPha8DB3BsmRYstH++0KrSokBx16ubChG+Cxxlk8fDskzc75GXAO9qD2b - h9Wnv/ujr3lmQduX/mFbukbM1q8b/uhGjqgktBp14ULZSCxIHNFZLjHmWEAHUDsh22/lx+1Wmoht - IvZl6ar2IlYK9Y1qWNk07NeIqtzk7e18LhRIe29W0cMqTFxd3g27La0t2tWuGH6zysmEYCWCUigB - VClZaeeS146LBuUSJe/7BtDaTTRyNlU6gpv0BneHf0k4KgGgqdJv4FkJFEx+Wa7W4mSRxdnydpH7 - k6yEQ97jqwp2Nf8e3vDJMrpUNHilqUjtnXYEkQN6djkno1OAFPq0lJoNNFy256lxvDT71GfphTl6 - 7PPrC5I6utQEgMcHOD2H7DzoA90hq4cnUUkwBYr2WcUMgIZCcCqVCNJycEzGoA66PDnqqUnTJk1f - BLWw7yog4dQxpal+pH1KNcvoo8BF3ydTLdJscSH+2rSR96M51uFmJf6ciqnCU/Di4+kfJ+9+rnNC - VRftalcMhmliTrqgTjqRihiTy1G5hOQwB2PBm+STk9vnp8pNNIA2sXooQfcDnc6bUfRVQJOIJtM1 - 37E4uV2tZ4uVeHuzvOSFmF5urgbffQrzOS8ueJuVXGkhHVW4G7NqMEB1ytlLhAwc2BrJBWJyJuWs - EniLSlpyqPqJ9mM20iDaIDoOonpnSJUCzJEhWjWruanQe0B1anJ+c7shBfjN3KLP2T6/nv0urq7N - IHQ+UaJ7/PeK5iO0SmKEZJEsaDCIJirpLWgl2WdnNNE2DO/xTzbwfTeJRfRGwxc5HA/3Bs26k8Vy - 8e/V8nb102Q2iDq+ZnZIIw25zWPMHYuwyOLD7Fp8WF6LKdApqINS62trdpULKlLWgpOWSinSaFYl - BfSZpSqerTJK+mhL9DltX2Wq9tBo1WTaOPSp3UO28ShAvaYZJE2o3cMnyqqTb/UwptHFu7Erh1uE - 0KtkE5XINjnpILlsIHprM0kwCYIO2lOqPQW3MU8Nsc+A2J2D3YITII+MWNMuFKuwamQ/Iv79byfi - Pa85rWd3vNraC+UhNqHqol3tiuH43LRY+uyhKDYlR1C5IJPfjOqI0WXlbIKodw71qk00bDZsHohN - Deb4ylRijWeoSdN7DFU0OV9eXMw5Lv/ppddNmM+CmILddA3+nyxRf6dYV7Kr+//wRvUcyHMiZ4y1 - GooBMJK9IR0RkIL1LijDvdmybguNnd/RHeQ+3dJsxrg/1x2kbDGVdagC38u9vglv00litiN68HMy - 44Gar75yN2rZYH5FsJpZZ1nQ2pRK5KKRAF0pWTNkTx5ihn06UPVOGsaaBBzJxH2EJVghjy0BDbaY - oLFcdYRPmRnpJcyMVG1mpNFmRjC+SEsaVEkKrdRUAmdniQ0VJpaIoTDrAWZGambGxtBnYqjZmxmV - +3bNjE2MPgRNM9gBPnL4/AHlu/Frv0TqfwAAAP//7F1bc6M2FH62fwXlofuwtUEggfDadBLn0p2k - SZO4e3vJSEjYrDHyAs6t/fEdAcZJfInJZibpDC9GknWOBJK+Ix0dHW2EVAdYvm4ZHCMMPWQb3Kcc - cOghzyQmMoGFOfN9265iH167sq+v/31BeJ07Z7ccp22/nnf2DcZGdj033QyzNtb2+hsdmy3MA48+ - Hh/vn19s6f2tIlO3KsX2hpGmzpBJAHY4dChBBGJoMWwSHSBbBx7RDUgBw7mft2qVqKHzrd4C4l2D - gfgajSfW5/Ho0NgTu5+u/zjaGSdsuNUtINVHxRu4FeQtK3nB3NrKQLgNnuGE/s9YzmrGSwKjSFfd - IrC1TsO2N2g1DB059Xn4dVJDHs+cRCQNRJRfWgFe5Ax8ZaZuVYrtTxcZnqVTiwKP+RRkKxKP2sDh - 2DYwsx3MOeUc5lKjYiVqqVGfb38ehuLSWN9sY+utnm936ln3E/iJsp22/iyWY9xvn5Jx+2MSkswJ - EXoB66rqnN1nkW2vIEa2TqHPIMUcYQuaiDDDkeczgQkwRrrJkfTNNN9pq1yTGlNrLfEzQdUuT2uC - 1z6tCTboMgCs9cTLUGqtM1pYWqFd/oSdwhIzZZ1pwnLOCt4+IUU2cahvQdvAlDEIATC4jqnFmEU9 - k2AdMrbeGmGp8Pc1LL5VBYU9Tr/8oM7YE1fsfHd/1j+mjOBTsXuib3dN6bYdtVZMPIH/5S4httoQ - vb5iQuLaBrUF/l+4j3p9JYWF1kiGxeq8slq7EkO3Su7t1dnM831DR4aHfWATavrQpCZEBsM6hoyY - tmNjAuB6KbG6ArWkeKuSwve0292L278OrEQ7s08Ojr/2943v/EswOvsJSbFuFNTSYrO0mG96Oqb1 - rE3Pl5YWwNqkikH2Q2HR7GopoSEvsUY+QzfLk+d4nKGRP7u/tFqKJoMdT0SpHECtlttsNjJYDlhP - 9YVIy5Vdym/SVlaVTg7nHyYkHgZRKxXTDuCTD6qkbTSUbuDHZMKfarkk0PeDiT7T+I24jIhGRZqK - SXuUTkJVyZaRPdU2sKqMuHzxnuroqpJxLpaVqq4qiReLMAyiYU+NhOp2tbzsQhxO885QSpNQDIOo - bKXjLOZmD9k0yr/Kw+wxHwZJyuOS4nye4M5DK+lCEg1nZMhLugseci9VynT3uAgpmvLov5zhQ36E - illaMtvJYm72WJWbhmK46Iky4srfTBrJjKWQl+2/IJNdgHiLYvp5XJklqrsI5wXKbvKgzKkIA++2 - pP07ke9WJLr3YysqXIDp7Lt5Te5ux2gGR9FVOm6LKBCLxhqcnqvu4PR81RszIVjIk3vCIY+7RWB9 - oXnHTFq+iGeTrHOWTA5k0hJ2ullyxvDBx+xqUznwsujjQmiQeiKIJPt7/E72P6vubpD2Rd77OkqX - LkgLmg4wnMHZp51YcD7ac/xv07sjBE7Yt8OzARz8CHx6KE9FPJUnBx5aTPCKSstalwOdkijicaI+ - atc4ScpJVBaeD4SLi+3lRJwkl8mEhOE96SoZFLIh+3r38EiRgDSvUIZIq/4XokCrZjfx4mCaus0r - EiuX15PLhKdpEA0Tpaf801SUqZjOIsbjThZTlFkcdpRGo/FONk/S0bQ0Jr4feG3CbqZxeienG9rv - 05B4XF5g0zOwY0P8a8xZEHMvfffbfwAAAP//pFzbbtw2EH1uvmLzEpJZRnuxc9OGMFo0DwESO0iN - ooUkGJREeZmVyC1J2d5I+veCorSrvThJUT/YmtGZMzOHHEq+wC2L4QXTlmfu7KUsVWvP5t60/XD+ - RMoVZ/7oF2DW8Vquu/CMahNzkfpGlezJaNQ8aRZ9A6TightOc/6N+VkpEvt7KIgq+6rjldTb3YWo - wVQpuvErrm/c1TaAokoxUyoxuoq/ssR4ayWNNJs184z8wyj712UJzXNIESEEBLJFjX61LBFosJbK - DNhwjBNUUUI9ewOiBc9gjKyt2B1TmjlXgqpMKmhb4WS64O+oZ/8JgVku+HiMKutPCQ14ZME/KCzd - K8yBI4BScnNfeM7riklxjK2QaMFyzUb/lblruSNuZTzktRWTtGk6RWmDFRWpLG7uaF6yU6LT4BM1 - Sy/LpVSwF+F563OhEKGoabCroV3A7vL/rmAvVINXbKP36Kz8S6qv7sVnJddMmQ05ot6/j5dU/y6F - eS/K4rfyljyFVZ/bF2WeN8iGttAP2oKYsu8aEPQogHDaxWsS7NwYGPlRJjRnW0er5VUGMNivAWDA - 9ee+wBZwKifAwL6RGlUmRioQ7fJ+bMUnW7vfklaOmATtXrTUMhvRp4QAJyR49mzo7HUEdU0JIbZ5 - 1C1PvOj3fDLiYkRRxTO430O3UDhBKPbWpV7CBDUONZD3cHgOOnAz9Cj3Fh3waJtmz7ndwPHxfCc4 - dRuEHY7BYNzsjoIUdaPOCBtMv1Ozahb7PbCjAyAjNGABj1rd07ahQYrtIMAMoexo1jOcHMz6rtr+ - ENxFDrrYBjaxy06ygRrcMEWNVDtF4u7EZbl7DsSLoekSkUNpYuRQSdl+R3rDRcoeyNQ5l1RfsgdD - Bmd6V8BxzDtynK0T8sWscXzigMzu4kEeiJzclATHXMFxyggPYT8ZE0UnGh6PF9uDsrvIaK5Z8zPH - 5m7ZhthTmzBqsFPkFNExvpOvaXBJ/e89Ywu61qRyP/dSfiXzVNOMKu5XBf0qlV+BGfADMHkDMJjM - 7KczEGEwBz6YnAMMLuwFaLAdDC6FxXtT67MBM6/FzdrLM3t5BjCYO8D5bO4MBzqfverMM2e+7sxz - Z77dJbNPEu1X91yk8l771S73p/fAB+fe2ynA4PJ6dObNZsAHl9dn3suZc523yS+v7VcM5tOpM0cv - W/uvz7bZ1uzwL7257fdPrg11yFct8nVvWNyb3rAdvfFmvWm7/XINfPDrl0+27G4vK3bLHthA9iCY - QHu80VAXXHAUTiAM0zG6CML70HsRjdGE4y0kKGTMc2ZoHI2RN+66/17MY6h9UBBOQh2NjwARDoCg - hX3mdCwAg3Z3gAgHk1BDuVboBHOEg23klU1hlTxFAVdcpDlDp6vLS0F1QtesLuiDWUpRC2YyJYWp - v1IrGKvjnH5jquvg4oDkectC76gwoa45c/LVOudFHVOelghe+N1S2KhjjueukAu/0HUIEeQMhfpU - qYqtpPgHQXjhhxO0X0CyVLLgZVFnuUxWtZLJqmC5qQueSsVrtubrJRWbWvN8VevVJuOK1fKOd5XV - scxNzZUUJ7fHDxYJGsVTJgzyxuou8EMdHZTvjXO+YqG+ZclK7i/dh/ePrtuG9rr9YPn/pvasfJQn - kYVM5U2q6O1Rf4dck5vJLQajx7mszqyWheD3LK6pkorWgeHf2L8AAAD//6RZzXPaOBT/V7qXxgbi - JO1uZ0qG8Wy7s7fdHnrYA/J0ZFsYFVsyenYMzeN/33mSDJhA0kxPBtnvS+9TPym94snjHzsG8UHt - h/i1AR/kulzIl9S8+kuX9VKqi3oG8ZSr3GiZR+MwM5XGzEgNL7H9bM27xPVSmkfj2IU9u2HdmEHg - qrw39pTTwf5/LNGbr/brq+QFEYGXAbFjj89LcUKIZyfSlWye4RAE7KYXNPDQvGdGPbDl1M9qYSJo - zNEKRN7f0b6/RZZsoNZrOXjCxFUwrdatMNpcKGLOQlwR5HfBxc/GnOIPsqChjYqfrYaXysCez7/+ - w4sRCJ1cNAu9cRrKTLj8Q5mJTnAQJWa8kkpjtpR07sCFUEpkWHFRaQZ9YaKWRdGr1cpuwJkKysb9 - PlBVW+gNguAVEWxxdV2JUjixGW/oQbWePkylybFeaqHk5lJTrPQPWZY8PBOP5oFNo7GtaOyG5WP7 - fZsd0h9rXXIjAcut2mAuy1KjzHiKVJEBecW3HLv3ld3z1ixwve4Lx/lW4/qVVCsIGbDg3NtCH2rP - +U4lM/FMhfp2MBy4zLwir4qnhMYnmjn8BBUyoNb4gUXv7hkE3FQ+Zt1rBvVSK0E9DTSEI9yv+07a - s5kzYDdJHMxVkwmWs4jGCdad5OtP5puGyPMdJlonVRDP3uNHVCFJZvBxwyAkoSTySRb855hcJb8s - mgVBmobB3W14PxTxqeTZ6pMwZnucalbblF6l9Cpk3Yg8PvS1bUsUu4MY8X0BO5FqwJqXFdOAa7XB - lOccjawY2GuOhjyClRCFdoFwnQwknIkCl/nbKpVcMYg1IP2hx4fbIJ7dh5cY7Tl9dcSntvpEjMbM - F/F7n3vR2Cf9kM3fbvHNl69Pdk1JuqLJNdYl31p0laYCCOadzOF9rY01/qHdp4JUjVObBUkcsK7f - 3u+6lDhfbUqVxG3aqqbFXJDyOKe73GQELQgshGq0Rm6yJQI5rONG4ELkNDlU5Az5wJEugsgbWSlV - u9GARuRL3uAPoTperk627Xrv4mVrcrQ0IYNT/xeqPV295LPM0HAAc9Yl1MA9RZ9ew/lAttW5fYVW - WR57eSx/4lxXEU9JSeCCDr26zq6Tx9vJ77sUcnQNY1Fuf9YIWc+plvA8GdPUHY00MBgF1qhwxMAN - oRXP8J6BO5YM9ZPWrKNUduNg5GaToOIZpQSDw2aD36bRhTI0ZLDkckUusUHkkpF6j532wyCesQhZ - iAzC/mTg/FjxTFJ4LLHiWRDPvtW6E6bOQgphqlG2S24wFRpQA7t5h7ySBafs1aZeUjhJsLo7qa1t - eS9varJzSIZvFw5JKUTTLwQepNFweKWBwPSWT32Ff/vWPaP9kPF0JaLb3z8pU8L48rvp1dWkEM10 - f7J9Cv8MS68pNhGv63Jr0Zy+CvsDcm9DaM/7v8ZKQ0hgSCPL6eOSwwDs3zNMI8JpO2E+c0L5Igvw - fFkEfLge/jabXd/tJiUtDUCVI2xnSLLbTZya00dTbI5t6QFEPpGz28n3yWpST9aTijfZUoB7Trgp - YMZN0RI+BXTRYAo4QI2zdw78Sukbwj4nBBmD/ze+O8J8PXxOl0QLqUR+RdccHsasCc+1lOHjemZ/ - zOtj2rWl9YBx+Mjn6/ltksz2zHaEUtLy8dpu9z8AAAD//6xdX2/bNhD/KjYwmGJFaPJa7MEqG2Dr - sJc2G9C8qVpAUWdbjiy5lJw2c/TdhyMpiYrlJA8DgoZ/jnfH4/FI8X5FkPeO3/Ew2r1PO613+EBq - Z8nTeJcE8AOkZ1ftKPSr63xuKYyZDjyMDu+1Yh2bQ8+GW9LY9++S6GX9F4tvlsmHUD8ndlWO5nQG - xcuEuk/iw8Sxy7xHa4/TCtDeCD1J23avt4OItxMiHBmLxVy3aqMsFrqIeBg6CNfSrqZUYN/iXxK6 - Ol8WZ5z+N1CgU39a1NmoCa3fnYt/eyZ+gusZW+MkjiouQapA3LXtaP1N25CRqhv1ZAv3D/Hoxalr - 3hSzAaOVxxZn8buhO+OiQ6fxUvvsjm7Z5AW+OGuW8S5hgnYb3stRwhWhV/1MVnk7GHGKw8vD+wm3 - LbPZ1RPG1/HUdTKGl/B99lE0mJ2QQQ3NTb4HT2LA1yVqkhbZQOf0+d4yDMM3v+qflNKgqf78fGOS - VTbbATyrpA5AgdEkqA9F3ngkIoZgzQnRhU1X2PI4ZFnybI5kzTE/0fHihEYbvo7DpPein//5WvuP - X2v/JzymiY4LG84FPaW3RpHbNf79c475Duxcdyu7pKctP5agP4K9NW6yTs6j4bPtPXtJt/ESs57W - 4tt2rbNeEU5maGQ1nOeJn9iFC59w4luxqU8eiS+pTyL4ccgV1Jz40ifRQTRbjo/ZrEB0TYlHA9xj - fF/FCRNZ9kQOA+2JwIfYSsFM2qwrqUrip256LxBZ9gey/GQlzEeR/7zfM3L6bNPAqGmE3GraMx5D - l5cxaQafnMFxlszd8IkNXBoy41jYEomYVEV2S/ws4RBpIueURK+2qyDxNG1xP3WGC4zdTA6wPyZp - yxTsq3v4HwxpGD1rywmSi+bM4KI5na4L5uzNdG5V7bFamq46tG11bPA6NtqJUzZ092aOsJTVODpO - jLkQL8+p4l0y58M9Jt4lFJFYeXmEmdZvalX5lJZ1kUvwQpbTQFalFI13mSr3l5RG+gCxUlomCxCj - y+n3bV6Ad9kgH0I66jSrbe+b/QKyqXmHmIpm60rtRbM6dVnBieusg6EYQSfeLDXGZknbNkIBLiZG - NxjeQQf+4acOFbSyTuMihUYHodvRj3981AlMJqtynW9WxOATiV9LBVAGuuoT1mEV+w5T9wlTUOf/ - 4hc6LyvWVFWRCoXFopL6Ux7LBmBUqRxqrOJH/lGX9lAeLb2sDg/bvMY/va5pNP4xFarmD1ATlte/ - 4QU9Wxl18/pG5ZsNqL6lMfXbuhHyDqPqdB4ULxoTZgw6w9CTKEA1Hvnb9syMZY5Kz2ZWAmSzppql - MMtAFkJBZmHGI4TWvVA5GmV2UHmlcIABc83wjnfU//+edEGuNbls1MoethswPn5JSUvHnqXRwK0u - a28Oq1PrVgMN9eLzvL4W1971cZ+C8gS6ML1ya6twNKo72ew4vF0EB4FICYGnLr3CX6vhgvLkemED - xkW1OwAZnaLaCkwdqgAJvCFc9oeyApE9fGlEA5wTWe0PBTRAXs1qtKNFlvWMGfn41+ffDZb4k4Za - E+Y41US0eG7o5EZ+olBriC5oU5V6priRQG5FuYGRPq8wyQs6Twh4ldZTapsXBEYQo07YS0zwvGcI - ZXTmM2yQi25zVIV7iHNOaovS6q7V0TSiRlDqvDBM4DPM1+k0kEfQ/wAAAP//xFxZb+M2EP4riYGa - Iiy7srNYBFLooC1aNED3rW+CIdASZcuRRUVHdoM4/70YHhIlX7tudhd5sMRzRjMkZ4bfZDi8/opV - iPexGwfmODKFkKeEj/SnMRfy4tqwcTqgk5O9pAlxlj5tFgtonK0E5r4KqGdX8w7NqHdvRZd3qk1j - 258jfX5aI0Qbceqdkc7c0WQ1QC/pZO1pYGvNOKajM5NBGlnVNapiK/llhtt+yYKYLyM0cZAIftAe - PNEym+HhcH+G8RRT32y1AMphRsPsOt62fZsqHaCk16bxSA22WxBcBL73QRlROLjDR7GcWXH8zO01 - 7H+BCDcWo9fC984MAt6FdFAj7f/ZCDdEr4DoWJIU9ydc9SZck9hfNe6qq1zfDTE8yXsf0TRFtrPQ - tuka/FnVJUAYu7JERxeh7JqMp/e9dm7vXQ8njuN27GlnbJD2xggzbaRX5GBvSUJlr8KCtf2lzRoK - Nxi/vS338IcSEawgiMDoo14JKfFVRIOXE4hJ9yKniqIrhCflOokrC9vCIHjIKqvtqKLYeLdzdLxW - X7NfNqbuLS46YVgp+S3xFzZk5TG5eZWAg4WKjCy70Yk5cWBhpXs4Tk4sc4DGLbjvlG54kgm1GCEX - uQh+0SgBmTz6fCFHygk8vzX+by4iMuZGr+CZVoY9aEpyYQ4+EWHVetJVyfvIx4LkAiQp7SnYY4bD - wncWd0R8pL9STisrFWjZ3Q6qCbBqQRNCRPluJ1+I0F8MQWAo8Np43BN+3Up9yrDXYVwUPmEvI5n/ - pJjrNuC5BdVb9ZSMyUyMqY7nrBP/xBncUCj7vT1MmBmMO64pgGBOGNrtDmnF/BazSVnx/GG7ZVFC - KwaLna6o3Na7torwE+UXPbhd6awp5XlY2Dw2qBLVYTOl45xohcYntzPVxae6+WLPAaXga+oO8iyG - MxltaehK2Erw0dbASYmUCm4+2FDdvonLyvYduT279jQrQhV8VNFloCrQ4qTlGqZJ+HjaClQDHbY3 - eRjW+QsoDOpzNu1wNu1xNr2MsxiSUX86b7Nbk7fZbZe32e2FUiuSPGU/njmFEAimM1tzcKF0Il4v - fwYH7Eue8oIVl1EN4YKUBRFL6cuPo1nhTFyapnbCS/j9P+SfIbzidbhmWfQNtJ8aKaRZyNL3XVsa - HPwdv8J7iu+7iuvdCG0P8tfO1tl35yPjhqlgtGJ/yoQMC0XJM8JeU7vk0QucfCyL/lgnaWRF2Ism - Ilr997+f/iHoTmWHgW1BBnBGJjLy+OuXcbnmaIQA4/PMxnFK0QiV68FVRCtKBiL72FX/OgCSRT9v - gzgO8jq4uQnidHCFRiocOpi2ydrTwfwO/r3E9gpsEejEIza4EpYPGVQFzcqcAngGkrYlaXN5Q0Zb - llesUvz+/vIQWag7M8IencQ8rEsLnkSa+iRKSgBIEZTxjCFPwTIA2HTQUa6L1MI2yusAjaBex5ft - w141hDhxZ1AEPkjKBZ7BNs73/bjMMUFSwYdIuD1KIbDHqt+qqkiWdQXZdSKNGNlI5iUj7FU8Vwi9 - yXGloPv3lpIYcbeCPvG6lM8lwh4TUfW2zNLq3zhAymqyneZPlMpIs44318x2bJEt51EhHri+lgMy - adAap2vn/sH8zBv6TGVs2FXlSvLwDUqWxsrt/Ew63QzlRd8q5q8RW1cqIERko/8AAAD//9RdzW+C - MBS/+1c0vbQNBNxhmbPgwZnoZbclO2w7wNANQoYRDVtM//fllVKKCHhYTGZioqWpj/fRPt/HD7Cb - KcAluFDZbEODMrEI9Cgr2pTCcM+tL5FOHf5H4jyhtYyXaloNzZTSYU6xi4FvNYfU9iSZV4scV4zT - 2RJcyvGssVgEc++1yVrjp7W1Nr2iU4NtKtKf7R3xhhbsWDhhepB1aLsfVaZUOJ2Ky3ioqX4HdtOY - HUXrX5/vV/WjhKm1AIfpMYuCdBEHafZBcduM1MJYytTGkZwIkB736sXLoXS92euxavC5RHtU31Zy - 75/eYL1FKhsVwjaduSuxuuJBWdCRHfbUpMq+ux0PzpnAHCmySmLVnbTaqq+jLy2+Qt+fdCoaBMlQ - KZSxvRB4vuY6ygpZ6w6fD1vyJvp69Lv9H+iCt68ZeRBwiycBhYvi6Drtycz+Uz4wuTem3oqGG5nI - /MJMpGUNRevtngkqpairPoBaITgdcHcbeBGMMj6S547EzFDgGR3brkb3OIOQEUQ5vJ0kBw9OrYf6 - 15uheIN08ilPonWYh1+fyTfyfR+ZRR/oiEbzyXY1DuKHpyVlHCFRUz2SUCCL+XI6dgEFxHPhuAF8 - IzhwZ78AAAD//wMACd2HwxJ2AQA= + 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 + DWsHAPcarQrSbgEA headers: cache-control: ['private, max-age=10800, pre-check=10800'] - cf-ray: [3ba9d151ec2b1a93-DUS] + cf-ray: [4a9a5534bffec4a6-DUS] connection: [keep-alive] content-encoding: [gzip] content-type: [text/html; charset=UTF-8] - date: ['Wed, 08 Nov 2017 16:13:09 GMT'] + date: ['Fri, 15 Feb 2019 19:55:35 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] last-modified: ['Thu, 28 Jul 2016 06:02:55 GMT'] - server: [cloudflare-nginx] - set-cookie: ['__cfduid=d105ccc3c87574cb043691d37adb489251510157586; expires=Thu, - 08-Nov-18 16:13:06 GMT; path=/; domain=.thepiratebay.org; HttpOnly', PHPSESSID=ebd5dba696a1241880a7fe9181ae57bc; - path=/; domain=.thepiratebay.org, 'language=en_EN; expires=Thu, 08-Nov-2018 - 16:13:08 GMT; Max-Age=31536000; path=/; domain=.thepiratebay.org'] + server: [cloudflare] + transfer-encoding: [chunked] vary: [Accept-Encoding] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/thepiratebay/thepiratebay_test.yaml b/tests/providers/torrent/thepiratebay/thepiratebay_test.yaml index c3bff42cbe..543e5e751f 100644 --- a/tests/providers/torrent/thepiratebay/thepiratebay_test.yaml +++ b/tests/providers/torrent/thepiratebay/thepiratebay_test.yaml @@ -4,22 +4,22 @@ daily: results: - seeders: 0 pubdate: - title: Ink.Master.Angels.S01E06.WEB.x264-TBS[ettv] + title: Hospital.S04E06.XviD-AFG leechers: 0 - link: magnet:?xt=urn:btih:2c0822768c241e36d770f1e60dc54fd093c68549 - size: 549055365 - - seeders: 124 + link: magnet:?xt=urn:btih:bef700a68338e37c53e3b42837d8282a3489b6b3 + size: 554371645 + - seeders: 0 pubdate: - title: The.Voice.S13E14.WEB.x264-TBS[ettv] - leechers: 78 - link: magnet:?xt=urn:btih:f16cbe510298eee0c1477b5477dd408568489bec - size: 620169789 - - seeders: 44 + title: Great.British.Railway.Journeys.S10E10.720p.HDTV.x264-QPEL + leechers: 0 + link: magnet:?xt=urn:btih:586cab8cbd80ab21e5230f19b1a9a86bc0c9c7f6 + size: 571211776 + - seeders: 0 pubdate: - title: The.Mayor.2017.S01E06.WEB.x264-TBS[ettv] - leechers: 21 - link: magnet:?xt=urn:btih:94411f7130f1d170b5ee13532ade9171d6dde7d4 - size: 183207198 + title: Show.Me.The.Movie.S02E02.480p.x264-mSD + leechers: 0 + link: magnet:?xt=urn:btih:f4915f92e8462c3769fcfca886448fd48d1861fb + size: 212504412 backlog: search_strings: @@ -34,6 +34,6 @@ backlog: - seeders: 1 pubdate: title: Arrow.S05E07.1080p.WEB-DL.6CH.x265.HEVC-PSA - leechers: 3 + leechers: 2 link: magnet:?xt=urn:btih:d540765a1d0b49ec1c7bf6186c42d9e652500aaa size: 524350914 diff --git a/tests/providers/torrent/tntvillage/tntvillage_backlog.yaml b/tests/providers/torrent/tntvillage/tntvillage_backlog.yaml new file mode 100644 index 0000000000..fa67ae4d97 --- /dev/null +++ b/tests/providers/torrent/tntvillage/tntvillage_backlog.yaml @@ -0,0 +1,53 @@ +interactions: +- request: + body: !!python/unicode cat=0&srcrel=American+Horror+Story+S08E08&page=1 + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + Content-Length: ['48'] + Content-Type: [application/x-www-form-urlencoded] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 60777a8f-32f5-11e9-99af-1c1b0d9d2a41)] + method: POST + uri: http://tntvillage.scambioetico.org/src/releaselist.php + response: + body: + string: !!binary | + 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 + headers: + connection: [keep-alive] + content-encoding: [gzip] + content-type: [text/html; charset=utf-8] + date: ['Sun, 17 Feb 2019 20:48:53 GMT'] + server: [nginx/1.10.3] + transfer-encoding: [chunked] + x-frame-options: [SAMEORIGIN] + x-powered-by: [PHP/5.3.29] + status: {code: 200, message: OK} +version: 1 diff --git a/tests/providers/torrent/tntvillage/tntvillage_daily.yaml b/tests/providers/torrent/tntvillage/tntvillage_daily.yaml new file mode 100644 index 0000000000..fd47a9c417 --- /dev/null +++ b/tests/providers/torrent/tntvillage/tntvillage_daily.yaml @@ -0,0 +1,85 @@ +interactions: +- request: + body: !!python/unicode srcrel=&page=1&cat=29 + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + Content-Length: ['21'] + Content-Type: [application/x-www-form-urlencoded] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 250c8c70-32f0-11e9-8831-1c1b0d9d2a41)] + method: POST + uri: http://tntvillage.scambioetico.org/src/releaselist.php + response: + body: + string: !!binary | + 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 + headers: + connection: [keep-alive] + content-encoding: [gzip] + content-type: [text/html; charset=utf-8] + date: ['Sun, 17 Feb 2019 20:11:04 GMT'] + server: [nginx/1.10.3] + transfer-encoding: [chunked] + x-frame-options: [SAMEORIGIN] + x-powered-by: [PHP/5.3.29] + status: {code: 200, message: OK} +version: 1 diff --git a/tests/providers/torrent/tntvillage/tntvillage_test.yaml b/tests/providers/torrent/tntvillage/tntvillage_test.yaml new file mode 100644 index 0000000000..6e763f49b0 --- /dev/null +++ b/tests/providers/torrent/tntvillage/tntvillage_test.yaml @@ -0,0 +1,39 @@ +daily: + search_strings: + RSS: [''] + results: + - seeders: 102 + pubdate: 2017-11-12 00:00:00 + title: NCIS Los Angeles S10e05 Versione 720 [Mux 720p - H264 - Ita Mp3] DLMux Poliziesco,Azione by.IperB + leechers: 20 + link: http://forum.tntvillage.scambioetico.org/index.php?act=Attach&type=post&id=15805710 + size: -1 + - seeders: 71 + pubdate: 2017-11-12 00:00:00 + title: The Last Ship S05e05 [Mux - H264 - Ita Aac] DLMux - Gnomo82 & Metalh + leechers: 8 + link: http://forum.tntvillage.scambioetico.org/index.php?act=Attach&type=post&id=15805705 + size: -1 + - seeders: 133 + pubdate: 2017-11-12 00:00:00 + title: The Last Ship S05e05 [Mux 720p - H264 - Ita Eng Ac3 - Sub Ita Eng] By Morpheus + leechers: 18 + link: http://forum.tntvillage.scambioetico.org/index.php?act=Attach&type=post&id=15805644 + size: -1 + +backlog: + search_strings: + Episode: ['American Horror Story S08E08'] + results: + - seeders: 13 + pubdate: 2017-11-12 00:00:00 + title: American Horror Story - Apocalypse S08e08 [Mux - H264 - Ita Aac] DLMux by UBi [CURA] Misteri - Deejay + leechers: 0 + link: http://forum.tntvillage.scambioetico.org/index.php?act=Attach&type=post&id=15796339 + size: -1 + - seeders: 23 + pubdate: 2017-11-12 00:00:00 + title: American Horror Story - Apocalypse S08e08 [Mux 1080p - H264 - Ita Eng Ac3 - Sub Ita Eng] by Morpheus [CURA] Misteri - Deejay + leechers: 6 + link: http://forum.tntvillage.scambioetico.org/index.php?act=Attach&type=post&id=15796132 + size: -1 diff --git a/tests/providers/torrent/tokyotoshokan/tokyotoshokan_backlog.yaml b/tests/providers/torrent/tokyotoshokan/tokyotoshokan_backlog.yaml index aa460c41f7..8918b71600 100644 --- a/tests/providers/torrent/tokyotoshokan/tokyotoshokan_backlog.yaml +++ b/tests/providers/torrent/tokyotoshokan/tokyotoshokan_backlog.yaml @@ -5,82 +5,84 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - Cookie: [lastvisit_session=1510861533; lastvisit=1510861533; __cfduid=da44a243da42480f632fb3aecb938556f1510861554] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; c07c3f9e-cb06-11e7-958f-1c1b0d9d2a41)] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET - uri: http://tokyotosho.info/search.php?type=1&terms=Yu-Gi-Oh%21+VRAINS+27 + uri: http://tokyotosho.info/search.php?terms=Yu-Gi-Oh%21+VRAINS+27&type=1 response: body: string: !!binary | - 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 - lXe7b15WO/tbb2z7K4R/WRBeuSuEQzn52SJ4/X9Wev66OF6260XbXg3kpa9A/msAeSJjQvR1fp/6 - AMdW5ZbgXl8T3OtfQmX+6uR1/d1R9eBw57i2+aL6crfc6ZxVK5t7L8/e1Z69+FqZf2GwXr4rrFc+ - 48K8+tkX5lalUdyorQB0q1mtfwX0X6cyr5VuB961NcG7mom25PK6FaW88jq6oObZRPqCWv6GRgCo - gqcr6YVwUXZMdcN0/Zbob90RnTZEs20GdZ9uT/svJ/J11mbIdBkSwjt0UfXvYvM6pjc0TNfply4x - rWiYLtItdUQXCZZaqosESz3TRYK0aVqYb5ouki12TRfHl9umS3Ne6lwuUiz1Ju8v9ibXa00qQrk8 - yYOx0Ku0Vzcr7fxu5d2blWv3Kq8zPuFYYf909Pr25VL30r6pfbnYvLTX6F4uNS/tnO5lVpGmuV0f - c7mFmNu7tPOal3P90lv3Kuc6nXZW8V1al7m/0Un6lvrnv7Nf7AwpVfD/u/v/59/rzP1UR80DTEr+ - PoZSS2b5C5nfIaOHcdCHEhjp8f3uRQUKl8oYikH7cb2x8QHVShAp6L39uGzVP6CqeimX4NFSj3X7 - A1SPVQQvMVjJEvH4gjCYFXoPCfRDqhuk1xLplvW4ulGeSi83KqnsWikVbW1cL7rR+PC7++nM9ihX - lY5oTmeMF6puiBGPxlzEfbL4g/3skPpHIEbGefJXZWhEQlArVYBpZTuAlK4G39IYYUbkP/oIYfXU - 70qZzKeNerHeKNqljaJVrqr0b+rfvqt/EeL8F+89hOLnMgAA + H4sIAAAAAAAAC+1bW2/bOBZ+boH5D6wG3ZliasuSr3FtdXJpk7S5NXaTdoqioCXaViOJGpKKk8H+ + k8G+7cM+7MtiXxb7e3YH2H+xh6Rky7ac28zOtkCLtpFIngsPD79zyKN0HmwdbvbfHj1DYxEG6Oj1 + xt7uJjJKpnla3TTNrf4WerPT399DVtkyzWcHBjLGQsRt05xMJuVJtUzZyOwfmxeS3LIkQfZc9oRn + OPc7ivFFGES8W0Brra2taQpDDmoHOBp1DRIpSoI9pxMSgZEkLJEfE/+8a2zSSJBIlPqXMTGQq9+6 + hiAXwpSMnrhjzDgR3UQMSy0DmcBK+CIgTp+eXVLUp3xMz3CE2m30tZBNQrag75HP3DLzf6JROSJC + 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 + /guPqztMKTMAAA== headers: cache-control: [max-age=1800] - cf-ray: [3becf41e778e1aab-DUS] + cf-ray: [4a9a54c5fdbfc4ce-DUS] connection: [keep-alive] content-encoding: [gzip] - content-length: ['3342'] + content-length: ['3373'] content-type: [text/html; charset=UTF-8] - date: ['Thu, 16 Nov 2017 19:45:57 GMT'] - expires: ['Thu, 16 Nov 2017 20:15:36 GMT'] - server: [cloudflare-nginx] + date: ['Fri, 15 Feb 2019 19:55:16 GMT'] + expires: ['Fri, 15 Feb 2019 20:24:51 GMT'] + server: [cloudflare] + set-cookie: ['__cfduid=dfdba84c366884066b48c964a2a5876471550260516; expires=Sat, + 15-Feb-20 19:55:16 GMT; path=/; domain=.tokyotosho.info; HttpOnly'] vary: [Accept-Encoding] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/tokyotoshokan/tokyotoshokan_daily.yaml b/tests/providers/torrent/tokyotoshokan/tokyotoshokan_daily.yaml index e95934b653..b323fff891 100644 --- a/tests/providers/torrent/tokyotoshokan/tokyotoshokan_daily.yaml +++ b/tests/providers/torrent/tokyotoshokan/tokyotoshokan_daily.yaml @@ -5,57 +5,56 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; c07c3f9e-cb06-11e7-958f-1c1b0d9d2a41)] + Cookie: [__cfduid=dfdba84c366884066b48c964a2a5876471550260516] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET - uri: http://tokyotosho.info/search.php?type=1&terms= + uri: http://tokyotosho.info/search.php?terms=&type=1 response: body: string: !!binary | - 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 - dehX5hEDjfI/E1c5/fgTAAA= + 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 headers: cache-control: [max-age=1800] - cf-ray: [3becf40bc35d1ac3-DUS] + cf-ray: [4a9a54d0ef81c4ce-DUS] connection: [keep-alive] content-encoding: [gzip] - content-length: ['1784'] + content-length: ['1805'] content-type: [text/html; charset=UTF-8] - date: ['Thu, 16 Nov 2017 19:45:54 GMT'] - expires: ['Thu, 16 Nov 2017 20:15:33 GMT'] + date: ['Fri, 15 Feb 2019 19:55:18 GMT'] + expires: ['Fri, 15 Feb 2019 20:24:53 GMT'] location: ['http://tokyotosho.info/?cat=1'] - server: [cloudflare-nginx] - set-cookie: ['__cfduid=da44a243da42480f632fb3aecb938556f1510861554; expires=Fri, - 16-Nov-18 19:45:54 GMT; path=/; domain=.tokyotosho.info; HttpOnly'] + server: [cloudflare] vary: [Accept-Encoding] status: {code: 302, message: Found} - request: @@ -64,8 +63,8 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - Cookie: [__cfduid=da44a243da42480f632fb3aecb938556f1510861554] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; c07c3f9e-cb06-11e7-958f-1c1b0d9d2a41)] + Cookie: [__cfduid=dfdba84c366884066b48c964a2a5876471550260516] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET uri: http://tokyotosho.info/?cat=1 response: @@ -73,14 +72,14 @@ interactions: string: !!binary | H4sIAAAAAAAACwMAAAAAAAAAAAA= headers: - cf-ray: [3becf40c23901ac3-DUS] + cf-ray: [4a9a54d1591bc4ce-DUS] connection: [keep-alive] content-encoding: [gzip] content-length: ['20'] content-type: [text/html; charset=UTF-8] - date: ['Thu, 16 Nov 2017 19:45:54 GMT'] + date: ['Fri, 15 Feb 2019 19:55:18 GMT'] location: ['https://www.tokyotosho.info/'] - server: [cloudflare-nginx] + server: [cloudflare] vary: [Accept-Encoding] status: {code: 302, message: Found} - request: @@ -89,299 +88,321 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - Cookie: [__cfduid=da44a243da42480f632fb3aecb938556f1510861554] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; c07c3f9e-cb06-11e7-958f-1c1b0d9d2a41)] + Cookie: [__cfduid=dfdba84c366884066b48c964a2a5876471550260516] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET uri: https://www.tokyotosho.info/ response: body: string: !!binary | - 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 + /wMArKS3g0R/AgA= headers: cache-control: ['no-store, no-cache, must-revalidate, post-check=0, pre-check=0'] - cf-ray: [3becf40cfbca1a93-DUS] + cf-ray: [4a9a54d25c26c4ce-DUS] connection: [keep-alive] content-encoding: [gzip] content-type: [text/html; charset=UTF-8] - date: ['Thu, 16 Nov 2017 19:45:54 GMT'] + date: ['Fri, 15 Feb 2019 19:55:18 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] expires: ['Mon, 26 Jul 1997 05:00:00 GMT'] - server: [cloudflare-nginx] - set-cookie: ['lastvisit=1510861533; expires=Thu, 30-Nov-2017 19:45:33 GMT; Max-Age=1209600; - path=/; domain=.tokyotosho.info', lastvisit_session=1510861533; path=/; + server: [cloudflare] + set-cookie: ['lastvisit=1550260493; expires=Fri, 01-Mar-2019 19:54:53 GMT; Max-Age=1209600; + path=/; domain=.tokyotosho.info', lastvisit_session=1550260493; path=/; domain=.tokyotosho.info] strict-transport-security: [max-age=86400] + transfer-encoding: [chunked] vary: [Accept-Encoding] status: {code: 200, message: OK} version: 1 diff --git a/tests/providers/torrent/tokyotoshokan/tokyotoshokan_test.yaml b/tests/providers/torrent/tokyotoshokan/tokyotoshokan_test.yaml index 55b313147b..8e17167c01 100644 --- a/tests/providers/torrent/tokyotoshokan/tokyotoshokan_test.yaml +++ b/tests/providers/torrent/tokyotoshokan/tokyotoshokan_test.yaml @@ -2,38 +2,38 @@ daily: search_strings: RSS: [''] results: - - seeders: 0 + - seeders: 312 pubdate: 2017-11-16 00:00:00 - title: mdb-802 - leechers: 0 - link: magnet:?xt=urn:btih:KWEBQHH34HMGMI5NN6C2VNEZ6EMF3MWC&tr=http + title: '[HorribleSubs] Mahou Shoujo Tokushusen Asuka - 06 [1080p].mkv' + leechers: 322 + link: magnet:?xt=urn:btih:Z4UZDVBQZFNWIV4TIARGO7KB6B2BHBQ3&tr=http size: -1 - - seeders: 0 + - seeders: 10 pubdate: 2017-11-16 00:00:00 - title: '[3D, RPG] [Ashita ha docchida!] Quest & Quest 3D - Short Short Female Adventurer Sina Ver.1.01' - leechers: 0 - link: magnet:?xt=urn:btih:QK6T2JHPDK6H3O55M7LZKHEIL32RJ4GD&tr=http + title: '[Erai-raws] Mahou Shoujo Tokushusen Asuka - 06 [1080p][Multiple Subtitle].mkv' + leechers: 27 + link: magnet:?xt=urn:btih:VOY4MC3IBY3OOP5H53Z6XASJE6ANLAVN&tr=http size: -1 - - seeders: 0 + - seeders: 504 pubdate: 2017-11-16 00:00:00 - title: lzdm-006 - leechers: 0 - link: magnet:?xt=urn:btih:J3OKF55VUE4UYDIFXIHTOVOS3FKKFADZ&tr=http + title: '[HorribleSubs] Mahou Shoujo Tokushusen Asuka - 06 [720p].mkv' + leechers: 324 + link: magnet:?xt=urn:btih:ELMQHCQLVLS2GMI27ZJDLWS3KOHCORBO&tr=http size: -1 backlog: search_strings: Episode: ['Yu-Gi-Oh! VRAINS 27'] results: - - seeders: 3 + - seeders: 0 pubdate: 2017-11-16 00:00:00 title: Yu-Gi-Oh! VRAINS - 27 (1280x720 HEVC2 AAC).mkv - leechers: 3 + leechers: 0 link: magnet:?xt=urn:btih:5OSHGHPWV5Q4NLO7SWWF3N4P3OJKIMLC&tr=http size: -1 - - seeders: 95 + - seeders: 3 pubdate: 2017-11-16 00:00:00 title: '[HorribleSubs] Yu-Gi-Oh! VRAINS - 27 [1080p].mkv' - leechers: 8 + leechers: 0 link: magnet:?xt=urn:btih:GW4QGTAFSIQK2FM6QGNVT652YV3UP77L&tr=http size: -1 diff --git a/tests/providers/torrent/torrent9/torrent9_backlog.yaml b/tests/providers/torrent/torrent9/torrent9_backlog.yaml deleted file mode 100644 index 115d405efd..0000000000 --- a/tests/providers/torrent/torrent9/torrent9_backlog.yaml +++ /dev/null @@ -1,112 +0,0 @@ -interactions: -- request: - body: null - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - Cookie: [__cfduid=d47f299e2936b076319ca2c735c8dc2d41510916082] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; b618ffb0-cb85-11e7-88d3-1c1b0d9d2a41)] - method: GET - uri: http://www.torrents9.pe/search_torrent/Les-Chroniques-de-Shannara-S01E06.html - response: - body: - string: !!binary | - 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 - headers: - cache-control: ['public, max-age=7200'] - cf-cache-status: [HIT] - cf-ray: [3bf2275af4fc1ac9-DUS] - connection: [keep-alive] - content-encoding: [gzip] - content-type: [text/html; charset=UTF-8] - date: ['Fri, 17 Nov 2017 10:54:44 GMT'] - expires: ['Fri, 17 Nov 2017 12:54:44 GMT'] - server: [cloudflare-nginx] - vary: [Accept-Encoding] - via: [1.1 varnish] - x-varnish: ['1418059275'] - status: {code: 200, message: OK} -version: 1 diff --git a/tests/providers/torrent/torrent9/torrent9_daily.yaml b/tests/providers/torrent/torrent9/torrent9_daily.yaml deleted file mode 100644 index 172ffd230d..0000000000 --- a/tests/providers/torrent/torrent9/torrent9_daily.yaml +++ /dev/null @@ -1,150 +0,0 @@ -interactions: -- request: - body: null - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; b618ffb0-cb85-11e7-88d3-1c1b0d9d2a41)] - method: GET - uri: http://www.torrents9.pe/torrents_series.html,trie-date-d - response: - body: - string: !!binary | - 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 - headers: - age: ['223'] - cf-ray: [3bf2274961631ab1-DUS] - connection: [keep-alive] - content-encoding: [gzip] - content-type: [text/html; charset=UTF-8] - date: ['Fri, 17 Nov 2017 10:54:42 GMT'] - server: [cloudflare-nginx] - set-cookie: ['__cfduid=d47f299e2936b076319ca2c735c8dc2d41510916082; expires=Sat, - 17-Nov-18 10:54:42 GMT; path=/; domain=.torrents9.pe; HttpOnly'] - via: [1.1 varnish] - x-varnish: [1418069697 1418025918] - status: {code: 200, message: OK} -version: 1 diff --git a/tests/providers/torrent/torrent9/torrent9_test.yaml b/tests/providers/torrent/torrent9/torrent9_test.yaml deleted file mode 100644 index e4cd2b90b0..0000000000 --- a/tests/providers/torrent/torrent9/torrent9_test.yaml +++ /dev/null @@ -1,39 +0,0 @@ -daily: - search_strings: - RSS: [''] - results: - - seeders: 9 - pubdate: - title: Marvel's The Punisher Saison 1 FRENCH BluRay 720p HDTV x264 - leechers: 0 - link: http://www.torrent9.red/get_torrent/marvel-s-the-punisher-saison-1-french-bluray-720p-hdtv.torrent - size: 10737418240 - - seeders: 9 - pubdate: - title: Marvel's The Punisher Saison 1 VOSTFR BluRay 720p HDTV x264 - leechers: 2 - link: http://www.torrent9.red/get_torrent/marvel-s-the-punisher-saison-1-vostfr-bluray-720p-hdtv.torrent - size: 10737418240 - - seeders: 7 - pubdate: - title: Peaky Blinders S04E01 VOSTFR HDTV x264 - leechers: 0 - link: http://www.torrent9.red/get_torrent/peaky-blinders-s04e01-vostfr-hdtv.torrent - size: 551026688 - -backlog: - search_strings: - Episode: ['Les Chroniques de Shannara S01E06'] - results: - - seeders: 40 - pubdate: - title: Les Chroniques de Shannara S01E06 FRENCH HDTV x264 - leechers: 0 - link: http://www.torrent9.red/get_torrent/les-chroniques-de-shannara-s01e06-french-hdtv.torrent - size: 331559731 - - seeders: 9 - pubdate: - title: Les Chroniques de Shannara S01E06 VOSTFR HDTV x264 - leechers: 2 - link: http://www.torrent9.red/get_torrent/les-chroniques-de-shannara-s01e06-vostfr-hdtv.torrent - size: 341206630 diff --git a/tests/providers/torrent/torrentz2/torrentz2_backlog.yaml b/tests/providers/torrent/torrentz2/torrentz2_backlog.yaml index c3b7939045..f96b4f92f1 100644 --- a/tests/providers/torrent/torrentz2/torrentz2_backlog.yaml +++ b/tests/providers/torrent/torrentz2/torrentz2_backlog.yaml @@ -5,37 +5,372 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - Cookie: [__cfduid=da0f3c3981b54e6fbc830ab43e94fbe941510518143] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; aa667f30-c7ed-11e7-a702-1c1b0d9d2a41)] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET - uri: https://torrentz2.eu/feed?f=Lethal+Weapon+S02E05 + uri: https://torrentz2.eu/feed?f=Lethal+Weapon+S03E05 + response: + body: {string: !!python/unicode "\n\n\n + \ \n \n \n \n \n Just + a moment...\n \n\n \n\n\n\n\n + \ \n \n \n \n \n
\n
\n \n
\n \n
\n
\n + \
\n
\n + \
\n

Checking your + browser before accessing torrentz2.eu.

\n \n

This process + is automatic. Your browser will redirect to your requested content shortly.

\n + \

Please allow up to 5 seconds…

\n + \
\n \n
\n \n + \ \n + \ \n + \ \n
\n
\n\n + \ \n
\n DDoS protection by Cloudflare\n + \
\n Ray ID: 4a9a54d86c2fc4d3\n
\n + \
\n\n\n"} + headers: + cache-control: [no-cache] + cf-ray: [4a9a54d86c2fc4d3-DUS] + connection: [close] + content-type: [text/html; charset=UTF-8] + date: ['Fri, 15 Feb 2019 19:55:19 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + server: [cloudflare] + set-cookie: ['__cfduid=d770a0a3c27fb21763f66fb8692f4439d1550260519; expires=Sat, + 15-Feb-20 19:55:19 GMT; path=/; domain=.torrentz2.eu; HttpOnly'] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-frame-options: [SAMEORIGIN] + status: {code: 503, message: Service Temporarily Unavailable} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + User-Agent: ['Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like + Gecko) Ubuntu Chromium/65.0.3325.181 Chrome/65.0.3325.181 Safari/537.36'] + method: GET + uri: https://torrentz2.eu/feed?f=Lethal+Weapon+S03E05 + response: + body: {string: !!python/unicode "\n\n\n + \ \n \n \n \n \n Just + a moment...\n \n\n \n\n\n\n\n \n \n \n \n \n
\n + \
\n \n
\n + \ \n
\n
\n
\n + \
\n
\n

Checking + your browser before accessing torrentz2.eu.

\n \n

This + process is automatic. Your browser will redirect to your requested content + shortly.

\n

Please allow up to 5 + seconds…

\n
\n \n
\n \n + \ \n + \ \n + \ \n
\n
\n\n + \ \n
\n DDoS protection by Cloudflare\n + \
\n Ray ID: 4a9a54d93e63c4dd\n
\n + \
\n\n\n"} + headers: + cache-control: [no-cache] + cf-ray: [4a9a54d93e63c4dd-DUS] + connection: [close] + content-type: [text/html; charset=UTF-8] + date: ['Fri, 15 Feb 2019 19:55:19 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + server: [cloudflare] + set-cookie: ['__cfduid=da36aae0a7d348835b5e20a14de12f2be1550260519; expires=Sat, + 15-Feb-20 19:55:19 GMT; path=/; domain=.torrentz2.eu; HttpOnly'] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-frame-options: [SAMEORIGIN] + status: {code: 503, message: Service Temporarily Unavailable} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Cookie: [__cfduid=da36aae0a7d348835b5e20a14de12f2be1550260519] + Referer: [!!python/unicode 'https://torrentz2.eu/feed?f=Lethal+Weapon+S03E05'] + User-Agent: ['Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like + Gecko) Ubuntu Chromium/65.0.3325.181 Chrome/65.0.3325.181 Safari/537.36'] + method: GET + uri: https://torrentz2.eu/cdn-cgi/l/chk_jschl?jschl_answer=52.7202477467&pass=1550260523.88-MsN%2BS0OJVQ&jschl_vc=a3a3bb1a60d4c29d3b85e5712d10e09b + response: + body: {string: !!python/unicode "\r\n302 Found\r\n\r\n

302 Found

\r\n
cloudflare
\r\n\r\n\r\n"} + headers: + cf-ray: [4a9a550f2ad9c4d8-DUS] + connection: [keep-alive] + content-length: ['159'] + content-type: [text/html] + date: ['Fri, 15 Feb 2019 19:55:28 GMT'] + location: ['https://torrentz2.eu/feed?f=Lethal+Weapon+S03E05'] + server: [cloudflare] + set-cookie: ['cf_clearance=083ee1cf09c313568c857a0e57ee7fd63bf0f965-1550260528-86400-150; + path=/; expires=Sat, 16-Feb-19 20:55:28 GMT; domain=.torrentz2.eu; HttpOnly'] + x-frame-options: [SAMEORIGIN] + status: {code: 302, message: Moved Temporarily} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Cookie: [cf_clearance=083ee1cf09c313568c857a0e57ee7fd63bf0f965-1550260528-86400-150; + __cfduid=da36aae0a7d348835b5e20a14de12f2be1550260519] + User-Agent: ['Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like + Gecko) Ubuntu Chromium/65.0.3325.181 Chrome/65.0.3325.181 Safari/537.36'] + method: GET + uri: https://torrentz2.eu/feed?f=Lethal+Weapon+S03E05 + response: + body: + string: !!binary | + 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 + headers: + cache-control: ['public, max-age=1500'] + cf-ray: [4a9a550f6b87c4d8-DUS] + connection: [keep-alive] + content-encoding: [gzip] + content-type: [application/xml; charset=utf-8] + date: ['Fri, 15 Feb 2019 19:55:28 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + server: [cloudflare] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-fastcgi-cache: [MISS] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + Cookie: [cf_clearance=083ee1cf09c313568c857a0e57ee7fd63bf0f965-1550260528-86400-150; + __cfduid=da36aae0a7d348835b5e20a14de12f2be1550260519] + !!python/unicode User-Agent: ['Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 + (KHTML, like Gecko) Ubuntu Chromium/65.0.3325.181 Chrome/65.0.3325.181 Safari/537.36'] + method: GET + uri: https://torrentz2.eu/feed?f=Lethal+Weapon+S03E05 response: body: string: !!binary | - H4sIAAAAAAAAA7WWbW/TMBDHX8OnsCIhgWCJn2LHUduJwaQJMTTRCV4iJ7m0EWkSknQbfHouZOmK - NpCZilSpjh3/c3c/351nxzebklxB2xV1NfeYT73jxdMns7br7mY5zhJ8r+pi29ebubfu+yYOguvr - a/9a+HW7CjilYfAaF71hd7q2VQXlMOyLvoRFX7ctVP0P7sOWHJH30K9tST6DbeqKLCk/peEsGF/F - PWVRfV3cfmN/Z9CBbdP18bf5KPCM01ECB5PIr72okUGXtkXTo1uLhz5HRi3yvLU9kLLYFH1MQvJt - C20BXcBoBympW8Io3ZvcFFX3Yhbsiw/22mq1tStYQHW07WbB7hnXhoDFg1Fk3UK+C91vbuUA2XG+ - c+pkcupkdMojLZRzr4My90j/vYG5Z5umLFI7eBcgqpcIxyPBEO+ihw3+T4EfXfdHRX/U83HSL3r/ - Y5GBrzlt/M+nJx+LxudvzvwbrkL/7PTTm6OL5Wt/8/XqjstfwIQsY0mW5nnKWEITISmwXFLKRaIM - DbWyWiVaAcZmYDvYt9oW2YOQ3bV+SQxazTZ5ixgXS9u/IoyRD/UV4ZRpwnQsQvyRlxRP6CyYXhw2 - YfhgVbffF58wDjW5RE93U8P6PuRl8QNiwpki5ydkibi6mDBOLgATJyaCnNlujcfHOQr72ggt2FHb - DcZkuIfPZzQagR29fT8wu2jrvLjxzyErrBMqkxpGlZEMAyIltRJCHBkuZZKHCS5xqSIF3AWVu9Y9 - VJfr7StCzR0qLmLGY6EOg8qgg/usJlTsFpW75Y9HdZtV/0xI8wGOYhHTQiqZpYIbHamBDM2TCDIq - kggzzIWQu5YrIXogQlxJ8RChKZncLX88oan4PTaXgIe5slZDJjImBU8SiuXTZCJVeZryMJEsBZDa - hZS7ljOpA5U9Jbl5iNSUS+6Wu5K6XAM5vYHuCzYsp6Km0oTmudSW5th/sD5jkgCVGVUQQWQ1t4yl - oXUC4a51D8TYfzh5Z6uh/whCw5jrmEeHKWqCRb81oKmo0dui5m75fwNhhUy0jZjVIgWaaorxz6US - RnJrM2wrFowxkXHJCHeteyDO6wq7i94DYWJqYjzHh7kIGBbtZQSdQEwZ4W75H0DgVWS6Qs+GC97i - J+NLCN+oCwAA + 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 + AAD//wMAlBpuVPdUAAA= headers: cache-control: ['public, max-age=1500'] - cf-ray: [3bcc77ebce0b1ab7-DUS] + cf-ray: [4a9a55115c34c49c-DUS] connection: [keep-alive] content-encoding: [gzip] content-type: [application/xml; charset=utf-8] - date: ['Sun, 12 Nov 2017 21:08:46 GMT'] - server: [cloudflare-nginx] + date: ['Fri, 15 Feb 2019 19:55:28 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + server: [cloudflare] + transfer-encoding: [chunked] vary: [Accept-Encoding] x-fastcgi-cache: [HIT] status: {code: 200, message: OK} diff --git a/tests/providers/torrent/torrentz2/torrentz2_daily.yaml b/tests/providers/torrent/torrentz2/torrentz2_daily.yaml index 21373da905..589ddfe3a7 100644 --- a/tests/providers/torrent/torrentz2/torrentz2_daily.yaml +++ b/tests/providers/torrent/torrentz2/torrentz2_daily.yaml @@ -5,90 +5,394 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; 305e03cf-c7e7-11e7-b747-1c1b0d9d2a41)] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 16166f70-32d6-11e9-b01c-1c1b0d9d2a41)] + method: GET + uri: https://torrentz2.eu/feed?f=tv+added%3A2d + response: + body: {string: !!python/unicode "\n\n\n + \ \n \n \n \n \n Just + a moment...\n \n\n \n\n\n\n\n \n \n \n \n \n
\n + \
\n \n
\n + \ \n
\n
\n + \
\n
\n + \
\n

Checking your + browser before accessing torrentz2.eu.

\n \n

This + process is automatic. Your browser will redirect to your requested content + shortly.

\n

Please allow up to 5 + seconds…

\n
\n \n
\n \n + \ \n + \ \n + \ \n
\n
\n\n + \ \n
\n DDoS protection by Cloudflare\n + \
\n Ray ID: 4aa9d54eac0fc4ce\n
\n + \
\n\n\n"} + headers: + cache-control: [no-cache] + cf-ray: [4aa9d54eac0fc4ce-DUS] + connection: [close] + content-type: [text/html; charset=UTF-8] + date: ['Sun, 17 Feb 2019 17:04:27 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + server: [cloudflare] + set-cookie: ['__cfduid=d7ed68492b0ec0f5b61b2de4301cc59b61550423067; expires=Mon, + 17-Feb-20 17:04:27 GMT; path=/; domain=.torrentz2.eu; HttpOnly'] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-frame-options: [SAMEORIGIN] + status: {code: 503, message: Service Temporarily Unavailable} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + User-Agent: ['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 + (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'] + method: GET + uri: https://torrentz2.eu/feed?f=tv+added%3A2d + response: + body: {string: !!python/unicode "\n\n\n + \ \n \n \n \n \n Just + a moment...\n \n\n \n\n\n\n\n + \ \n \n \n \n \n
\n
\n \n
\n \n
\n
\n
\n + \
\n
\n

Checking + your browser before accessing torrentz2.eu.

\n \n

This + process is automatic. Your browser will redirect to your requested content + shortly.

\n

Please allow up to 5 + seconds…

\n
\n \n
\n \n + \ \n + \ \n + \ \n
\n
\n\n + \ \n
\n DDoS protection by Cloudflare\n + \
\n Ray ID: 4aa9d5523e5bc49c\n
\n + \
\n\n\n"} + headers: + cache-control: [no-cache] + cf-ray: [4aa9d5523e5bc49c-DUS] + connection: [close] + content-type: [text/html; charset=UTF-8] + date: ['Sun, 17 Feb 2019 17:04:28 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + server: [cloudflare] + set-cookie: ['__cfduid=d1e37f9a0219ce814d7d94daa529532da1550423068; expires=Mon, + 17-Feb-20 17:04:28 GMT; path=/; domain=.torrentz2.eu; HttpOnly'] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-frame-options: [SAMEORIGIN] + status: {code: 503, message: Service Temporarily Unavailable} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Cookie: [__cfduid=d1e37f9a0219ce814d7d94daa529532da1550423068] + Referer: [!!python/unicode 'https://torrentz2.eu/feed?f=tv+added%3A2d'] + User-Agent: ['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 + (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'] + method: GET + uri: https://torrentz2.eu/cdn-cgi/l/chk_jschl?pass=1550423072.52-oQEGraZxLW&jschl_vc=6af3c933abe004f7cbe6fd770b11e231&jschl_answer=14.5232626222 + response: + body: {string: !!python/unicode "\r\n302 Found\r\n\r\n

302 Found

\r\n
cloudflare
\r\n\r\n\r\n"} + headers: + cf-ray: [4aa9d58b9954c4a1-DUS] + connection: [keep-alive] + content-length: ['159'] + content-type: [text/html] + date: ['Sun, 17 Feb 2019 17:04:37 GMT'] + location: ['https://torrentz2.eu/feed?f=tv+added%3A2d'] + server: [cloudflare] + set-cookie: ['cf_clearance=525b26404fdb9c577ebdda993476bbde07fc6048-1550423077-86400-150; + path=/; expires=Mon, 18-Feb-19 18:04:37 GMT; domain=.torrentz2.eu; HttpOnly'] + x-frame-options: [SAMEORIGIN] + status: {code: 302, message: Moved Temporarily} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Cookie: [cf_clearance=525b26404fdb9c577ebdda993476bbde07fc6048-1550423077-86400-150; + __cfduid=d1e37f9a0219ce814d7d94daa529532da1550423068] + User-Agent: ['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 + (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'] + method: GET + uri: https://torrentz2.eu/feed?f=tv+added%3A2d + response: + body: + string: !!binary | + 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 + 9m+29wcAAAD//wMA9MzY+V1YAAA= + headers: + cache-control: ['public, max-age=1500'] + cf-ray: [4aa9d58c3b50c4a1-DUS] + connection: [keep-alive] + content-encoding: [gzip] + content-type: [application/xml; charset=utf-8] + date: ['Sun, 17 Feb 2019 17:04:37 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + server: [cloudflare] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-fastcgi-cache: [HIT] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: [!!python/unicode 'gzip,deflate'] + Connection: [keep-alive] + Cookie: [cf_clearance=525b26404fdb9c577ebdda993476bbde07fc6048-1550423077-86400-150; + __cfduid=d1e37f9a0219ce814d7d94daa529532da1550423068] + !!python/unicode User-Agent: ['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) + AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'] method: GET uri: https://torrentz2.eu/feed?f=tv+added%3A2d response: body: string: !!binary | - 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 - 7b1XX/0fbTtQlx9XAAA= + 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 headers: cache-control: ['public, max-age=1500'] - cf-ray: [3bcc33fa7f721ab1-DUS] + cf-ray: [4aa9d5979860c4c4-DUS] connection: [keep-alive] content-encoding: [gzip] content-type: [application/xml; charset=utf-8] - date: ['Sun, 12 Nov 2017 20:22:23 GMT'] - server: [cloudflare-nginx] - set-cookie: ['__cfduid=da0f3c3981b54e6fbc830ab43e94fbe941510518143; expires=Mon, - 12-Nov-18 20:22:23 GMT; path=/; domain=.torrentz2.eu; HttpOnly'] + date: ['Sun, 17 Feb 2019 17:04:39 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + server: [cloudflare] + transfer-encoding: [chunked] vary: [Accept-Encoding] x-fastcgi-cache: [HIT] status: {code: 200, message: OK} diff --git a/tests/providers/torrent/torrentz2/torrentz2_test.yaml b/tests/providers/torrent/torrentz2/torrentz2_test.yaml index a953810da9..eee4f502f5 100644 --- a/tests/providers/torrent/torrentz2/torrentz2_test.yaml +++ b/tests/providers/torrent/torrentz2/torrentz2_test.yaml @@ -2,38 +2,38 @@ daily: search_strings: RSS: [''] results: + - seeders: 4 + pubdate: 2017-11-12 00:00:00 + title: Marvels.The.Punisher.2017.S02.2160p.NF.WEBRip.H.264.RUS.LF.DDP5.1-EniaHD + leechers: 4 + link: magnet:?xt=urn:btih:863bcf64fd3873ed7ae62559c497b51f9f0c799c + size: 34603008 - seeders: 0 pubdate: 2017-11-12 00:00:00 - title: Eggheads.S19E46.HDTV.x264-NORiTE - leechers: 26 - link: magnet:?xt=urn:btih:18921c8b6642c77b0c218d179baacf2362767e4c - size: 132120576 + title: Saturday.Night.Live.S44E13.Don.Cheadle.Gary.Clark.Jr.1080p.HULU.WEBRip.AAC2.0.H264-monkee[rarbg] + leechers: 0 + link: magnet:?xt=urn:btih:2db802cc4ba5a720941454e9b09a0c4be9c8ee0b + size: 3027238912 - seeders: 3 pubdate: 2017-11-12 00:00:00 - title: Blackstone.S04E07.720p.WEBRip.x264-aAF - leechers: 1 - link: magnet:?xt=urn:btih:8a5b74b2feeca4696fe28a9fea2bf16f42600d7d - size: 1373634560 - - seeders: 309 - pubdate: 2017-11-12 00:00:00 - title: Once.Upon.a.Time.S07E06.HDTV.x264-SVA[ettv] - leechers: 123 - link: magnet:?xt=urn:btih:2b485956239344991f0a2acb09b1e821f05e6ba7 - size: 272629760 + title: World.Cup.2018.Semi-final.Croatia-England.HDTV.1080i.ts + leechers: 0 + link: magnet:?xt=urn:btih:743015de447c2a28ecd48ec31211a9e40501f44d + size: 13631488 backlog: search_strings: - Episode: ['Lethal Weapon S02E05'] + Episode: ['Lethal Weapon S03E05'] results: - - seeders: 12 + - seeders: 1 pubdate: 2017-11-12 00:00:00 - title: Lethal.Weapon.S02E05.Let.it.Ride.720p.WEBRip.2CH.x265.HEVC-PSA.mkv + title: Lethal.Weapon..Season.3.(WEB-DL.l.1080p.l.Jaskier) leechers: 3 - link: magnet:?xt=urn:btih:51d1bdcffc11b0b340e1f40023b690576a76b76e - size: 226492416 - - seeders: 1 + link: magnet:?xt=urn:btih:c8a9e817db0c92018168055bb4ee565b7c148b3e + size: 31457280 + - seeders: 2 pubdate: 2017-11-12 00:00:00 - title: Lethal.Weapon.S02.1080p.WEB-DLRip.Profix.Media - leechers: 1 - link: magnet:?xt=urn:btih:9c9106941200440a4e52009244bf5b10624686e2 - size: 10423894016 + title: Lethal.Weapon..Season.3.(WEB-DL.l.720p.l.Jaskier) + leechers: 23 + link: magnet:?xt=urn:btih:1a36685aa7468edfc2b05590bc19034d4c7c402e + size: 13631488 diff --git a/tests/providers/torrent/yggtorrent/yggtorrent_backlog.yaml b/tests/providers/torrent/yggtorrent/yggtorrent_backlog.yaml deleted file mode 100644 index 7181aecede..0000000000 --- a/tests/providers/torrent/yggtorrent/yggtorrent_backlog.yaml +++ /dev/null @@ -1,490 +0,0 @@ -interactions: -- request: - body: !!python/unicode "0\r\n\r\n" - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - Content-Type: [application/x-www-form-urlencoded] - User-Agent: [!!python/unicode 'Medusa/0.2.5 (Windows; 7; 46751f9e-7acf-11e8-bdbf-001fd0d1e3a5)'] - method: POST - uri: https://ww1.yggtorrent.is/user/login - response: - body: - string: !!binary | - H4sIAAAAAAAAAwMAAAAAAAAAAAA= - headers: - cache-control: ['no-store, no-cache, must-revalidate'] - connection: [keep-alive] - content-encoding: [gzip] - content-type: [text/html; charset=UTF-8] - date: ['Thu, 28 Jun 2018 12:32:01 GMT'] - expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] - pragma: [no-cache] - server: [Ygg Webserver] - set-cookie: ['ygg_=r0rcub23g41jlbcs0tq8h24pjodv0o5l; expires=Thu, 28-Jun-2018 - 14:32:01 GMT; Max-Age=7200; path=/; HttpOnly'] - x-content-type-options: [nosniff] - x-frame-options: [SAMEORIGIN] - status: {code: 200, message: OK} -- request: - body: null - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - Cookie: [ygg_=r0rcub23g41jlbcs0tq8h24pjodv0o5l] - User-Agent: [!!python/unicode 'Medusa/0.2.5 (Windows; 7; 46751f9e-7acf-11e8-bdbf-001fd0d1e3a5)'] - method: GET - uri: https://ww1.yggtorrent.is/ - response: - body: - string: !!binary | - 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 - sxhh/5C5aGoVQPL/AcLwSkXblwAA - headers: - cache-control: ['no-store, no-cache, must-revalidate'] - connection: [keep-alive] - content-encoding: [gzip] - content-type: [text/html; charset=UTF-8] - date: ['Thu, 28 Jun 2018 12:32:01 GMT'] - expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] - pragma: [no-cache] - server: [Ygg Webserver] - x-content-type-options: [nosniff] - x-frame-options: [SAMEORIGIN] - status: {code: 200, message: OK} -- request: - body: null - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - Cookie: [ygg_=r0rcub23g41jlbcs0tq8h24pjodv0o5l] - User-Agent: [!!python/unicode 'Medusa/0.2.5 (Windows; 7; 46751f9e-7acf-11e8-bdbf-001fd0d1e3a5)'] - method: GET - uri: https://ww1.yggtorrent.is/engine/search?category=2145&do=search&name=Lethal+Weapon+S02E05 - response: - body: - string: !!binary | - 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 - +A9EEQILyscAAA== - headers: - cache-control: ['no-store, no-cache, must-revalidate'] - connection: [keep-alive] - content-encoding: [gzip] - content-type: [text/html; charset=UTF-8] - date: ['Thu, 28 Jun 2018 12:32:01 GMT'] - expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] - pragma: [no-cache] - server: [Ygg Webserver] - x-content-type-options: [nosniff] - x-frame-options: [SAMEORIGIN] - status: {code: 200, message: OK} -version: 1 diff --git a/tests/providers/torrent/yggtorrent/yggtorrent_daily.yaml b/tests/providers/torrent/yggtorrent/yggtorrent_daily.yaml deleted file mode 100644 index 7d5bf34b95..0000000000 --- a/tests/providers/torrent/yggtorrent/yggtorrent_daily.yaml +++ /dev/null @@ -1,584 +0,0 @@ -interactions: -- request: - body: !!python/unicode "0\r\n\r\n" - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - Content-Type: [application/x-www-form-urlencoded] - User-Agent: [!!python/unicode 'Medusa/0.2.5 (Windows; 7; c0481f00-7ac8-11e8-b20b-001fd0d1e3a5)'] - method: POST - uri: https://ww1.yggtorrent.is/user/login - response: - body: - string: !!binary | - H4sIAAAAAAAAAwMAAAAAAAAAAAA= - headers: - cache-control: ['no-store, no-cache, must-revalidate'] - connection: [keep-alive] - content-encoding: [gzip] - content-type: [text/html; charset=UTF-8] - date: ['Thu, 28 Jun 2018 11:45:26 GMT'] - expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] - pragma: [no-cache] - server: [Ygg Webserver] - set-cookie: ['ygg_=o29iicvjjbs9o84eincbgplrd6i9r2i9; expires=Thu, 28-Jun-2018 - 13:45:26 GMT; Max-Age=7200; path=/; HttpOnly'] - x-content-type-options: [nosniff] - x-frame-options: [SAMEORIGIN] - status: {code: 200, message: OK} -- request: - body: null - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - Cookie: [ygg_=o29iicvjjbs9o84eincbgplrd6i9r2i9] - User-Agent: [!!python/unicode 'Medusa/0.2.5 (Windows; 7; c0481f00-7ac8-11e8-b20b-001fd0d1e3a5)'] - method: GET - uri: https://ww1.yggtorrent.is/ - response: - body: - string: !!binary | - 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 - sxhh/5C5aGoVQPL/AcLwSkXblwAA - headers: - cache-control: ['no-store, no-cache, must-revalidate'] - connection: [keep-alive] - content-encoding: [gzip] - content-type: [text/html; charset=UTF-8] - date: ['Thu, 28 Jun 2018 11:45:26 GMT'] - expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] - pragma: [no-cache] - server: [Ygg Webserver] - x-content-type-options: [nosniff] - x-frame-options: [SAMEORIGIN] - status: {code: 200, message: OK} -- request: - body: null - headers: - Accept: ['*/*'] - Accept-Encoding: [!!python/unicode 'gzip,deflate'] - Connection: [keep-alive] - Cookie: [ygg_=o29iicvjjbs9o84eincbgplrd6i9r2i9] - User-Agent: [!!python/unicode 'Medusa/0.2.5 (Windows; 7; c0481f00-7ac8-11e8-b20b-001fd0d1e3a5)'] - method: GET - uri: https://ww1.yggtorrent.is/engine/search?category=2145&do=search - response: - body: - string: !!binary | - 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 - Rj2u0KZUAQA= - headers: - cache-control: ['no-store, no-cache, must-revalidate'] - connection: [keep-alive] - content-encoding: [gzip] - content-type: [text/html; charset=UTF-8] - date: ['Thu, 28 Jun 2018 11:45:26 GMT'] - expires: ['Thu, 19 Nov 1981 08:52:00 GMT'] - pragma: [no-cache] - server: [Ygg Webserver] - x-content-type-options: [nosniff] - x-frame-options: [SAMEORIGIN] - status: {code: 200, message: OK} -version: 1 diff --git a/tests/providers/torrent/yggtorrent/yggtorrent_test.yaml b/tests/providers/torrent/yggtorrent/yggtorrent_test.yaml deleted file mode 100644 index fdcffe0270..0000000000 --- a/tests/providers/torrent/yggtorrent/yggtorrent_test.yaml +++ /dev/null @@ -1,69 +0,0 @@ -daily: - search_strings: - RSS: [''] - results: - - leechers: 3 - link: https://ww1.yggtorrent.is/engine/download_torrent?id=271559 - pubdate: 2018-06-28 11:09:43+00:00 - seeders: 1 - size: 2115271393 - title: Germinal (1962) VF DVDRip h264 AAC - - leechers: 0 - link: https://ww1.yggtorrent.is/engine/download_torrent?id=271548 - pubdate: 2018-06-28 10:52:20+00:00 - seeders: 1 - size: 1793148846 - title: "Enqu\xEAtes criminelles - Affaire Benaym, la veuve et le jardinier Affaire Roman HDTV 720p AC-3 Fr du 27 juin 2018 MKV Diablo" - - leechers: 1 - link: https://ww1.yggtorrent.is/engine/download_torrent?id=271542 - pubdate: 2018-06-28 10:31:52+00:00 - seeders: 4 - size: 1342177280 - title: "La L\xE9gende Du Nil (de L'eau Dans Le D\xE9sert).2014.FRENCH.HDTV.x264.mkv" - - leechers: 6 - link: https://ww1.yggtorrent.is/engine/download_torrent?id=271534 - pubdate: 2018-06-28 10:17:20+00:00 - seeders: 12 - size: 4874787880 - title: The.100.S05E08.FASTSUB.VOSTFR.1080p.AMZN.WEB-DL.DD+5.1.H.264-GOLD - -backlog: - search_strings: - Episode: ['Lethal Weapon S02E05'] - results: - - leechers: 0 - link: https://ww1.yggtorrent.is/engine/download_torrent?id=210187 - pubdate: 2018-03-15 12:18:31+00:00 - seeders: 17 - size: 320507740 - title: Lethal.Weapon.S02E05.FRENCH.HDTV.x264-COLL3CTiF - - leechers: 0 - link: https://ww1.yggtorrent.is/engine/download_torrent?id=210188 - pubdate: 2018-03-15 12:18:33+00:00 - seeders: 30 - size: 959939870 - title: Lethal.Weapon.S02E05.FRENCH.720p.HDTV.x264-COLL3CTiF - - leechers: 0 - link: https://ww1.yggtorrent.is/engine/download_torrent?id=210393 - pubdate: 2018-03-15 17:27:03+00:00 - seeders: 21 - size: 2534030704 - title: Lethal.Weapon.S02E05.FRENCH.1080p.AMZN.WEB-DL.H264-FRATERNiTY - - leechers: 0 - link: https://ww1.yggtorrent.is/engine/download_torrent?id=121656 - pubdate: 2017-11-08 22:15:23+00:00 - seeders: 5 - size: 977734205 - title: Lethal.Weapon.S02E05.SUBFRENCH.720p.WEB-DL.x264-FDS - - leechers: 0 - link: https://ww1.yggtorrent.is/engine/download_torrent?id=122889 - pubdate: 2017-11-10 17:32:41+00:00 - seeders: 2 - size: 1793148846 - title: Lethal.Weapon.S02E05.SUBFRENCH.1080p.WEB-DL.H264-Yn1D.mkv - - leechers: 0 - link: https://ww1.yggtorrent.is/engine/download_torrent?id=121510 - pubdate: 2017-11-08 19:44:57+00:00 - seeders: 12 - size: 338868305 - title: Lethal.Weapon.S02E05.SUBFRENCH.WEB-DL.x264-ARK01 diff --git a/tests/providers/torrent/zooqle/zooqle_backlog.yaml b/tests/providers/torrent/zooqle/zooqle_backlog.yaml index 641b721b4c..8859d3d4c1 100644 --- a/tests/providers/torrent/zooqle/zooqle_backlog.yaml +++ b/tests/providers/torrent/zooqle/zooqle_backlog.yaml @@ -5,360 +5,370 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - Cookie: [__cfduid=dedaecb71dd9c0c3b833108d25ac94c7f1510138217] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; 99ec5e51-c472-11e7-ad0c-1c1b0d9d2a41)] + Cookie: [__cfduid=dc445a4194558945bf53771d78df3baf91550260508] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET uri: https://zooqle.com/search?q=Chance+S02E03+category%3ATV response: body: string: !!binary | - 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 - JgZ0YrZo8YtIvc1/AAAA//8DAByK2XzE+AEA + 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 headers: cache-control: ['max-age=0, private, no-store, no-cache, must-revalidate'] - cf-ray: [3ba7f87a6c541adb-DUS] + cf-ray: [4a9a553ee96dc4c4-DUS] connection: [keep-alive] content-encoding: [gzip] content-security-policy: [frame-ancestors 'self' torrents.me] content-type: [text/html; charset=UTF-8] - date: ['Wed, 08 Nov 2017 10:50:18 GMT'] - expires: ['Sun, 08 Oct 2017 10:50:18 GMT'] - server: [cloudflare-nginx] + date: ['Fri, 15 Feb 2019 19:55:36 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + expires: ['Tue, 15 Jan 2019 19:55:36 GMT'] + server: [cloudflare] + transfer-encoding: [chunked] vary: [Accept-Encoding] x-frame-options: ['ALLOW-FROM https://torrents.me/'] status: {code: 200, message: OK} diff --git a/tests/providers/torrent/zooqle/zooqle_daily.yaml b/tests/providers/torrent/zooqle/zooqle_daily.yaml index 61de161880..b10943e1cf 100644 --- a/tests/providers/torrent/zooqle/zooqle_daily.yaml +++ b/tests/providers/torrent/zooqle/zooqle_daily.yaml @@ -5,387 +5,389 @@ interactions: Accept: ['*/*'] Accept-Encoding: [!!python/unicode 'gzip,deflate'] Connection: [keep-alive] - User-Agent: [!!python/unicode Medusa/0.0.1 (Windows; 10; e51c8a30-c49a-11e7-aacc-1c1b0d9d2a41)] + User-Agent: [!!python/unicode Medusa/0.2.14 (Windows; 10; 8f8dca51-315b-11e9-a5d0-1c1b0d9d2a41)] method: GET - uri: https://zooqle.com/search?v=t&s=dt&q=%2A+category%3ATV&sd=d + uri: https://zooqle.com/search?v=t&sd=d&q=%2A+category%3ATV&s=dt response: body: string: !!binary | - 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 - G/oBAA== + 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 headers: cache-control: ['max-age=0, private, no-store, no-cache, must-revalidate'] - cf-ray: [3ba99efa3b371a81-DUS] + cf-ray: [4a9a5493df90c4e2-DUS] connection: [keep-alive] content-encoding: [gzip] content-security-policy: [frame-ancestors 'self' torrents.me] content-type: [text/html; charset=UTF-8] - date: ['Wed, 08 Nov 2017 15:38:44 GMT'] - expires: ['Sun, 08 Oct 2017 15:38:44 GMT'] - server: [cloudflare-nginx] - set-cookie: ['__cfduid=dc5a3ca6ea5d0a08dca7e76e156c12ae01510155524; expires=Thu, - 08-Nov-18 15:38:44 GMT; path=/; domain=.zooqle.com; HttpOnly'] + date: ['Fri, 15 Feb 2019 19:55:09 GMT'] + expect-ct: ['max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'] + expires: ['Tue, 15 Jan 2019 19:55:08 GMT'] + server: [cloudflare] + set-cookie: ['__cfduid=dc445a4194558945bf53771d78df3baf91550260508; expires=Sat, + 15-Feb-20 19:55:08 GMT; path=/; domain=.zooqle.com; HttpOnly'] + transfer-encoding: [chunked] vary: [Accept-Encoding] x-frame-options: ['ALLOW-FROM https://torrents.me/'] status: {code: 200, message: OK} diff --git a/tests/providers/torrent/zooqle/zooqle_test.yaml b/tests/providers/torrent/zooqle/zooqle_test.yaml index a04002e32c..e8851ae401 100644 --- a/tests/providers/torrent/zooqle/zooqle_test.yaml +++ b/tests/providers/torrent/zooqle/zooqle_test.yaml @@ -2,38 +2,38 @@ daily: search_strings: RSS: [''] results: - - seeders: 1 + - seeders: 10 pubdate: 2017-11-08 00:00:00 - title: Homes Under The Hammer S20E19 720p HDTV x264-NORiTE[rartv] - leechers: 0 - link: magnet:?xt=urn:btih:60C628C2BBA16D83E0451983C0973F8DC02DEF11 - size: -1 + title: Beat Bobby Flay S19E06 Choc O Love 480p x264-mSD [eztv] + leechers: 5 + link: magnet:?xt=urn:btih:7D0358FC19C33367196F67FA11D74D88AB5EBC3D + size: 131072000 - seeders: 2 pubdate: 2017-11-08 00:00:00 - title: Squidbillies S11E04 720p HDTV x264-MiNDTHEGAP[rartv] - leechers: 0 - link: magnet:?xt=urn:btih:1801088BAAF2801E21F2526213F61B26FD0553A6 + title: Beat Bobby Flay S19E06 Choc O Love 480p x264-mSD + leechers: 2 + link: magnet:?xt=urn:btih:8529C50A64665EF8B82B579F7C6195612C6ABEA0 size: -1 - - seeders: 1 + - seeders: 3 pubdate: 2017-11-08 00:00:00 - title: Squidbillies S11E04 HDTV x264-MiNDTHEGAP[rartv] - leechers: 0 - link: magnet:?xt=urn:btih:9D6D689B06FEC9EF14F08C69D9BC31A9368DC242 - size: -1 + title: Beat Bobby Flay S19E06 Choc O Love XviD-AFG + leechers: 1 + link: magnet:?xt=urn:btih:7B9FA4071A993775F9F5430B33B83F015E8D5591 + size: 337641472 backlog: search_strings: Episode: ['Chance S02E03'] results: - - seeders: 63 - pubdate: 2017-10-09 00:00:00 - title: Chance S02E03 WEB h264-TBS[ettv] - leechers: 5 - link: magnet:?xt=urn:btih:029AD775FD366536F19CE4F526958C1BFB1F1CFE - size: 255852544 - - seeders: 59 + - seeders: 33 pubdate: 2017-10-09 00:00:00 title: Chance S02E03 WEB h264-TBS [eztv] leechers: 46 link: magnet:?xt=urn:btih:3E0044197C6FFD4B410FD924D7ED8467E01812D9 size: 255852544 + - seeders: 16 + pubdate: 2017-10-09 00:00:00 + title: Chance S02E03 720p WEB h264-TBS [eztv] + leechers: 18 + link: magnet:?xt=urn:btih:5ED81FEECA5BAB5193D260185B4BF863D02B14FD + size: 740294656 diff --git a/tests/report_guessit.py b/tests/report_guessit.py index 201c8ab1cb..0087942617 100644 --- a/tests/report_guessit.py +++ b/tests/report_guessit.py @@ -1,5 +1,6 @@ # coding=utf-8 """Utility module to report guessit issues.""" +from __future__ import unicode_literals import os import sys @@ -12,6 +13,8 @@ from medusa.name_parser.guessit_parser import guessit from rebulk.__version__ import __version__ as rebulk_version +from six import iteritems + class MockTvShow(object): def __init__(self, name): @@ -22,7 +25,7 @@ def __init__(self, name): def main(argv): if len(argv) < 2: - print('Usage: python {} '.format(__file__)) + print('Usage: python {0} '.format(__file__)) sys.exit(1) show_list = argv[2:] @@ -35,7 +38,7 @@ def main(argv): if show_list: results.append('# show list: {}'.format(argv[2:])) results.append('? {}'.format(argv[1])) - for key, value in actual.items(): + for key, value in iteritems(actual): fmt = ': {key}: {value}' if len(results) <= 2 else ' {key}: {value}' results.append(fmt.format(key=key, value=value)) diff --git a/tests/test_clients.py b/tests/test_clients.py index 2242ae4c27..0ec2e764b1 100644 --- a/tests/test_clients.py +++ b/tests/test_clients.py @@ -1,46 +1,48 @@ # coding=utf-8 """Tests for medusa.clients.torrent module.""" +from __future__ import unicode_literals import medusa.clients.torrent as sut from medusa.clients.torrent import ( - deluge_client, deluged_client, downloadstation_client, mlnet_client, - qbittorrent_client, rtorrent_client, transmission_client, utorrent_client + deluge, deluged, downloadstation, mlnet, + qbittorrent, rtorrent, transmission, utorrent ) + import pytest @pytest.mark.parametrize('p', [ { # p0 'client': 'deluge', - 'expected': deluge_client + 'expected': deluge }, { # p1 'client': 'deluged', - 'expected': deluged_client + 'expected': deluged }, { # p2 'client': 'downloadstation', - 'expected': downloadstation_client + 'expected': downloadstation }, { # p3 'client': 'mlnet', - 'expected': mlnet_client + 'expected': mlnet }, { # p4 'client': 'qbittorrent', - 'expected': qbittorrent_client + 'expected': qbittorrent }, { # p5 'client': 'rtorrent', - 'expected': rtorrent_client + 'expected': rtorrent }, { # p6 'client': 'transmission', - 'expected': transmission_client + 'expected': transmission }, { # p7 'client': 'utorrent', - 'expected': utorrent_client + 'expected': utorrent } ]) def test_get_client_module(p): @@ -67,35 +69,35 @@ def test_get_client_module__non_existent(): @pytest.mark.parametrize('p', [ { # p0 'client': 'deluge', - 'expected': deluge_client.DelugeAPI + 'expected': deluge.DelugeAPI }, { # p1 'client': 'deluged', - 'expected': deluged_client.DelugeDAPI + 'expected': deluged.DelugeDAPI }, { # p2 'client': 'downloadstation', - 'expected': downloadstation_client.DownloadStationAPI + 'expected': downloadstation.DownloadStationAPI }, { # p3 'client': 'mlnet', - 'expected': mlnet_client.MLNetAPI + 'expected': mlnet.MLNetAPI }, { # p4 'client': 'qbittorrent', - 'expected': qbittorrent_client.QBittorrentAPI + 'expected': qbittorrent.QBittorrentAPI }, { # p5 'client': 'rtorrent', - 'expected': rtorrent_client.RTorrentAPI + 'expected': rtorrent.RTorrentAPI }, { # p6 'client': 'transmission', - 'expected': transmission_client.TransmissionAPI + 'expected': transmission.TransmissionAPI }, { # p7 'client': 'utorrent', - 'expected': utorrent_client.UTorrentAPI + 'expected': utorrent.UTorrentAPI } ]) def test_get_client_class(p): diff --git a/tests/test_common.py b/tests/test_common.py index 514dfbdaf7..a99d34998a 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa.common.py.""" +from __future__ import unicode_literals from medusa.common import Quality diff --git a/tests/test_guessit.py b/tests/test_guessit.py index 9fece60878..7ac9591844 100644 --- a/tests/test_guessit.py +++ b/tests/test_guessit.py @@ -9,7 +9,7 @@ import medusa.name_parser.guessit_parser as sut from medusa import app import pytest -from six import binary_type, text_type +from six import binary_type, text_type, iteritems import yaml __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) @@ -60,9 +60,9 @@ def _parameters(single_test=None): with open(input_file, 'r') as stream: data = yaml.load(stream) - for release_names, expected in data.items(): - expected = {k: v for k, v in expected.items()} - for k, v in expected.items(): + for release_names, expected in iteritems(data): + expected = {k: v for k, v in iteritems(expected)} + for k, v in iteritems(expected): if isinstance(v, binary_type): expected[k] = text_type(v) @@ -91,7 +91,7 @@ def test_guess(monkeypatch, show_list, release_name, expected): actual = guessit.guessit(release_name, options=options) # Then - actual = {k: _format_param(v) for k, v in actual.items()} + actual = {k: _format_param(v) for k, v in iteritems(actual)} expected['release_name'] = release_name actual['release_name'] = release_name diff --git a/tests/test_guessit.yml b/tests/test_guessit.yml index 2b0e45d1e5..bea61efb1c 100644 --- a/tests/test_guessit.yml +++ b/tests/test_guessit.yml @@ -4341,7 +4341,8 @@ source: HDTV audio_codec: AC3 audio_channels: '5.1' - language: ca + episode_title: desca202 + language: [es, ca] container: mkv mimetype: video/x-matroska type: episode @@ -4354,7 +4355,7 @@ source: HDTV audio_codec: AC3 audio_channels: '5.1' - language: [ca, pt] + language: ca release_group: desca202 container: mkv mimetype: video/x-matroska @@ -4372,3 +4373,15 @@ container: mkv mimetype: video/x-matroska type: episode + +? VA_-_Redux_presents_The_Uplifting_Selection_Vol_1-2019-(RDXSEL026)-WEB-2019-ZzZz +: title: VA + year: 2019 + season: 2019 + episode: 1 + episode_title: '2019' + release_group: RDXSEL026 + alias: VA - Redux presents The Uplifting Selection Vol + alternative_title: Redux presents The Uplifting Selection Vol + source: Web + type: episode diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 7d28fb45d7..3b000a5443 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa.helpers.py.""" +from __future__ import unicode_literals from collections import OrderedDict import medusa.helpers as sut diff --git a/tests/test_imdb.py b/tests/test_imdb.py index 42417e7dae..29cfcca58b 100644 --- a/tests/test_imdb.py +++ b/tests/test_imdb.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/imdb.py.""" +from __future__ import unicode_literals import os.path diff --git a/tests/test_init.py b/tests/test_init.py index 33a0f25103..00a27319a4 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -13,34 +13,34 @@ @pytest.mark.parametrize('p', [ { # p0: bytes with *allowed* extra data 'value': b'd5:hello5:world7:numbersli1ei2eeeEXTRA_DATA_HERE', - 'expected': {'hello': b'world', 'numbers': [1, 2]}, + 'expected': {'hello': 'world', 'numbers': [1, 2]}, 'allow_extra_data': True, 'raises_exc': None, 'exc_message': r'' }, { # p1: bytes with *disallowed* extra data 'value': b'd5:hello5:world7:numbersli1ei2eeeEXTRA_DATA_HERE', - 'expected': {'hello': b'world', 'numbers': [1, 2]}, + 'expected': {'hello': 'world', 'numbers': [1, 2]}, 'allow_extra_data': False, 'raises_exc': bencode.BencodeDecodeError, 'exc_message': r'.+\(data after valid prefix\)' }, { # p2: unicode with *allowed* extra data - 'value': 'd5:hello5:world7:numbersli1ei2eeeEXTRA_DATA_HERE', - 'expected': {'hello': b'world', 'numbers': [1, 2]}, + 'value': b'd5:hello5:world7:numbersli1ei2eeeEXTRA_DATA_HERE', + 'expected': {'hello': 'world', 'numbers': [1, 2]}, 'allow_extra_data': True, 'raises_exc': None, 'exc_message': r'' }, { # p3: unicode with *disallowed* extra data - 'value': 'd5:hello5:world7:numbersli1ei2eeeEXTRA_DATA_HERE', - 'expected': {'hello': b'world', 'numbers': [1, 2]}, + 'value': b'd5:hello5:world7:numbersli1ei2eeeEXTRA_DATA_HERE', + 'expected': {'hello': 'world', 'numbers': [1, 2]}, 'allow_extra_data': False, 'raises_exc': bencode.BencodeDecodeError, 'exc_message': r'.+\(data after valid prefix\)' }, { # p4: invalid data - 'value': b'Heythere', + 'value': 'Heythere', 'expected': None, 'allow_extra_data': False, 'raises_exc': bencode.BencodeDecodeError, diff --git a/tests/test_issue_submitter.py b/tests/test_issue_submitter.py index b63e4333d1..351cd171c6 100644 --- a/tests/test_issue_submitter.py +++ b/tests/test_issue_submitter.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa.server.web.core.error_logs.py.""" +from __future__ import unicode_literals import logging @@ -11,6 +12,7 @@ from mock.mock import Mock import pytest +from six import itervalues sut = IssueSubmitter() @@ -220,7 +222,7 @@ def test_find_similar_issues(monkeypatch, logger, github_repo, read_loglines, cr 4: 'Missing time zone for network: USA Network', 5: "AttributeError: 'NoneType' object has no attribute 'findall'", } - for line in lines.values(): + for line in itervalues(lines): logger.warning(line) loglines = list(read_loglines) @@ -238,7 +240,7 @@ def test_find_similar_issues(monkeypatch, logger, github_repo, read_loglines, cr kwargs = {} if not pull_request else {'pull_request': 'mock'} issues[number] = create_github_issue(title=title, number=number, **kwargs) - monkeypatch.setattr(github_repo, 'get_issues', lambda *args, **kwargs: issues.values()) + monkeypatch.setattr(github_repo, 'get_issues', lambda *args, **kwargs: itervalues(issues)) expected = { lines[1]: issues[2], @@ -252,7 +254,7 @@ def test_find_similar_issues(monkeypatch, logger, github_repo, read_loglines, cr actual = sut.find_similar_issues(github_repo, loglines) # Then - assert len(set(issues.values())) == len(issues) # all issues should be different + assert len(list(issues.values())) == len(issues) # all issues should be different assert expected == actual diff --git a/tests/test_list_associated_files.py b/tests/test_list_associated_files.py index 993c1a1eb5..aa7017da25 100644 --- a/tests/test_list_associated_files.py +++ b/tests/test_list_associated_files.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/test_list_associated_files.py.""" +from __future__ import unicode_literals import os from medusa import app diff --git a/tests/test_logger.py b/tests/test_logger.py index ec82771033..a79eeb2aa9 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -1,5 +1,7 @@ # coding=utf-8 """Tests for medusa.logger.py.""" +from __future__ import unicode_literals + import os.path from datetime import datetime @@ -55,8 +57,8 @@ def test_logger__various_messages(self, logger, read_loglines, p): }, { # p1: Regression 'message': 'This is an example: {json}', - 'args': [{'json': {'a': 1}}], - 'expected': "This is an example: {'a': 1}" + 'args': [{'json': {5: 1}}], + 'expected': 'This is an example: {5: 1}' }, ]) def test_logger__brace_adapter(self, logger, read_loglines, p): @@ -110,21 +112,20 @@ def describe_logline(logline): @pytest.mark.parametrize('line_pattern', [ - b'This is a example of log line with number {n}', - u'This is a example of unicode log line with number {n}', - b'This is a example of log line with number {n} using \xbb', + 'This is a example of log line with number {n}', ]) def test_reverse_readlines(create_file, line_pattern): # Given no_lines = 10000 - filename = create_file(filename='samplefile.log', lines=[line_pattern.format(n=i) for i in range(0, no_lines)]) - expected = [line_pattern.format(n=no_lines - i - 1) for i in range(0, no_lines)] + lines = [line_pattern.format(n=i).encode('utf-8') for i in list(range(0, no_lines))] + filename = create_file(filename='samplefile.log', lines=lines) + expected = [line_pattern.format(n=no_lines - i - 1) for i in list(range(0, no_lines))] for i, v in enumerate(expected): if not isinstance(v, text_type): expected[i] = text_type(v, errors='replace') # When - actual = list(sut.reverse_readlines(filename, buf_size=1024)) + actual = list(sut.reverse_readlines(filename, block_size=1024)) # Then assert expected == actual @@ -134,7 +135,7 @@ def test_read_loglines(logger, commit_hash, logfile): # Given no_msgs = 200 line_pattern = 'This is a example of log line with number {n}' - for i in range(0, no_msgs): + for i in list(range(0, no_msgs)): logger.warning(line_pattern.format(n=i + 1)) # When @@ -159,9 +160,9 @@ def test_read_loglines__with_traceback(logger, commit_hash, logfile): logger.info(line1) logger.debug(line2) try: - 1 / 0 - except ZeroDivisionError as e: - logger.exception(e.message) + 1 // 0 + except ZeroDivisionError as error: + logger.exception(error) # When actual = list(sut.read_loglines(logfile)) @@ -340,8 +341,8 @@ def test_get_context_loglines__without_timestamp(): def test_get_context_loglines(logger, read_loglines): # Given max_lines = 100 - for i in range(1, 200): - logger.debug('line {}'.format(i)) + for i in list(range(1, 200)): + logger.debug('line {0}'.format(i)) loglines = list(read_loglines) logline = loglines[0] expected = reversed(loglines[:max_lines]) @@ -356,11 +357,11 @@ def test_get_context_loglines(logger, read_loglines): def test_read_loglines__max_traceback_depth(logger): # Given try: - 1 / 0 + 1 // 0 except ZeroDivisionError: logger.exception('Expected exception message') try: - 123 / 0 + 123 // 0 except ZeroDivisionError: logger.exception('Another Expected exception message') @@ -381,7 +382,7 @@ def test_format_to_html(logger, read_loglines, app_config): prog_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) base_url = '../base' try: - 1 / 0 + 1 // 0 except ZeroDivisionError: logger.exception('Expected exception message') loglines = list(read_loglines) diff --git a/tests/test_postprocessor_parse_info.py b/tests/test_postprocessor_parse_info.py index b0073c18b2..6b2b64dea4 100644 --- a/tests/test_postprocessor_parse_info.py +++ b/tests/test_postprocessor_parse_info.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/post_processor.py.""" +from __future__ import unicode_literals from medusa.common import Quality from medusa.name_parser.parser import NameParser from medusa.post_processor import PostProcessor diff --git a/tests/test_process_tv.py b/tests/test_process_tv.py index acfca15d13..5c395d4c13 100644 --- a/tests/test_process_tv.py +++ b/tests/test_process_tv.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/process_tv.py.""" +from __future__ import unicode_literals import os from medusa import app diff --git a/tests/test_release_refiner.py b/tests/test_release_refiner.py index a6a3d72375..283d09a6de 100644 --- a/tests/test_release_refiner.py +++ b/tests/test_release_refiner.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa.refiners.release.py.""" +from __future__ import unicode_literals import os diff --git a/tests/test_rename_associated_file.py b/tests/test_rename_associated_file.py index 4143e54945..7f9c43d7cd 100644 --- a/tests/test_rename_associated_file.py +++ b/tests/test_rename_associated_file.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/post_processor.py.""" +from __future__ import unicode_literals import os from medusa import app diff --git a/tests/test_search_core.py b/tests/test_search_core.py index 7e2e4ab22c..e0ad20351c 100644 --- a/tests/test_search_core.py +++ b/tests/test_search_core.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/search/core.py.""" +from __future__ import unicode_literals import functools import logging diff --git a/tests/test_server_base.py b/tests/test_server_base.py index 005a3e4a5c..3a1f30110c 100644 --- a/tests/test_server_base.py +++ b/tests/test_server_base.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa.tv identifiers.""" +from __future__ import unicode_literals import re from medusa.server.api.v2.base import BaseRequestHandler diff --git a/tests/test_should_process.py b/tests/test_should_process.py index 4ef0b6097d..f186733ccb 100644 --- a/tests/test_should_process.py +++ b/tests/test_should_process.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/test_should_process.py.""" +from __future__ import unicode_literals from medusa.common import Quality from medusa.post_processor import PostProcessor @@ -79,5 +80,5 @@ def test_should_process(p): # Then if expected != actual: - print msg + print(msg) assert expected == actual diff --git a/tests/test_should_replace.py b/tests/test_should_replace.py index 872e036c72..484eae89f7 100644 --- a/tests/test_should_replace.py +++ b/tests/test_should_replace.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/test_should_replace.py.""" +from __future__ import unicode_literals from medusa.common import ARCHIVED, DOWNLOADED, Quality, SKIPPED, SNATCHED, SNATCHED_BEST, SNATCHED_PROPER, WANTED from medusa.search import DAILY_SEARCH, PROPER_SEARCH @@ -538,5 +539,5 @@ def test_should_replace(p): # Then if expected != actual: - print msg + print(msg) assert expected == actual diff --git a/tests/test_should_search.py b/tests/test_should_search.py index 760ffaabf1..ccaff13e4d 100644 --- a/tests/test_should_search.py +++ b/tests/test_should_search.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/test_should_search.py.""" +from __future__ import unicode_literals from medusa.common import (ARCHIVED, DOWNLOADED, IGNORED, Quality, SKIPPED, SNATCHED, SNATCHED_BEST, SNATCHED_PROPER, WANTED) from medusa.tv import Series @@ -234,5 +235,5 @@ def test_should_search(p): # Then if expected != actual: - print msg + print(msg) assert expected == actual diff --git a/tests/test_subtitles.py b/tests/test_subtitles.py index a5fe15b350..95f85b0edf 100644 --- a/tests/test_subtitles.py +++ b/tests/test_subtitles.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa.subtitles.py.""" +from __future__ import unicode_literals import os import subprocess import sys @@ -13,6 +14,8 @@ from subliminal.core import ProviderPool from subliminal.subtitle import Subtitle +from six import text_type + def test_sorted_service_list(monkeypatch): # Given @@ -407,7 +410,7 @@ def test_get_subtitles_dir__no_subtitles_dir(monkeypatch): def test_get_subtitles_dir__absolute_subtitles_dir(monkeypatch, tmpdir): # Given - expected = str(tmpdir.ensure('subtitles')) + expected = text_type(tmpdir.ensure('subtitles')) monkeypatch.setattr(app, 'SUBTITLES_DIR', expected) video_path = '/somefolder/subfolder/video.mkv' @@ -423,8 +426,8 @@ def test_get_subtitles_dir__relative_subtitles_dir(monkeypatch, tmpdir): relative_folder = 'subtitles' monkeypatch.setattr(app, 'SYS_ENCODING', sys.getdefaultencoding()) monkeypatch.setattr(app, 'SUBTITLES_DIR', relative_folder) - video_path = str(tmpdir.ensure('video.mkv')) - expected = os.path.join(str(tmpdir), 'subtitles') + video_path = text_type(tmpdir.ensure('video.mkv')) + expected = os.path.join(text_type(tmpdir), 'subtitles') # When actual = sut.get_subtitles_dir(video_path) @@ -439,15 +442,15 @@ def test_delete_unwanted_subtitles__existing_subtitles_in_unwanted_languages(mon monkeypatch.setattr(app, 'SUBTITLES_MULTI', True) monkeypatch.setattr(app, 'SUBTITLES_KEEP_ONLY_WANTED', True) monkeypatch.setattr(app, 'SUBTITLES_LANGUAGES', ['pob', 'eng']) - subtitle_pob = str(tmpdir.ensure('video.pt-BR.srt')) - subtitle_eng = str(tmpdir.ensure('video.en.srt')) - subtitle_fre = str(tmpdir.ensure('video.fr.srt')) - some_file = str(tmpdir.ensure('video.fr.nfo')) + subtitle_pob = text_type(tmpdir.ensure('video.pt-BR.srt')) + subtitle_eng = text_type(tmpdir.ensure('video.en.srt')) + subtitle_fre = text_type(tmpdir.ensure('video.fr.srt')) + some_file = text_type(tmpdir.ensure('video.fr.nfo')) # When - sut.delete_unwanted_subtitles(str(tmpdir), subtitle_pob) - sut.delete_unwanted_subtitles(str(tmpdir), subtitle_eng) - sut.delete_unwanted_subtitles(str(tmpdir), subtitle_fre) + sut.delete_unwanted_subtitles(text_type(tmpdir), subtitle_pob) + sut.delete_unwanted_subtitles(text_type(tmpdir), subtitle_eng) + sut.delete_unwanted_subtitles(text_type(tmpdir), subtitle_fre) # Then assert os.path.exists(subtitle_pob) @@ -461,8 +464,8 @@ def test_delete_unwanted_subtitles__multi_disabled(monkeypatch, tmpdir): monkeypatch.setattr(app, 'SUBTITLES_MULTI', False) monkeypatch.setattr(app, 'SUBTITLES_KEEP_ONLY_WANTED', True) monkeypatch.setattr(app, 'SUBTITLES_LANGUAGES', ['pob', 'eng']) - subtitle_pob = str(tmpdir.ensure('video.pt-BR.srt')) - subtitle_fre = str(tmpdir.ensure('video.fr.srt')) + subtitle_pob = text_type(tmpdir.ensure('video.pt-BR.srt')) + subtitle_fre = text_type(tmpdir.ensure('video.fr.srt')) # When sut.delete_unwanted_subtitles(tmpdir, subtitle_pob) @@ -478,8 +481,8 @@ def test_delete_unwanted_subtitles__keep_only_wanted_disabled(monkeypatch, tmpdi monkeypatch.setattr(app, 'SUBTITLES_MULTI', True) monkeypatch.setattr(app, 'SUBTITLES_KEEP_ONLY_WANTED', False) monkeypatch.setattr(app, 'SUBTITLES_LANGUAGES', ['pob', 'eng']) - subtitle_pob = str(tmpdir.ensure('video.pt-BR.srt')) - subtitle_fre = str(tmpdir.ensure('video.fr.srt')) + subtitle_pob = text_type(tmpdir.ensure('video.pt-BR.srt')) + subtitle_fre = text_type(tmpdir.ensure('video.fr.srt')) # When sut.delete_unwanted_subtitles(tmpdir, subtitle_pob) @@ -561,7 +564,7 @@ def test_download_subtitles(monkeypatch, tmpdir, video, tvshow, create_sub, crea # Given subtitles = [create_sub(language=code, id=sid, content=content) for sid, code, content in p['list_subtitles']] best_subtitles = [create_sub(language=code, id=sid, content=content) for sid, code, content in p['best_subtitles']] - video_path = str(tmpdir.ensure(video.name)) + video_path = text_type(tmpdir.ensure(video.name)) tvepisode = create_tvepisode(series=tvshow, season=3, episode=4, subtitles=p['existing_subtitles']) external_subtitles = p['external_subtitles'] embedded_subtitles = p['embedded_subtitles'] if p['embedded_subtitles'] is not None else True diff --git a/tests/test_system.py b/tests/test_system.py index 792fcc01b0..5f8c3c3f76 100644 --- a/tests/test_system.py +++ b/tests/test_system.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa.system module.""" +from __future__ import unicode_literals from medusa.event_queue import Events from medusa.system.restart import Restart @@ -15,7 +16,6 @@ (123, False), (b'123', False), (123456, True), - (b'123456', True), # unicode test cases (u'0', False), @@ -42,7 +42,6 @@ def test_restart(pid, expected, app_config): (123, False), (b'123', False), (123456, True), - (b'123456', True), # unicode test cases (u'0', False), diff --git a/tests/test_tv_identifiers.py b/tests/test_tv_identifiers.py index af1691f793..a98d67d3af 100644 --- a/tests/test_tv_identifiers.py +++ b/tests/test_tv_identifiers.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa.tv identifiers.""" +from __future__ import unicode_literals from datetime import datetime diff --git a/tests/test_tvepisode_refiner.py b/tests/test_tvepisode_refiner.py index fc7455cadc..66cdeab80c 100644 --- a/tests/test_tvepisode_refiner.py +++ b/tests/test_tvepisode_refiner.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa.refiners.tv_episode.py.""" +from __future__ import unicode_literals from medusa.common import DOWNLOADED, Quality from medusa.refiners import tv_episode as sut diff --git a/tests/test_update_status_quality.py b/tests/test_update_status_quality.py index 56ffd0c619..69b1419afd 100644 --- a/tests/test_update_status_quality.py +++ b/tests/test_update_status_quality.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/tv/episode.py:update_status_quality""" +from __future__ import unicode_literals from medusa.common import (ARCHIVED, DOWNLOADED, IGNORED, Quality, SKIPPED, SNATCHED, SNATCHED_BEST, SNATCHED_PROPER, UNAIRED, UNSET, WANTED, statusStrings) diff --git a/tests/test_words.py b/tests/test_words.py index a25d6bf02e..2062964eb7 100644 --- a/tests/test_words.py +++ b/tests/test_words.py @@ -1,6 +1,7 @@ # coding=utf-8 """Test if a string contains specific words.""" +from __future__ import unicode_literals from medusa.show.naming import contains_words @@ -46,3 +47,97 @@ def has_words_lazy(item, words): """Test if item contains words lazily.""" found_words = any(contains_words(item, words)) assert found_words, (item, words) + + +@pytest.mark.parametrize('p', [ + # The regular Show uses xem data. To map scene S06E29 to indexer S06E28 + { + 'series_info': { + 'name': u'Regular Show', + 'is_scene': False + }, + 'global': { + 'ignored': ['pref1', 'pref2', 'pref3'], + }, + 'series': { + 'ignored': 'pref1,pref5,pref6', + 'exclude_ignored': False, + }, + 'expected_ignored': [u'pref1', u'pref5', u'pref6', u'pref2', u'pref3'], + }, + { + 'series_info': { + 'name': u'Regular Show', + 'is_scene': False + }, + 'global': { + 'ignored': ['pref1', 'pref2', 'pref3'], + }, + 'series': { + 'ignored': 'pref1,pref2', + 'exclude_ignored': True, + }, + 'expected_ignored': [u'pref3'], + }, + +]) +def test_combine_ignored_words(p, create_tvshow, app_config): + app_config('IGNORE_WORDS', p['global']['ignored']) + + # confirm passed in show object indexer id matches result show object indexer id + series = create_tvshow(name=p['series_info']['name']) + series.rls_ignore_words = p['series']['ignored'] + series.rls_ignore_exclude = p['series']['exclude_ignored'] + + actual = series.show_words() + + expected = p['expected_ignored'] + + assert expected == actual.ignored_words + + +@pytest.mark.parametrize('p', [ + # The regular Show uses xem data. To map scene S06E29 to indexer S06E28 + { + 'series_info': { + 'name': u'Regular Show', + 'is_scene': False + }, + 'global': { + 'required': ['req1', 'req2', 'req3'] + }, + 'series': { + 'required': 'req1,req2,req4', + 'exclude_required': False, + }, + 'expected_required': [u'req1', u'req2', u'req4', u'req3'], + }, + { + 'series_info': { + 'name': u'Regular Show', + 'is_scene': False + }, + 'global': { + 'required': ['req1', 'req2', 'req3'] + }, + 'series': { + 'required': 'req2', + 'exclude_required': True, + }, + 'expected_required': [u'req1', u'req3'], + }, + +]) +def test_combine_required_words(p, create_tvshow, app_config): + app_config('REQUIRE_WORDS', p['global']['required']) + + # confirm passed in show object indexer id matches result show object indexer id + series = create_tvshow(name=p['series_info']['name']) + series.rls_require_words = p['series']['required'] + series.rls_require_exclude = p['series']['exclude_required'] + + actual = series.show_words() + + expected = p['expected_required'] + + assert expected == actual.required_words diff --git a/tests/test_ws.py b/tests/test_ws.py index 697066ba31..1ad5521037 100644 --- a/tests/test_ws.py +++ b/tests/test_ws.py @@ -1,5 +1,6 @@ # coding=utf-8 """Tests for medusa/ws/*.py.""" +from __future__ import unicode_literals import json diff --git a/themes-default/slim/.babelrc b/themes-default/slim/.babelrc index deb10346d1..be6cc698e1 100644 --- a/themes-default/slim/.babelrc +++ b/themes-default/slim/.babelrc @@ -5,12 +5,5 @@ "plugins": [ "@babel/plugin-syntax-dynamic-import", "@babel/plugin-proposal-object-rest-spread" - ], - "env": { - "test": { - "plugins": [ - "istanbul" - ] - } - } + ] } diff --git a/themes-default/slim/.eslintrc b/themes-default/slim/.eslintrc index f6cf538c89..6fdb8dae47 100644 --- a/themes-default/slim/.eslintrc +++ b/themes-default/slim/.eslintrc @@ -2,15 +2,15 @@ "extends": [ "xo/browser", "xo/esnext", - "plugin:vue/essential" + "plugin:vue/essential", + "plugin:jest/recommended" ], "rules": { - "indent": ["error", 4], - "object-curly-spacing": ["error", "always"], - "space-before-function-paren": ["error", "never"], - "unicorn/catch-error-name": ["error", { "name": "error" }] - }, - "env": { - "jquery": true - } + "indent": ["error", 4], + "object-curly-spacing": ["error", "always"], + "space-before-function-paren": ["error", "never"] + }, + "env": { + "jquery": true + } } diff --git a/themes-default/slim/gulpfile.js b/themes-default/slim/gulpfile.js index c41b7283de..907091b768 100644 --- a/themes-default/slim/gulpfile.js +++ b/themes-default/slim/gulpfile.js @@ -1,5 +1,4 @@ const path = require('path'); -const runSequence = require('run-sequence'); const gulp = require('gulp'); const imagemin = require('gulp-imagemin'); const pngquant = require('imagemin-pngquant'); @@ -21,6 +20,12 @@ const setCsstheme = theme => { } }; +/** + * Compressing and copying images to their destinations. + * Should save up to 50% of total filesize. + * + * @returns {NodeJS.ReadWriteStream} stream + */ const moveImages = () => { const dest = `${buildDest}/assets/img`; return gulp @@ -38,32 +43,21 @@ const moveImages = () => { /** Gulp tasks */ -/** - * By default build. - */ -gulp.task('default', ['sync']); - -const syncTheme = (theme, sequence) => { - return new Promise(resolve => { - console.log(`Starting syncing for theme: ${theme}`); - setCsstheme(theme); - runSequence(sequence, resolve); +const generateSyncTasks = () => { + const tasks = Object.keys(config.cssThemes).map(theme => { + const setTheme = callback => { + console.log(`Starting syncing for theme: ${theme}`); + setCsstheme(theme); + callback(); + }; + return gulp.series(setTheme, moveImages); }); + return gulp.series(...tasks); }; -/** - * Build the current theme and copy all files to the location configured in the package.json config attribute. - */ -gulp.task('sync', async () => { // eslint-disable-line space-before-function-paren - // Whe're building the light and dark theme. For this we need to run two sequences. - // If we need a yargs parameter name csstheme. - for (const theme of Object.keys(config.cssThemes)) { - await syncTheme(theme, ['img']); // eslint-disable-line no-await-in-loop - } -}); +exports.sync = generateSyncTasks(); /** - * Task for compressing and copying images to it's destination. - * Should save up to 50% of total filesize. + * Sync by default. */ -gulp.task('img', moveImages); +exports.default = exports.sync; diff --git a/themes-default/slim/package.json b/themes-default/slim/package.json index 0498e3bbc5..ece235133b 100644 --- a/themes-default/slim/package.json +++ b/themes-default/slim/package.json @@ -9,7 +9,7 @@ "dev": "webpack --mode development", "build": "webpack --mode production", "install": "yarn run lint", - "test": "cross-env NODE_ENV=test nyc ava", + "test": "cross-env NODE_ENV=test nyc --clean jest --coverage", "coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov -F frontend" }, "config": { @@ -28,70 +28,71 @@ }, "dependencies": {}, "devDependencies": { - "@babel/core": "7.1.6", - "@babel/plugin-proposal-object-rest-spread": "7.0.0", - "@babel/plugin-syntax-dynamic-import": "7.0.0", - "@babel/polyfill": "7.0.0", - "@babel/preset-env": "7.1.6", - "@babel/register": "7.0.0", + "@babel/core": "7.3.4", + "@babel/plugin-proposal-object-rest-spread": "7.3.4", + "@babel/plugin-syntax-dynamic-import": "7.2.0", + "@babel/preset-env": "7.3.4", "@mapbox/stylelint-processor-arbitrary-tags": "0.2.0", - "@vue/test-utils": "1.0.0-beta.25", - "ava": "1.0.0-rc.2", + "@vue/test-utils": "1.0.0-beta.29", "axios": "0.18.0", + "babel-core": "7.0.0-bridge.0", "babel-eslint": "10.0.1", - "babel-loader": "8.0.4", - "babel-plugin-istanbul": "5.1.0", - "bootstrap": "3.3.7", - "browser-env": "3.2.5", - "clean-webpack-plugin": "1.0.0", - "codecov": "3.1.0", - "copy-webpack-plugin": "4.6.0", + "babel-loader": "8.0.5", + "bootstrap": "3.4.1", + "browser-env": "3.2.6", + "clean-webpack-plugin": "2.0.0", + "codecov": "3.2.0", + "copy-webpack-plugin": "5.0.1", + "country-language": "0.1.7", "cross-env": "5.2.0", - "css-loader": "1.0.1", - "date-fns": "1.29.0", - "eslint": "5.10.0", - "eslint-config-xo": "0.25.0", - "eslint-plugin-vue": "5.0.0-beta.4", - "esm": "3.0.84", - "file-loader": "2.0.0", + "css-loader": "2.1.1", + "date-fns": "1.30.1", + "eslint": "5.15.1", + "eslint-config-xo": "0.26.0", + "eslint-plugin-jest": "22.3.2", + "eslint-plugin-vue": "5.2.2", + "file-loader": "3.0.1", "filemanager-webpack-plugin": "2.0.5", "glob": "7.1.3", - "gulp": "3.9.1", + "gulp": "4.0.0", "gulp-changed": "3.2.0", "gulp-imagemin": "5.0.3", - "imagemin-pngquant": "6.0.0", + "imagemin-pngquant": "7.0.0", "is-visible": "2.2.0", + "jest": "24.5.0", + "jest-haste-map": "24.5.0", + "jest-resolve": "24.5.0", + "jest-serializer-vue": "2.0.2", "jquery": "3.3.1", "lodash": "4.17.11", - "mini-css-extract-plugin": "0.4.5", - "nyc": "13.1.0", - "require-extension-hooks": "0.3.3", - "require-extension-hooks-babel": "1.0.0-beta.1", - "require-extension-hooks-vue": "1.1.0", - "run-sequence": "2.2.1", - "stylelint": "9.9.0", + "mini-css-extract-plugin": "0.5.0", + "nyc": "13.3.0", + "optimize-css-assets-webpack-plugin": "5.0.1", + "stylelint": "9.10.1", "stylelint-config-standard": "18.2.0", - "tablesorter": "2.31.0", - "vue": "2.5.17", - "vue-async-computed": "3.5.0", - "vue-js-toggle-button": "1.3.0", - "vue-loader": "15.4.2", - "vue-meta": "1.5.5", + "tablesorter": "2.31.1", + "vue": "2.6.8", + "vue-async-computed": "3.6.1", + "vue-jest": "3.0.4", + "vue-js-toggle-button": "1.3.2", + "vue-loader": "15.7.0", + "vue-meta": "1.5.8", "vue-native-websocket": "2.0.12", - "vue-router": "3.0.1", - "vue-scrollto": "2.13.0", + "vue-router": "3.0.2", + "vue-scrollto": "2.14.0", "vue-snotify": "3.2.1", - "vue-template-compiler": "2.5.17", + "vue-template-compiler": "2.6.8", "vue-truncate-collapsed": "2.1.0", - "vuex": "3.0.1", - "webpack": "4.26.0", - "webpack-cli": "3.1.2", - "xo": "0.23.0" + "vuex": "3.1.0", + "webpack": "4.29.6", + "webpack-cli": "3.2.3", + "xo": "0.24.0" }, "xo": { "space": 4, "extends": [ - "plugin:vue/essential" + "plugin:vue/essential", + "plugin:jest/recommended" ], "extensions": [ "vue" @@ -114,7 +115,8 @@ ], "valid-jsdoc": [ "error" - ] + ], + "padding-line-between-statements": "off" }, "envs": [ "browser" @@ -174,6 +176,7 @@ "severity": "error" } ], + "no-empty-source": null, "no-descending-specificity": null }, "ignoreFiles": [ @@ -181,29 +184,30 @@ "static/css/*.min.css" ] }, - "ava": { - "require": [ - "esm", - "@babel/register", - "@babel/polyfill", + "jest": { + "setupFiles": [ "./test/helpers/setup.js" ], - "files": [ - "test/specs/**/*.spec.js" + "moduleFileExtensions": [ + "js", + "json", + "vue" ], - "sources": [ - "src/**/*.vue", - "src/**/*.js" + "moduleNameMapper": { + "^@/(.*)$": "/src/$1" + }, + "transform": { + "^.+\\.js$": "babel-jest", + ".*\\.(vue)$": "vue-jest" + }, + "snapshotSerializers": [ + "jest-serializer-vue" ], - "concurrency": 5, - "failWithoutAssertions": true, - "powerAssert": true + "coverageReporters": [ + "json" + ] }, "nyc": { - "require": [ - "@babel/register", - "@babel/polyfill" - ], "sourceMap": false, "instrument": false, "extension": [ @@ -216,6 +220,7 @@ "reporter": [ "lcov", "text" - ] + ], + "tempDirectory": "./coverage" } } diff --git a/themes-default/slim/src/api.js b/themes-default/slim/src/api.js index bc7e404a52..7545730b22 100644 --- a/themes-default/slim/src/api.js +++ b/themes-default/slim/src/api.js @@ -6,7 +6,7 @@ const apiKey = document.body.getAttribute('api-key'); /** * Api client based on the axios client, to communicate with medusa's web routes, which return json data. */ -const apiRoute = axios.create({ // eslint-disable-line no-unused-vars +const apiRoute = axios.create({ baseURL: webRoot + '/', timeout: 30000, headers: { @@ -18,7 +18,7 @@ const apiRoute = axios.create({ // eslint-disable-line no-unused-vars /** * Api client based on the axios client, to communicate with medusa's api v1. */ -const apiv1 = axios.create({ // eslint-disable-line no-unused-vars +const apiv1 = axios.create({ baseURL: webRoot + '/api/v1/' + apiKey + '/', timeout: 30000, headers: { @@ -30,7 +30,7 @@ const apiv1 = axios.create({ // eslint-disable-line no-unused-vars /** * Api client based on the axios client, to communicate with medusa's api v2. */ -const api = axios.create({ // eslint-disable-line no-unused-vars +const api = axios.create({ baseURL: webRoot + '/api/v2/', timeout: 30000, headers: { diff --git a/themes-default/slim/src/app.js b/themes-default/slim/src/app.js index 6c01f7119c..9c143779df 100644 --- a/themes-default/slim/src/app.js +++ b/themes-default/slim/src/app.js @@ -2,9 +2,7 @@ import Vue from 'vue'; import Vuex, { mapState } from 'vuex'; import VueRouter from 'vue-router'; import AsyncComputed from 'vue-async-computed'; -import ToggleButton from 'vue-js-toggle-button'; import Snotify from 'vue-snotify'; -import Truncate from 'vue-truncate-collapsed'; import store from './store'; import router from './router'; import { isDevelopment } from './utils'; @@ -32,7 +30,6 @@ Vue.config.performance = true; Vue.use(Vuex); Vue.use(VueRouter); Vue.use(AsyncComputed); -Vue.use(ToggleButton); Vue.use(Snotify); // Load x-template components @@ -71,7 +68,6 @@ const app = new Vue({ store, router, components: { - Truncate }, data() { return { diff --git a/themes-default/slim/src/components/add-recommended.vue b/themes-default/slim/src/components/add-recommended.vue index 854dc1c76a..a1db05000e 100644 --- a/themes-default/slim/src/components/add-recommended.vue +++ b/themes-default/slim/src/components/add-recommended.vue @@ -41,5 +41,5 @@ export default { }; diff --git a/themes-default/slim/src/components/add-show-options.vue b/themes-default/slim/src/components/add-show-options.vue index 88ab782305..6fed930689 100644 --- a/themes-default/slim/src/components/add-show-options.vue +++ b/themes-default/slim/src/components/add-show-options.vue @@ -340,5 +340,5 @@ export default { }; diff --git a/themes-default/slim/src/components/add-shows.vue b/themes-default/slim/src/components/add-shows.vue index 4727efbf79..4bd99602bc 100644 --- a/themes-default/slim/src/components/add-shows.vue +++ b/themes-default/slim/src/components/add-shows.vue @@ -33,5 +33,5 @@ export default { }; diff --git a/themes-default/slim/src/components/backstretch.vue b/themes-default/slim/src/components/backstretch.vue index 9b8e749643..f9da46afff 100644 --- a/themes-default/slim/src/components/backstretch.vue +++ b/themes-default/slim/src/components/backstretch.vue @@ -44,5 +44,5 @@ export default { }; diff --git a/themes-default/slim/src/components/config-post-processing.vue b/themes-default/slim/src/components/config-post-processing.vue index 0552aae5cc..a49483e2d6 100644 --- a/themes-default/slim/src/components/config-post-processing.vue +++ b/themes-default/slim/src/components/config-post-processing.vue @@ -359,6 +359,7 @@ diff --git a/themes-default/slim/src/components/helpers/app-link.vue b/themes-default/slim/src/components/helpers/app-link.vue index 18c9fda752..e6b9e6fcab 100644 --- a/themes-default/slim/src/components/helpers/app-link.vue +++ b/themes-default/slim/src/components/helpers/app-link.vue @@ -40,7 +40,7 @@ export default { return Object.keys(indexers).find(indexer => indexers[indexer].id === parseInt(indexerId, 10)); }, computedBase() { - return document.getElementsByTagName('base')[0].getAttribute('href'); + return document.querySelectorAll('base')[0].getAttribute('href'); }, computedHref() { const { href, indexerId, placeholder, indexerName } = this; diff --git a/themes-default/slim/src/components/helpers/asset.vue b/themes-default/slim/src/components/helpers/asset.vue index bff44f2898..05f067ee43 100644 --- a/themes-default/slim/src/components/helpers/asset.vue +++ b/themes-default/slim/src/components/helpers/asset.vue @@ -53,10 +53,11 @@ export default { if (this.link) { return this.src.replace('Thumb', ''); } + return undefined; } } }; diff --git a/themes-default/slim/src/components/helpers/config-template.vue b/themes-default/slim/src/components/helpers/config-template.vue index 5de33dd891..06428fcedb 100644 --- a/themes-default/slim/src/components/helpers/config-template.vue +++ b/themes-default/slim/src/components/helpers/config-template.vue @@ -30,5 +30,5 @@ export default { diff --git a/themes-default/slim/src/components/helpers/config-toggle-slider.vue b/themes-default/slim/src/components/helpers/config-toggle-slider.vue index 339ec68692..f3e41f5dd1 100644 --- a/themes-default/slim/src/components/helpers/config-toggle-slider.vue +++ b/themes-default/slim/src/components/helpers/config-toggle-slider.vue @@ -16,8 +16,13 @@ diff --git a/themes-default/slim/src/components/helpers/name-pattern.vue b/themes-default/slim/src/components/helpers/name-pattern.vue index b7125de49a..a3f0755ff6 100644 --- a/themes-default/slim/src/components/helpers/name-pattern.vue +++ b/themes-default/slim/src/components/helpers/name-pattern.vue @@ -275,10 +275,14 @@ diff --git a/themes-default/slim/src/components/helpers/select-list.vue b/themes-default/slim/src/components/helpers/select-list.vue index 63b133e27d..93f3729e81 100644 --- a/themes-default/slim/src/components/helpers/select-list.vue +++ b/themes-default/slim/src/components/helpers/select-list.vue @@ -67,14 +67,6 @@ export default { }; }, created() { - /* - These are needed in order to test the component, - but they break the component in the application: - - this.editItems = this.sanitize(this.listItems); - this.csv = this.editItems.map(item => item.value).join(', '); - */ - /** * ListItems property might receive values originating from the API, * that are sometimes not available when rendering. diff --git a/themes-default/slim/src/components/helpers/show-selector.vue b/themes-default/slim/src/components/helpers/show-selector.vue index ae5328a709..5456e9ddc7 100644 --- a/themes-default/slim/src/components/helpers/show-selector.vue +++ b/themes-default/slim/src/components/helpers/show-selector.vue @@ -112,7 +112,7 @@ export default { } const indexerName = selectedShow.indexer; const showId = selectedShow.id[indexerName]; - const base = document.getElementsByTagName('base')[0].getAttribute('href'); + const base = document.querySelectorAll('base')[0].getAttribute('href'); const path = 'home/displayShow?indexername=' + indexerName + '&seriesid=' + showId; window.location.href = base + path; } diff --git a/themes-default/slim/src/components/helpers/state-switch.vue b/themes-default/slim/src/components/helpers/state-switch.vue index 33a75a64be..19441ff7a4 100644 --- a/themes-default/slim/src/components/helpers/state-switch.vue +++ b/themes-default/slim/src/components/helpers/state-switch.vue @@ -35,7 +35,7 @@ export default { computed: { src() { const { theme, realState: state } = this; - return state === 'loading' ? `images/loading16-${theme}.gif` : `images/${state}16.png`; + return state === 'loading' ? `images/loading16-${theme || 'dark'}.gif` : `images/${state}16.png`; }, alt() { const { realState: state } = this; @@ -56,5 +56,5 @@ export default { }; diff --git a/themes-default/slim/src/components/home.vue b/themes-default/slim/src/components/home.vue index e7a0be4e82..cfe4d220f2 100644 --- a/themes-default/slim/src/components/home.vue +++ b/themes-default/slim/src/components/home.vue @@ -142,7 +142,7 @@ export default { // This needs to be refined to work a little faster. $('.progressbar').each(function() { const percentage = $(this).data('progress-percentage'); - const classToAdd = percentage === 100 ? 100 : percentage > 80 ? 80 : percentage > 60 ? 60 : percentage > 40 ? 40 : 20; // eslint-disable-line no-nested-ternary + const classToAdd = percentage === 100 ? 100 : percentage > 80 ? 80 : percentage > 60 ? 60 : percentage > 40 ? 40 : 20; $(this).progressbar({ value: percentage }); @@ -448,5 +448,5 @@ export default { diff --git a/themes-default/slim/src/components/http/404.vue b/themes-default/slim/src/components/http/404.vue index 8aacda0689..3b72ec0602 100644 --- a/themes-default/slim/src/components/http/404.vue +++ b/themes-default/slim/src/components/http/404.vue @@ -7,5 +7,5 @@ export default { }; diff --git a/themes-default/slim/src/components/index.js b/themes-default/slim/src/components/index.js index 95940180b2..d25e098f9b 100644 --- a/themes-default/slim/src/components/index.js +++ b/themes-default/slim/src/components/index.js @@ -12,6 +12,7 @@ export { default as Login } from './login.vue'; export { default as ManualPostProcess } from './manual-post-process.vue'; export { default as RootDirs } from './root-dirs.vue'; export { default as Show } from './show.vue'; +export { default as ShowHeader } from './show-header.vue'; export { default as SnatchSelection } from './snatch-selection.vue'; export { default as Status } from './status.vue'; export * from './http'; diff --git a/themes-default/slim/src/components/login.vue b/themes-default/slim/src/components/login.vue index a49d2b2a2c..1e17338973 100644 --- a/themes-default/slim/src/components/login.vue +++ b/themes-default/slim/src/components/login.vue @@ -19,5 +19,5 @@ export default { diff --git a/themes-default/slim/src/components/manual-post-process.vue b/themes-default/slim/src/components/manual-post-process.vue index ac5e48db4f..0517d2b5cb 100644 --- a/themes-default/slim/src/components/manual-post-process.vue +++ b/themes-default/slim/src/components/manual-post-process.vue @@ -12,5 +12,5 @@ export default { diff --git a/themes-default/slim/src/components/show-header.vue b/themes-default/slim/src/components/show-header.vue new file mode 100644 index 0000000000..b9e1c437d8 --- /dev/null +++ b/themes-default/slim/src/components/show-header.vue @@ -0,0 +1,694 @@ + + + + + diff --git a/themes-default/slim/src/components/show.vue b/themes-default/slim/src/components/show.vue index c50d410def..1cfb8c24ef 100644 --- a/themes-default/slim/src/components/show.vue +++ b/themes-default/slim/src/components/show.vue @@ -1,16 +1,16 @@ diff --git a/themes-default/slim/src/components/snatch-selection.vue b/themes-default/slim/src/components/snatch-selection.vue index 833838be9a..ae5d9a74dc 100644 --- a/themes-default/slim/src/components/snatch-selection.vue +++ b/themes-default/slim/src/components/snatch-selection.vue @@ -1,12 +1,14 @@ diff --git a/themes-default/slim/src/components/status.vue b/themes-default/slim/src/components/status.vue index 5102a40fee..4e6099d80c 100644 --- a/themes-default/slim/src/components/status.vue +++ b/themes-default/slim/src/components/status.vue @@ -31,5 +31,5 @@ export default { diff --git a/themes-default/slim/src/index.js b/themes-default/slim/src/index.js index 2cc83311c5..5696d6fdcb 100644 --- a/themes-default/slim/src/index.js +++ b/themes-default/slim/src/index.js @@ -2,6 +2,7 @@ import $ from 'jquery'; import 'bootstrap'; import 'bootstrap/dist/css/bootstrap.min.css'; +import 'vue-snotify/styles/material.css'; import '../vendor/js/tablesorter'; import '../vendor/css/open-sans.css'; /* eslint-enable import/no-unassigned-import */ @@ -12,9 +13,8 @@ import VueMeta from 'vue-meta'; import VueRouter from 'vue-router'; import VueNativeSock from 'vue-native-websocket'; import AsyncComputed from 'vue-async-computed'; -import ToggleButton from 'vue-js-toggle-button'; +import { ToggleButton } from 'vue-js-toggle-button'; import Snotify from 'vue-snotify'; -import Truncate from 'vue-truncate-collapsed'; import axios from 'axios'; import debounce from 'lodash/debounce'; import store from './store'; @@ -63,7 +63,6 @@ if (window) { window.AsyncComputed = AsyncComputed; window.ToggleButton = ToggleButton; window.Snotify = Snotify; - window.Truncate = Truncate; window.axios = axios; window._ = { debounce }; window.store = store; diff --git a/themes-default/slim/src/store/modules/clients.js b/themes-default/slim/src/store/modules/clients.js index b92804fc61..6a0cea7c50 100644 --- a/themes-default/slim/src/store/modules/clients.js +++ b/themes-default/slim/src/store/modules/clients.js @@ -12,7 +12,7 @@ const state = { method: null, path: null, paused: null, - rpcurl: null, + rpcUrl: null, seedLocation: null, seedTime: null, username: null, diff --git a/themes-default/slim/src/store/modules/defaults.js b/themes-default/slim/src/store/modules/defaults.js index 6ee544782b..b513cb1601 100644 --- a/themes-default/slim/src/store/modules/defaults.js +++ b/themes-default/slim/src/store/modules/defaults.js @@ -1,32 +1,62 @@ const state = { show: { airs: null, + airsFormatValid: null, akas: null, cache: null, classification: null, config: { airByDate: null, - aliases: null, + aliases: [], anime: null, defaultEpisodeStatus: null, dvdOrder: null, location: null, + locationValid: null, paused: null, - qualities: null, - release: null, + qualities: { + allowed: [], + preferred: [] + }, + release: { + requiredWords: [], + ignoredWords: [], + blacklist: [], + whitelist: [], + allgroups: [], + requiredWordsExclude: null, + ignoredWordsExclude: null + }, scene: null, seasonFolders: null, sports: null, - subtitlesEnabled: null + subtitlesEnabled: null, + airdateOffset: null }, countries: null, - country_codes: null, // eslint-disable-line camelcase - genres: null, + genres: [], id: { tvdb: null, slug: null }, indexer: null, + imdbInfo: { + akas: null, + certificates: null, + countries: null, + countryCodes: null, + genres: null, + imdbId: null, + imdbInfoId: null, + indexer: null, + indexerId: null, + lastUpdate: null, + plot: null, + rating: null, + runtimes: null, + title: null, + votes: null + }, language: null, network: null, nextAirDate: null, @@ -42,7 +72,10 @@ const state = { status: null, title: null, type: null, - year: {} + year: {}, + size: null, + showQueueStatus: [], + xemNumbering: [] } }; diff --git a/themes-default/slim/src/store/modules/notifiers/email.js b/themes-default/slim/src/store/modules/notifiers/email.js index 2a84a14609..adbdb00c37 100644 --- a/themes-default/slim/src/store/modules/notifiers/email.js +++ b/themes-default/slim/src/store/modules/notifiers/email.js @@ -9,7 +9,7 @@ export const state = { tls: null, username: null, password: null, - addressList: null, + addressList: [], subject: null }; diff --git a/themes-default/slim/src/store/modules/notifiers/prowl.js b/themes-default/slim/src/store/modules/notifiers/prowl.js index 94071cd701..33661c0e5c 100644 --- a/themes-default/slim/src/store/modules/notifiers/prowl.js +++ b/themes-default/slim/src/store/modules/notifiers/prowl.js @@ -1,8 +1,8 @@ export const state = { enabled: null, - api: null, + api: [], messageTitle: null, - piority: null, + priority: null, notifyOnSnatch: null, notifyOnDownload: null, notifyOnSubtitleDownload: null diff --git a/themes-default/slim/src/store/modules/qualities.js b/themes-default/slim/src/store/modules/qualities.js index d48d0302ed..28eaeb7a5e 100644 --- a/themes-default/slim/src/store/modules/qualities.js +++ b/themes-default/slim/src/store/modules/qualities.js @@ -20,7 +20,23 @@ const mutations = { } }; -const getters = {}; +const getters = { + getPreset: state => value => { + return Object.keys(state.presets) + .filter(key => { + return state.presets[key] === value; + }) + .map(key => { + return { + [key]: state.presets[key] + }; + }); + }, + combineQualities: () => qualities => { + const reducer = (accumulator, currentValue) => accumulator | currentValue; + return qualities.reduce(reducer, 0); + } +}; const actions = {}; diff --git a/themes-default/slim/src/store/modules/shows.js b/themes-default/slim/src/store/modules/shows.js index 448c01d701..6f4dab38c4 100644 --- a/themes-default/slim/src/store/modules/shows.js +++ b/themes-default/slim/src/store/modules/shows.js @@ -3,7 +3,11 @@ import { api } from '../../api'; import { ADD_SHOW } from '../mutation-types'; const state = { - shows: [] + shows: [], + currentShow: { + indexer: null, + id: null + } }; const mutations = { @@ -28,6 +32,10 @@ const mutations = { // Update state Vue.set(state.shows, state.shows.indexOf(existingShow), newShow); console.debug(`Merged ${newShow.title || newShow.indexer + String(newShow.id)}`, newShow); + }, + currentShow(state, { indexer, id }) { + state.currentShow.indexer = indexer; + state.currentShow.id = id; } }; @@ -41,6 +49,9 @@ const getters = { getEpisode: state => ({ id, indexer, season, episode }) => { const show = state.shows.find(show => Number(show.id[indexer]) === Number(id)); return show && show.seasons && show.seasons[season] ? show.seasons[season][episode] : undefined; + }, + getCurrentShow: (state, getters, rootState) => { + return state.shows.find(show => Number(show.id[state.currentShow.indexer]) === Number(state.currentShow.id)) || rootState.defaults.show; } }; @@ -62,16 +73,26 @@ const actions = { * @returns {Promise} The API response. */ getShow(context, { indexer, id, detailed, fetch }) { - const { commit } = context; - const params = {}; - if (detailed !== undefined) { - params.detailed = Boolean(detailed); - } - if (fetch !== undefined) { - params.fetch = Boolean(fetch); - } - return api.get('/series/' + indexer + id, { params }).then(res => { - commit(ADD_SHOW, res.data); + return new Promise((resolve, reject) => { + const { commit } = context; + const params = {}; + + if (detailed !== undefined) { + params.detailed = Boolean(detailed); + } + + if (fetch !== undefined) { + params.fetch = Boolean(fetch); + } + + api.get('/series/' + indexer + id, { params }) + .then(res => { + commit(ADD_SHOW, res.data); + resolve(res.data); + }) + .catch(error => { + reject(error); + }); }); }, /** @@ -84,17 +105,42 @@ const actions = { getShows(context, shows) { const { commit, dispatch } = context; - // If no shows are provided get the first 10k + // If no shows are provided get the first 1000 if (!shows) { - const params = { - limit: 10000 - }; - return api.get('/series', { params }).then(res => { - const shows = res.data; - return shows.forEach(show => { - commit(ADD_SHOW, show); - }); - }); + return (() => { + const limit = 1000; + const page = 1; + const params = { + limit, + page + }; + + // Get first page + api.get('/series', { params }) + .then(response => { + const totalPages = Number(response.headers['x-pagination-total']); + response.data.forEach(show => { + commit(ADD_SHOW, show); + }); + + // Optionally get additional pages + const pageRequests = []; + for (let page = 2; page <= totalPages; page++) { + const newPage = { page }; + newPage.limit = params.limit; + pageRequests.push(api.get('/series', { params: newPage }).then(response => { + response.data.forEach(show => { + commit(ADD_SHOW, show); + }); + })); + } + + return Promise.all(pageRequests); + }) + .catch(() => { + console.log('Could not retrieve a list of shows'); + }); + })(); } return shows.forEach(show => dispatch('getShow', show)); diff --git a/themes-default/slim/src/utils.js b/themes-default/slim/src/utils.js index 43e3dc6dff..e9f6ff32c4 100644 --- a/themes-default/slim/src/utils.js +++ b/themes-default/slim/src/utils.js @@ -14,7 +14,33 @@ const combineQualities = (allowedQualities, preferredQualities) => { return (allowed | (preferred << 16)) >>> 0; // Unsigned int }; +/** + * Return a human readable representation of the provided size. + * @param {number} bytes - The size in bytes to convert + * @param {boolean} [useDecimal=false] - Use decimal instead of binary prefixes (e.g. kilo = 1000 instead of 1024) + * @returns {string} The converted size. + */ +const humanFileSize = (bytes, useDecimal = false) => { + if (bytes === undefined) { + return; + } + + const thresh = useDecimal ? 1000 : 1024; + if (Math.abs(bytes) < thresh) { + return bytes + ' B'; + } + const units = ['KB', 'MB', 'GB', 'TB', 'PB']; + let u = -1; + do { + bytes /= thresh; + ++u; + } while (Math.abs(bytes) >= thresh && u < units.length - 1); + + return `${bytes.toFixed(2)} ${units[u]}`; +}; + export { combineQualities, + humanFileSize, isDevelopment }; diff --git a/themes-default/slim/static/css/lib/vue-snotify-material.css b/themes-default/slim/static/css/lib/vue-snotify-material.css deleted file mode 100644 index eabe85f8da..0000000000 --- a/themes-default/slim/static/css/lib/vue-snotify-material.css +++ /dev/null @@ -1,708 +0,0 @@ -.snotifyToast { - -webkit-animation-fill-mode: both; - animation-fill-mode: both; } - -.snotify-leftTop .fadeIn, -.snotify-leftCenter .fadeIn, -.snotify-leftBottom .fadeIn { - -webkit-animation-name: fadeInLeft; - animation-name: fadeInLeft; } - -.snotify-leftTop .fadeOut, -.snotify-leftCenter .fadeOut, -.snotify-leftBottom .fadeOut { - -webkit-animation-name: fadeOutLeft; - animation-name: fadeOutLeft; } - -.snotify-rightTop .fadeIn, -.snotify-rightCenter .fadeIn, -.snotify-rightBottom .fadeIn { - -webkit-animation-name: fadeInRight; - animation-name: fadeInRight; } - -.snotify-rightTop .fadeOut, -.snotify-rightCenter .fadeOut, -.snotify-rightBottom .fadeOut { - -webkit-animation-name: fadeOutRight; - animation-name: fadeOutRight; } - -.snotify-centerTop .fadeIn { - -webkit-animation-name: fadeInDown; - animation-name: fadeInDown; } - -.snotify-centerTop .fadeOut { - -webkit-animation-name: fadeOutUp; - animation-name: fadeOutUp; } - -.snotify-centerCenter .fadeIn { - -webkit-animation-name: fadeIn; - animation-name: fadeIn; } - -.snotify-centerCenter .fadeOut { - -webkit-animation-name: fadeOut; - animation-name: fadeOut; } - -.snotify-centerBottom .fadeIn { - -webkit-animation-name: fadeInUp; - animation-name: fadeInUp; } - -.snotify-centerBottom .fadeOut { - -webkit-animation-name: fadeOutDown; - animation-name: fadeOutDown; } - -@-webkit-keyframes fadeInLeft { - 0% { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0) scaleX(1.2); - transform: translate3d(-100%, 0, 0) scaleX(1.2); } - 100% { - opacity: 1; - -webkit-transform: none; - transform: none; } } - -@keyframes fadeInLeft { - 0% { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0) scaleX(1.2); - transform: translate3d(-100%, 0, 0) scaleX(1.2); } - 100% { - opacity: 1; - -webkit-transform: none; - transform: none; } } - -@-webkit-keyframes fadeInRight { - 0% { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0) scaleX(1.2); - transform: translate3d(100%, 0, 0) scaleX(1.2); } - 100% { - opacity: 1; - -webkit-transform: none; - transform: none; } } - -@keyframes fadeInRight { - 0% { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0) scaleX(1.2); - transform: translate3d(100%, 0, 0) scaleX(1.2); } - 100% { - opacity: 1; - -webkit-transform: none; - transform: none; } } - -@-webkit-keyframes fadeInUp { - 0% { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0) scaleY(1.2); - transform: translate3d(0, 100%, 0) scaleY(1.2); } - 100% { - opacity: 1; - -webkit-transform: none; - transform: none; } } - -@keyframes fadeInUp { - 0% { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0) scaleY(1.2); - transform: translate3d(0, 100%, 0) scaleY(1.2); } - 100% { - opacity: 1; - -webkit-transform: none; - transform: none; } } - -@-webkit-keyframes fadeInDown { - 0% { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0) scaleY(1.2); - transform: translate3d(0, -100%, 0) scaleY(1.2); } - 100% { - opacity: 1; - -webkit-transform: none; - transform: none; } } - -@keyframes fadeInDown { - 0% { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0) scaleY(1.2); - transform: translate3d(0, -100%, 0) scaleY(1.2); } - 100% { - opacity: 1; - -webkit-transform: none; - transform: none; } } - -@-webkit-keyframes fadeIn { - 0% { - opacity: 0; } - 100% { - opacity: 1; } } - -@keyframes fadeIn { - 0% { - opacity: 0; } - 100% { - opacity: 1; } } - -@-webkit-keyframes fadeOut { - 0% { - opacity: 1; } - 100% { - opacity: 0; } } - -@keyframes fadeOut { - 0% { - opacity: 1; } - 100% { - opacity: 0; } } - -@-webkit-keyframes fadeOutDown { - 0% { - opacity: 1; } - 100% { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); } } - -@keyframes fadeOutDown { - 0% { - opacity: 1; } - 100% { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); } } - -@-webkit-keyframes fadeOutLeft { - 0% { - opacity: 1; } - 100% { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); } } - -@keyframes fadeOutLeft { - 0% { - opacity: 1; } - 100% { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); } } - -@-webkit-keyframes fadeOutRight { - 0% { - opacity: 1; } - 100% { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); } } - -@keyframes fadeOutRight { - 0% { - opacity: 1; } - 100% { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); } } - -@-webkit-keyframes fadeOutUp { - 0% { - opacity: 1; } - 100% { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); } } - -@keyframes fadeOutUp { - 0% { - opacity: 1; } - 100% { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); } } - -@-webkit-keyframes appear { - 0% { - max-height: 0; } - 100% { - max-height: 50vh; } } - -@keyframes appear { - 0% { - max-height: 0; } - 100% { - max-height: 50vh; } } - -@-webkit-keyframes disappear { - 0% { - opacity: 0; - max-height: 50vh; } - 100% { - opacity: 0; - max-height: 0; } } - -@keyframes disappear { - 0% { - opacity: 0; - max-height: 50vh; } - 100% { - opacity: 0; - max-height: 0; } } - -@-webkit-keyframes async { - 0% { - -webkit-transform: translate(0, -50%) rotate(0deg); - transform: translate(0, -50%) rotate(0deg); } - 100% { - -webkit-transform: translate(0, -50%) rotate(360deg); - transform: translate(0, -50%) rotate(360deg); } } - -@keyframes async { - 0% { - -webkit-transform: translate(0, -50%) rotate(0deg); - transform: translate(0, -50%) rotate(0deg); } - 100% { - -webkit-transform: translate(0, -50%) rotate(360deg); - transform: translate(0, -50%) rotate(360deg); } } - -.snotify { - display: block; - position: fixed; - width: 300px; - z-index: 9999; - -webkit-box-sizing: border-box; - box-sizing: border-box; - pointer-events: none; } - .snotify * { - -webkit-box-sizing: border-box; - box-sizing: border-box; } - -.snotify-leftTop, -.snotify-leftCenter, -.snotify-leftBottom { - left: 10px; } - -.snotify-rightTop, -.snotify-rightCenter, -.snotify-rightBottom { - right: 10px; } - -.snotify-centerTop, -.snotify-centerCenter, -.snotify-centerBottom { - left: calc(50% - 300px / 2); } - -.snotify-leftTop, -.snotify-centerTop, -.snotify-rightTop { - top: 10px; } - -.snotify-leftCenter, -.snotify-rightCenter, -.snotify-centerCenter { - top: 50%; - -webkit-transform: translateY(-50%); - transform: translateY(-50%); } - -.snotify-leftBottom, -.snotify-rightBottom, -.snotify-centerBottom { - bottom: 10px; } - -.snotify-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - background-color: #000; - opacity: 0; - z-index: 9998; - -webkit-transition: opacity .3s; - transition: opacity .3s; } - -.snotifyToast { - display: block; - cursor: pointer; - background-color: #fff; - height: 100%; - margin: 5px; - opacity: 0; - border-radius: 5px; - overflow: hidden; - pointer-events: auto; } - .snotifyToast--in { - -webkit-animation-name: appear; - animation-name: appear; } - .snotifyToast--out { - -webkit-animation-name: disappear; - animation-name: disappear; } - .snotifyToast__inner { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -webkit-flex-flow: column nowrap; - -ms-flex-flow: column nowrap; - flex-flow: column nowrap; - -webkit-box-align: start; - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - position: relative; - padding: 5px 65px 5px 15px; - min-height: 78px; - font-size: 16px; - color: #000; } - .snotifyToast__progressBar { - position: relative; - width: 100%; - height: 10px; - background-color: #c7c7c7; } - .snotifyToast__progressBar__percentage { - position: absolute; - top: 0; - left: 0; - height: 10px; - background-color: #4c4c4c; - max-width: 100%; } - .snotifyToast__title { - font-size: 1.8em; - line-height: 1.2em; - margin-bottom: 5px; - color: #fff; } - .snotifyToast__body { - font-size: 1em; } - -.snotifyToast-show { - -webkit-transform: translate(0, 0); - transform: translate(0, 0); - opacity: 1; } - -.snotifyToast-remove { - max-height: 0; - overflow: hidden; - -webkit-transform: translate(0, 50%); - transform: translate(0, 50%); - opacity: 0; } - -.fadeOutRight { - -webkit-animation-name: fadeOutRight; - animation-name: fadeOutRight; } - -/*************** - ** Modifiers ** - **************/ -.snotify-simple .snotifyToast__title, -.snotify-simple .snotifyToast__body { - color: #000; } - -.snotify-success { - background-color: #4caf50; } - .snotify-success .snotifyToast__progressBar { - background-color: #388e3c; } - .snotify-success .snotifyToast__progressBar__percentage { - background-color: #81c784; } - .snotify-success .snotifyToast__body { - color: #c8e6c9; } - -.snotify-info { - background-color: #1e88e5; } - .snotify-info .snotifyToast__progressBar { - background-color: #1565c0; } - .snotify-info .snotifyToast__progressBar__percentage { - background-color: #64b5f6; } - .snotify-info .snotifyToast__body { - color: #e3f2fd; } - -.snotify-warning { - background-color: #ff9800; } - .snotify-warning .snotifyToast__progressBar { - background-color: #ef6c00; } - .snotify-warning .snotifyToast__progressBar__percentage { - background-color: #ffcc80; } - .snotify-warning .snotifyToast__body { - color: #fff3e0; } - -.snotify-error { - background-color: #f44336; } - .snotify-error .snotifyToast__progressBar { - background-color: #c62828; } - .snotify-error .snotifyToast__progressBar__percentage { - background-color: #ef9a9a; } - .snotify-error .snotifyToast__body { - color: #ffebee; } - -.snotify-async { - background-color: #1e88e5; } - .snotify-async .snotifyToast__progressBar { - background-color: #1565c0; } - .snotify-async .snotifyToast__progressBar__percentage { - background-color: #64b5f6; } - .snotify-async .snotifyToast__body { - color: #e3f2fd; } - -.snotify-confirm { - background-color: #009688; } - .snotify-confirm .snotifyToast__progressBar { - background-color: #4db6ac; } - .snotify-confirm .snotifyToast__progressBar__percentage { - background-color: #80cbc4; } - .snotify-confirm .snotifyToast__body { - color: #e0f2f1; } - -.snotify-prompt { - background-color: #009688; } - .snotify-prompt .snotifyToast__title { - margin-bottom: 0; } - .snotify-prompt .snotifyToast__body { - color: #e0f2f1; } - -.snotify-confirm .snotifyToast__inner, -.snotify-prompt .snotifyToast__inner { - padding: 10px 15px; } - -.snotifyToast__input { - position: relative; - z-index: 1; - display: inline-block; - margin: 0; - width: 100%; - vertical-align: top; - -webkit-transition: all .5s; - transition: all .5s; - -webkit-transition-delay: .3s; - transition-delay: .3s; - -webkit-transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); - transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); } - .snotifyToast__input__field { - position: relative; - display: block; - float: right; - padding: .85em .5em; - width: 100%; - border: none; - border-radius: 0; - background: transparent; - color: #333; - font-weight: bold; - -webkit-appearance: none; - /* for box shadows to show on iOS */ - opacity: 0; - -webkit-transition: opacity .3s; - transition: opacity .3s; } - .snotifyToast__input__field:focus { - outline: none; } - .snotifyToast__input__label { - display: inline-block; - float: right; - padding: 0 .85em; - width: 100%; - color: #e0f2f1; - font-weight: bold; - font-size: 70.25%; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-touch-callout: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - position: absolute; - left: 0; - height: 100%; - text-align: left; - pointer-events: none; } - .snotifyToast__input__label::before, .snotifyToast__input__label::after { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - -webkit-transition: -webkit-transform .3s; - transition: -webkit-transform .3s; - transition: transform .3s; - transition: transform .3s, -webkit-transform .3s; } - .snotifyToast__input__label::before { - border-top: 2px solid #fff; - -webkit-transform: translate3d(0, 100%, 0) translate3d(0, -2px, 0); - transform: translate3d(0, 100%, 0) translate3d(0, -2px, 0); - -webkit-transition-delay: .3s; - transition-delay: .3s; } - .snotifyToast__input__label::after { - z-index: -1; - background: #b2dfdb; - -webkit-transform: scale3d(1, 0, 1); - transform: scale3d(1, 0, 1); - -webkit-transform-origin: 50% 0; - transform-origin: 50% 0; } - .snotifyToast__input__labelContent { - position: relative; - display: block; - padding: 1em 0; - width: 100%; - -webkit-transition: -webkit-transform .3s .3s; - transition: -webkit-transform .3s .3s; - transition: transform .3s .3s; - transition: transform .3s .3s, -webkit-transform .3s .3s; } - -.snotifyToast__input--filled { - margin-top: 2.5em; } - .snotifyToast__input--filled:focus, - .snotifyToast__input--filled .snotifyToast__input__field { - opacity: 1; - -webkit-transition-delay: .3s; - transition-delay: .3s; } - -.snotifyToast__input__field:focus + .snotifyToast__input__label .snotifyToast__input__labelContent, -.snotifyToast__input--filled .snotifyToast__input__labelContent { - -webkit-transform: translate(0, -80%); - transform: translate(0, -80%); - -webkit-transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); - transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); } - -.snotifyToast__input__field:focus + .snotifyToast__input__label::before, -.snotifyToast__input--filled .snotifyToast__input__label::before { - -webkit-transition-delay: 0s; - transition-delay: 0s; } - -.snotifyToast__input__field:focus + .snotifyToast__input__label::before, -.snotifyToast__input--filled .snotifyToast__input__label::before { - -webkit-transform: translate(0, 0); - transform: translate(0, 0); } - -.snotifyToast__input__field:focus + .snotifyToast__input__label::after, -.snotifyToast__input--filled .snotifyToast__input__label::after { - -webkit-transform: scale(1, 1); - transform: scale(1, 1); - -webkit-transition-delay: .3s; - transition-delay: .3s; - -webkit-transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); - transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); } - -.snotifyToast--invalid .snotifyToast__input__label::before { - border-color: #f44336; } - -.snotifyToast--valid .snotifyToast__input__label::before { - border-color: #4caf50; } - -.snotifyToast__buttons { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: horizontal; - -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; - -ms-flex-flow: row nowrap; - flex-flow: row nowrap; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - border-top: 1px solid rgba(0, 0, 0, 0.1); } - .snotifyToast__buttons button { - position: relative; - width: 100%; - border-right: 1px solid rgba(0, 0, 0, 0.1); - border-left: 1px solid rgba(0, 0, 0, 0.1); - border-top: none; - border-bottom: none; - background: transparent; - padding: 8px; - text-transform: capitalize; - color: #fff; - -webkit-box-sizing: border-box; - box-sizing: border-box; - overflow: hidden; } - .snotifyToast__buttons button::after { - content: ''; - position: absolute; - top: 50%; - left: 50%; - width: 5px; - height: 5px; - background: rgba(255, 255, 255, 0.3); - opacity: 0; - border-radius: 100%; - -webkit-transform: scale(1, 1) translate(-50%); - transform: scale(1, 1) translate(-50%); - -webkit-transform-origin: 50% 50%; - transform-origin: 50% 50%; } - .snotifyToast__buttons button:focus:not(:active)::after { - -webkit-animation: ripple 1s ease-out; - animation: ripple 1s ease-out; } - .snotifyToast__buttons button:hover, .snotifyToast__buttons button:focus { - background: rgba(0, 0, 0, 0.1); - outline: none; } - .snotifyToast__buttons button:active { - background: rgba(0, 0, 0, 0.15); } - .snotifyToast__buttons button:last-child { - border-right: none; } - .snotifyToast__buttons button:first-child { - border-left: none; } - .snotifyToast__buttons--bold { - font-weight: 700; } - -@-webkit-keyframes ripple { - 0% { - -webkit-transform: scale(0, 0); - transform: scale(0, 0); - opacity: 1; } - 20% { - -webkit-transform: scale(25, 25); - transform: scale(25, 25); - opacity: 1; } - 100% { - opacity: 0; - -webkit-transform: scale(40, 40); - transform: scale(40, 40); } } - -@keyframes ripple { - 0% { - -webkit-transform: scale(0, 0); - transform: scale(0, 0); - opacity: 1; } - 20% { - -webkit-transform: scale(25, 25); - transform: scale(25, 25); - opacity: 1; } - 100% { - opacity: 0; - -webkit-transform: scale(40, 40); - transform: scale(40, 40); } } - -.snotify-icon { - position: absolute; - right: 10px; - top: 50%; - line-height: 0; - -webkit-transform: translate(0, -50%); - transform: translate(0, -50%); - max-height: 48px; - max-width: 48px; - width: 100%; - height: 100%; } - -.snotify-icon--error { - background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20version=%221.1%22%20x=%220px%22%20y=%220px%22%20viewBox=%220%200%20512%20512%22%20fill=%22%23ffcdd2%22%3E%3Cg%3E%3Cpath%20d=%22M437,75A256,256,0,1,0,75,437,256,256,0,1,0,437,75ZM416.43,416.43a226.82,226.82,0,0,1-320.86,0C7.11,328,7.11,184,95.57,95.57a226.82,226.82,0,0,1,320.86,0C504.89,184,504.89,328,416.43,416.43Z%22/%3E%3Cpath%20d=%22M368.81,143.19a14.5,14.5,0,0,0-20.58,0L256,235.42l-92.23-92.23a14.55,14.55,0,0,0-20.58,20.58L235.42,256l-92.23,92.23a14.6,14.6,0,0,0,10.24,24.89,14.19,14.19,0,0,0,10.24-4.31l92.23-92.23,92.23,92.23a14.64,14.64,0,0,0,10.24,4.31,14,14,0,0,0,10.24-4.31,14.5,14.5,0,0,0,0-20.58l-92-92.23,92.23-92.23A14.5,14.5,0,0,0,368.81,143.19Z%22/%3E%3C/g%3E%3C/svg%3E"); } - -.snotify-icon--warning { - background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20version=%221.1%22%20x=%220px%22%20y=%220px%22%20viewBox=%220%200%20512%20512%22%20fill=%22%23ffccbc%22%3E%3Cg%3E%3Cpath%20d=%22M256,512c141.15,0,256-114.84,256-256S397.15,0,256,0,0,114.84,0,256,114.85,512,256,512Zm0-480.49c123.79,0,224.49,100.71,224.49,224.49S379.79,480.49,256,480.49,31.51,379.79,31.51,256,132.21,31.51,256,31.51Z%22/%3E%3Ccircle%20cx=%22260.08%22%20cy=%22343.87%22%20r=%2226.35%22/%3E%3Cpath%20d=%22M254.68,278.39a15.76,15.76,0,0,0,15.75-15.75V128.72a15.75,15.75,0,1,0-31.51,0V262.63A15.76,15.76,0,0,0,254.68,278.39Z%22/%3E%3C/g%3E%3C/svg%3E"); } - -.snotify-icon--info { - background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20version=%221.1%22%20x=%220px%22%20y=%220px%22%20viewBox=%220%200%20512%20512%22%20fill=%22%23bbdefb%22%3E%3Cg%3E%3Cpath%20d=%22M256,0C114.84,0,0,114.84,0,256S114.84,512,256,512,512,397.16,512,256,397.15,0,256,0Zm0,478.43C133.35,478.43,33.57,378.64,33.57,256S133.35,33.58,256,33.58,478.42,133.36,478.42,256,378.64,478.43,256,478.43Z%22/%3E%3Cpath%20d=%22M251.26,161.24a22.39,22.39,0,1,0-22.38-22.39A22.39,22.39,0,0,0,251.26,161.24Z%22/%3E%3Cpath%20d=%22M286.84,357.87h-14v-160A16.79,16.79,0,0,0,256,181.05H225.17a16.79,16.79,0,0,0,0,33.58h14.05V357.87H225.17a16.79,16.79,0,0,0,0,33.57h61.67a16.79,16.79,0,1,0,0-33.57Z%22/%3E%3C/g%3E%3C/svg%3E"); } - -.snotify-icon--success { - background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20version=%221.1%22%20x=%220px%22%20y=%220px%22%20viewBox=%220%200%20512%20512%22%20fill=%22%23c8e6c9%22%3E%3Cg%3E%3Cpath%20d=%22M256,0C114.85,0,0,114.84,0,256S114.85,512,256,512,512,397.16,512,256,397.15,0,256,0Zm0,492.31c-130.29,0-236.31-106-236.31-236.31S125.71,19.69,256,19.69,492.31,125.71,492.31,256,386.29,492.31,256,492.31Z%22/%3E%3Cpath%20class=%22cls-1%22%20d=%22M376.64,151,225.31,321.24l-91.17-72.93a9.85,9.85,0,0,0-12.3,15.38l98.46,78.77a9.86,9.86,0,0,0,13.52-1.15L391.36,164.08A9.85,9.85,0,0,0,376.64,151Z%22/%3E%3C/g%3E%3C/svg%3E"); } - -.snotify-icon--async { - background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20version=%221.1%22%20x=%220px%22%20y=%220px%22%20viewBox=%220%200%20512%20512%22%20fill=%22%23bbdefb%22%3E%3Cg%3E%3Cpath%20d=%22M256,0a32,32,0,0,0-32,32V96a32,32,0,0,0,64,0V32A32,32,0,0,0,256,0Zm0,384a32,32,0,0,0-32,32v64a32,32,0,0,0,64,0V416A32,32,0,0,0,256,384ZM391.74,165.5,437,120.22A32,32,0,0,0,391.74,75L346.5,120.22a32,32,0,0,0,45.25,45.28Zm-271.52,181L75,391.74A32,32,0,0,0,120.22,437l45.25-45.25a32,32,0,0,0-45.25-45.25Zm0-271.52A32,32,0,1,0,75,120.22l45.25,45.28a32,32,0,1,0,45.25-45.28ZM391.74,346.5a32,32,0,0,0-45.25,45.25L391.74,437A32,32,0,0,0,437,391.74ZM480,224H416a32,32,0,0,0,0,64h64a32,32,0,0,0,0-64ZM128,256a32,32,0,0,0-32-32H32a32,32,0,0,0,0,64H96A32,32,0,0,0,128,256Z%22/%3E%3C/g%3E%3C/svg%3E"); - -webkit-animation: async 3s infinite linear; - animation: async 3s infinite linear; - -webkit-transform-origin: 50% 50%; - transform-origin: 50% 50%; } diff --git a/themes-default/slim/static/css/style.css b/themes-default/slim/static/css/style.css index 35eda52ea3..8f6a1168e2 100644 --- a/themes-default/slim/static/css/style.css +++ b/themes-default/slim/static/css/style.css @@ -603,11 +603,6 @@ div.xem { border: 1px solid rgb(136, 136, 136); } -/* Used by the displayShow and snatchSelection show header posters */ -#col-show-summary img.show-image { - max-width: 180px; -} - .background-image img { width: 100%; overflow: hidden; @@ -1143,29 +1138,6 @@ displayShow.mako overflow-y: auto; } -div#col-show-summary { - display: table; -} - -.show-poster-container { - margin-right: 10px; - display: table-cell; - width: 180px; -} - -.ver-spacer { - width: 15px; -} - -#show-specials-and-seasons { - margin-bottom: 15px; -} - -.show-info-container { - overflow: hidden; - display: table-cell; -} - .container-navShow { margin-top: -2px; margin-left: 305px; @@ -1219,65 +1191,17 @@ div#col-show-summary { float: none; } - .show-poster-container { - display: inline-block; - width: 100%; - margin: 0 auto; - border-style: none; - } - - .show-poster-container img { - display: block; - margin: 0 auto; - max-width: 280px !important; - } - .col-md-12 > .horizontal-scroll { margin: 0 -13px; } - - .show-info-container { - display: block; - padding-top: 5px; - width: 100%; - } } @media (min-width: 768px) { - .display-specials, - .display-seasons { - top: -60px; - } - - #show-specials-and-seasons { - bottom: 5px; - right: 15px; - position: absolute; - } - .tvshowImg { max-height: 245px; } } -@media (max-width: 991px) and (min-width: 768px) { - .show-poster-container { - float: left; - display: inline-block; - width: 100%; - border-style: none; - } - - .show-info-container { - display: block; - width: 100%; - } - - #col-show-summary img.show-image { - max-width: 280px; - } -} - @media (min-width: 992px) and (max-width: 1199px) { .pull-md-left { float: left; @@ -1428,10 +1352,6 @@ ul.tags li a { z-index: -2; } -.summaryTable { - overflow: hidden; -} - #checkboxControls { padding-top: 2px; } @@ -1778,6 +1698,10 @@ button.selectColumns { margin-right: 2px; } +.location-invalid { + color: rgb(255, 0, 0); +} + /* ======================================================================= schedule.mako ========================================================================== */ @@ -2606,22 +2530,6 @@ span.true { word-wrap: break-word; } -span.required { - color: green; -} - -span.preferred { - color: blue; -} - -span.undesired { - color: orange; -} - -span.ignored { - color: red; -} - a.wiki { color: red; } @@ -4119,10 +4027,6 @@ div#searchNotification { text-align: center; } -.summaryTable tr td { - word-break: break-all; -} - .release-name-ellipses { overflow: hidden; text-overflow: ellipsis; diff --git a/themes-default/slim/static/images/hearing_impaired.png b/themes-default/slim/static/images/hearing_impaired.png new file mode 100644 index 0000000000..6e56a3820c Binary files /dev/null and b/themes-default/slim/static/images/hearing_impaired.png differ diff --git a/themes-default/slim/static/js/ajax-episode-subtitles.js b/themes-default/slim/static/js/ajax-episode-subtitles.js index 6d0486e6a7..dd6ad733ab 100644 --- a/themes-default/slim/static/js/ajax-episode-subtitles.js +++ b/themes-default/slim/static/js/ajax-episode-subtitles.js @@ -157,12 +157,19 @@ const startAjaxEpisodeSubtitles = function() { // eslint-disable-line no-unused- if (subtitle.sub_score >= subtitle.max_score) { missingGuess = ''; } + // If hearing impaired, add an icon next to subtitle filename + let hearingImpairedTitle = ''; + let hearingImpairedImage = ''; + if (subtitle.hearing_impaired) { + hearingImpairedTitle = 'hearing impaired '; + hearingImpairedImage = ' '; + } // If perfect match, add a checkmark next to subtitle filename let checkmark = ''; if (subtitle.sub_score >= subtitle.min_score) { - checkmark = ''; + checkmark = ' '; } - const subtitleLink = '' + subtitleName + checkmark + ''; + const subtitleLink = '' + hearingImpairedImage + subtitleName + checkmark + ''; // Make subtitle score always between 0 and 10 if (subtitleScore > 10) { subtitleScore = 10; diff --git a/themes-default/slim/static/js/browser.js b/themes-default/slim/static/js/browser.js index 295953f713..7b19c3e3c6 100644 --- a/themes-default/slim/static/js/browser.js +++ b/themes-default/slim/static/js/browser.js @@ -125,7 +125,7 @@ // Set up the browser and launch the dialog let initialDir = ''; if (options.initialDir) { - initialDir = options.initialDir; // eslint-disable-line prefer-destructuring + initialDir = options.initialDir; } browse(initialDir, options.url, options.includeFiles); diff --git a/themes-default/slim/static/js/notifications.js b/themes-default/slim/static/js/notifications.js index 4cfbe7a356..4fd70fe910 100644 --- a/themes-default/slim/static/js/notifications.js +++ b/themes-default/slim/static/js/notifications.js @@ -19,9 +19,9 @@ window.displayNotification = (type, title, message, id) => { desktop: { tag: id }, - text: String(message).replace(/]*)?>/ig, '\n') // eslint-disable-line unicorn/no-unsafe-regex - .replace(/<[/]?b(?:\s[^>]*)?>/ig, '*') // eslint-disable-line unicorn/no-unsafe-regex - .replace(/]*)?>/ig, '[').replace(/<[/]i>/ig, ']') // eslint-disable-line unicorn/no-unsafe-regex - .replace(/<(?:[/]?ul|\/li)(?:\s[^>]*)?>/ig, '').replace(/]*)?>/ig, '\n* ') // eslint-disable-line unicorn/no-unsafe-regex + text: String(message).replace(/]*)?>/ig, '\n') + .replace(/<[/]?b(?:\s[^>]*)?>/ig, '*') + .replace(/]*)?>/ig, '[').replace(/<[/]i>/ig, ']') + .replace(/<(?:[/]?ul|\/li)(?:\s[^>]*)?>/ig, '').replace(/]*)?>/ig, '\n* ') }); }; diff --git a/themes-default/slim/static/js/parsers.js b/themes-default/slim/static/js/parsers.js index 62d90ecfbe..c261159244 100644 --- a/themes-default/slim/static/js/parsers.js +++ b/themes-default/slim/static/js/parsers.js @@ -7,7 +7,7 @@ $.tablesorter.addParser({ if (s.indexOf('Loading...') === 0) { return s.replace('Loading...', '000'); } - return (MEDUSA.config.sortArticle ? (s || '') : (s || '').replace(/^(The|A|An)\s/i, '')); // eslint-disable-line no-undef + return (MEDUSA.config.sortArticle ? (s || '') : (s || '').replace(/^(The|A|An)\s/i, '')); }, type: 'text' }); diff --git a/themes-default/slim/static/js/trending-shows.js b/themes-default/slim/static/js/trending-shows.js index 21d4cdae8a..bf40428607 100644 --- a/themes-default/slim/static/js/trending-shows.js +++ b/themes-default/slim/static/js/trending-shows.js @@ -12,7 +12,7 @@ $(document).ready(() => { getSortData: { name(itemElem) { const name = $(itemElem).attr('data-name') || ''; - return (MEDUSA.config.sortArticle ? name : name.replace(/^(The|A|An)\s/i, '')).toLowerCase(); // eslint-disable-line no-undef + return (MEDUSA.config.sortArticle ? name : name.replace(/^(The|A|An)\s/i, '')).toLowerCase(); }, rating: '[data-rating] parseInt', votes: '[data-votes] parseInt' diff --git a/themes-default/slim/test/__fixtures__/shows.json b/themes-default/slim/test/__fixtures__/shows.json index 406768ead9..4c6682214d 100644 --- a/themes-default/slim/test/__fixtures__/shows.json +++ b/themes-default/slim/test/__fixtures__/shows.json @@ -60,7 +60,7 @@ "subtitlesEnabled": true, "anime": false }, - "country_codes": [ + "countryCodes": [ "gb" ], "runtime": 60, @@ -125,7 +125,7 @@ "subtitlesEnabled": true, "anime": false }, - "country_codes": [], + "countryCodes": [], "runtime": 25, "type": "Scripted", "id": { @@ -194,7 +194,7 @@ "subtitlesEnabled": true, "anime": false }, - "country_codes": [ + "countryCodes": [ "gb" ], "runtime": 25, diff --git a/themes-default/slim/test/helpers/generators.js b/themes-default/slim/test/helpers/generators.js index c6380b4e5e..1ac683d058 100644 --- a/themes-default/slim/test/helpers/generators.js +++ b/themes-default/slim/test/helpers/generators.js @@ -10,19 +10,19 @@ const generatePropTest = component => { /** * A simple component prop test case. * - * @param {*} t - AVA test with a context containing `localVue` and `store` properties. + * @param {localVue} localVue property. + * @param {store} store property. * @param {string} message - Test message. * @param {object} propsData - Props to pass to the component. */ - const propTest = (t, message, propsData) => { - const { localVue, store } = t.context; - - t.snapshot(mount(component, { + const propTest = (localVue, store, message, propsData) => { + expect(mount(component, { localVue, store, propsData - }).html(), message); + }).element).toMatchSnapshot(message); }; + return propTest; }; diff --git a/themes-default/slim/test/helpers/setup.js b/themes-default/slim/test/helpers/setup.js index a9f04d39d8..6915f5cb9e 100644 --- a/themes-default/slim/test/helpers/setup.js +++ b/themes-default/slim/test/helpers/setup.js @@ -1,6 +1,5 @@ import browserEnv from 'browser-env'; -import jQuery from 'jquery'; -import hooks from 'require-extension-hooks'; +import $ from 'jquery'; // Setup browser environment browserEnv({ @@ -11,13 +10,8 @@ browserEnv({ // Setup document variables const baseElement = document.createElement('base'); baseElement.setAttribute('href', 'http://localhost:8081'); -document.head.appendChild(baseElement); +document.head.append(baseElement); // Setup jQuery -global.$ = jQuery(window); - -// Setup vue files to be processed by `require-extension-hooks-vue` -hooks('vue').plugin('vue').push(); -// Setup vue and js files to be processed by `require-extension-hooks-babel` -// This also requires `require-extension-hooks-vue` -hooks(['vue', 'js']).plugin('babel').push(); +global.$ = $; +global.jQuery = $; diff --git a/themes-default/slim/test/specs/__snapshots__/add-recommended.spec.js.snap b/themes-default/slim/test/specs/__snapshots__/add-recommended.spec.js.snap new file mode 100644 index 0000000000..58231725f5 --- /dev/null +++ b/themes-default/slim/test/specs/__snapshots__/add-recommended.spec.js.snap @@ -0,0 +1,88 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AddRecommended.test.js renders 1`] = ` +
+ +
+
+
+ +
+

+ Add From Trakt Lists +

+ +

+ For shows that you haven't downloaded yet, this option lets you choose from a show from one of the Trakt lists to add to Medusa . +

+
+ + + +
+
+
+ +
+

+ Add From IMDB's Popular Shows +

+ +

+ View IMDB's list of the most popular shows. This feature uses IMDB's MOVIEMeter algorithm to identify popular TV Shows. +

+
+ + + +
+
+
+ +
+

+ Add From Anidb's Hot Anime list +

+ +

+ View Anidb's list of the most popular anime shows. Anidb provides lists for Popular Anime, using the "Hot Anime" list. +

+
+ +
+`; diff --git a/themes-default/slim/test/specs/__snapshots__/add-show-options.spec.js.snap b/themes-default/slim/test/specs/__snapshots__/add-show-options.spec.js.snap new file mode 100644 index 0000000000..8e9ae9f4c7 --- /dev/null +++ b/themes-default/slim/test/specs/__snapshots__/add-show-options.spec.js.snap @@ -0,0 +1,575 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AddShowOptions.test.js renders with \`enable-anime-options\` disabled 1`] = ` +
+
+
+
+ + +
+ +
+
+
+ +
+
+
+
+ + +
+ + +

+ Download subtitles for this show? +

+ +
+
+
+
+
+ +
+
+ + +
+ +
+
+
+ +
+
+ + +
+ +
+
+
+ +
+
+
+ + +
+ + +

+ Group episodes by season folders? +

+ +
+
+
+
+ + + + + +
+
+
+ + +
+ + +

+ Is this show scene numbered? +

+ +
+
+
+
+ +
+
+ + +
+ +
+
+
+
+
+`; + +exports[`AddShowOptions.test.js renders with \`enable-anime-options\` enabled 1`] = ` +
+
+
+
+ + +
+ +
+
+
+ +
+
+
+
+ + +
+ + +

+ Download subtitles for this show? +

+ +
+
+
+
+
+ +
+
+ + +
+ +
+
+
+ +
+
+ + +
+ +
+
+
+ +
+
+
+ + +
+ + +

+ Group episodes by season folders? +

+ +
+
+
+
+ +
+
+
+ + +
+ + +

+ Is this show an Anime? +

+ +
+
+
+
+ + + +
+
+
+ + +
+ + +

+ Is this show scene numbered? +

+ +
+
+
+
+ +
+
+ + +
+ +
+
+
+
+
+`; diff --git a/themes-default/slim/test/specs/__snapshots__/add-shows.spec.js.snap b/themes-default/slim/test/specs/__snapshots__/add-shows.spec.js.snap new file mode 100644 index 0000000000..18c0947705 --- /dev/null +++ b/themes-default/slim/test/specs/__snapshots__/add-shows.spec.js.snap @@ -0,0 +1,61 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AddShows.test.js renders 1`] = ` +
+ +
+
+
+ +
+

+ Add New Show +

+ +

+ For shows that you haven't downloaded yet, this option finds a show on your preferred indexer, creates a directory for it's episodes, and adds it to Medusa. +

+
+ + + +
+
+
+ +
+

+ Add Existing Shows +

+ +

+ Use this option to add shows that already have a folder created on your hard drive. Medusa will scan your existing metadata/episodes and add the show accordingly. +

+
+ +
+`; diff --git a/themes-default/slim/test/specs/__snapshots__/anidb-release-group-ui.spec.js.snap b/themes-default/slim/test/specs/__snapshots__/anidb-release-group-ui.spec.js.snap new file mode 100644 index 0000000000..c7b81c6cee --- /dev/null +++ b/themes-default/slim/test/specs/__snapshots__/anidb-release-group-ui.spec.js.snap @@ -0,0 +1,97 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AnidbReleaseGroupUi.test.js renders 1`] = ` +
+
+
+ + Whitelist + + + +
    + +
    + +
    +
+
+ +
+ + Release groups + + +
    + +
    + +
    +
+
+ +
+ + Blacklist + + + +
    + +
    + +
    +
+
+
+ +
+
+ +
+ +
+

+ Use the input to add custom whitelist / blacklist release groups. Click on the + + to add it to the correct list. +

+
+
+
+`; diff --git a/themes-default/slim/test/specs/__snapshots__/app-header.spec.js.snap b/themes-default/slim/test/specs/__snapshots__/app-header.spec.js.snap new file mode 100644 index 0000000000..e0201caec2 --- /dev/null +++ b/themes-default/slim/test/specs/__snapshots__/app-header.spec.js.snap @@ -0,0 +1,675 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AppHeader.test.js renders 1`] = ` + +`; diff --git a/themes-default/slim/test/specs/__snapshots__/app-link.spec.js.snap b/themes-default/slim/test/specs/__snapshots__/app-link.spec.js.snap new file mode 100644 index 0000000000..6c8801f289 --- /dev/null +++ b/themes-default/slim/test/specs/__snapshots__/app-link.spec.js.snap @@ -0,0 +1,55 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AppLink.test.js renders "false-link" anchor 1`] = ` + +`; + +exports[`AppLink.test.js renders anonymised external link 1`] = ` + +`; + +exports[`AppLink.test.js renders external link 1`] = ` + +`; + +exports[`AppLink.test.js renders internal link 1`] = ` + +`; + +exports[`AppLink.test.js renders router-link from to (object) 1`] = ` + +`; + +exports[`AppLink.test.js renders router-link from to (string) 1`] = ` + +`; + +exports[`AppLink.test.js renders simple anchor 1`] = ` + +`; diff --git a/themes-default/slim/test/specs/__snapshots__/asset.spec.js.snap b/themes-default/slim/test/specs/__snapshots__/asset.spec.js.snap new file mode 100644 index 0000000000..3949d4971c --- /dev/null +++ b/themes-default/slim/test/specs/__snapshots__/asset.spec.js.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Asset.test.js renders default content for network 1`] = ` + +`; + +exports[`Asset.test.js renders image with API v2 path for network 1`] = ` + +`; diff --git a/themes-default/slim/test/specs/__snapshots__/config-post-processing.spec.js.snap b/themes-default/slim/test/specs/__snapshots__/config-post-processing.spec.js.snap new file mode 100644 index 0000000000..41fce65e2e --- /dev/null +++ b/themes-default/slim/test/specs/__snapshots__/config-post-processing.spec.js.snap @@ -0,0 +1,3191 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ConfigPostProcessing.test.js renders 1`] = ` +
+
+
+
+
    +
  • + + Post Processing + +
  • + +
  • + + Episode Naming + +
  • + +
  • + + Metadata + +
  • +
+ +
+
+
+

+ Scheduled Post-Processing +

+ +

+ Settings that dictate how Medusa should process completed downloads. +

+ +

+ The scheduled postprocessor will periodically scan a folder for media to process. +

+
+ +
+
+
+ + +
+ + +

+ Enable the scheduled post processor to scan and process any files in your + + Post Processing Dir + + ? +

+ +
+

+ + NOTE: + + Do not use if you use an external Post Processing script +

+
+
+
+ +
+
+ + +
+ + + + The folder where your download client puts the completed TV downloads. + + +
+

+ + NOTE: + + Please use seperate downloading and completed folders in your download client if possible. +

+
+
+
+ +
+ + +
+ + + + What method should be used to put files into the library? + + +

+ + NOTE: + + If you keep seeding torrents after they finish, please avoid the 'move' processing method to prevent errors. +

+ + +
+
+ +
+ + +
+ + + + Time in minutes to check for new files to auto post-process (min 10) + +
+
+
+
+
+
+ +
+
+

+ General Post-Processing +

+ +

+ Generic postprocessing settings that apply both to the scheduled postprocessor as external scripts +

+
+ +
+
+
+ + +
+ + + + Wait to process a folder if sync files are present. + +
+
+ +
+ + +
+ + + + comma seperated list of extensions or filename globs Medusa ignores when Post Processing + +
+
+ +
+ + +
+ + + + Wait to process a file until subtitles are present + +
+ + + Language names are allowed in subtitle filename (en.srt, pt-br.srt, ita.srt, etc.) + +
+ + + + NOTE: + + Automatic post processor should be disabled to avoid files with pending subtitles being processed over and over. + +
+ + + If you have any active show with subtitle search disabled, you must enable Automatic post processor. + +
+
+ +
+ + +
+ + + + Rename episode using the Episode Naming settings? + +
+
+ +
+ + +
+ + + + Create missing show directories when they get deleted + +
+
+ +
+ + +
+ + + + Add shows without creating a directory (not recommended) + +
+
+ +
+ + +
+ + + + Delete srt/srr/sfv/etc files while post processing? + +
+
+ +
+ + +
+ + + + Comma seperated list of associated file extensions Medusa should keep while post processing. + +
+ + + Leaving it empty means all associated files will be deleted + +
+
+ +
+ + +
+ + + + Rename the original .nfo file to .nfo-orig to avoid conflicts? + +
+
+ +
+ + +
+ + + + Set last modified filedate to the date that the episode aired? + +
+
+ +
+ + +
+ + + + What timezone should be used to change File Date? + +
+
+ +
+ + +
+ + + + Unpack any TV releases in your + + TV Download Dir + + ? + +
+ + + + NOTE: + + Only working with RAR archive + +
+
+ +
+ + +
+ + + + Delete content of RAR files, even if Process Method not set to move? + +
+
+ +
+ + +
+ + + + Leave empty folders when Post Processing? + +
+ + + + NOTE: + + Can be overridden using manual Post Processing + +
+
+ +
+ + +
+ + + + See + + + Wiki + + + for script arguments description and usage. + +
+
+
+ + +
+
+
+ +
+
+
+

+ Episode Naming +

+ +

+ How Medusa will name and sort your episodes. +

+
+ +
+
+ + + + + + + + +
+ + +
+ + + + Remove the TV show's year when renaming the file? + + +

+ Only applies to shows that have year inside parentheses +

+
+
+
+
+
+
+ +
+
+
+

+ Metadata +

+ +

+ The data associated to the data. These are files associated to a TV show in the form of images and text that, when supported, will enhance the viewing experience. +

+
+ +
+
+
+ + +
+ + + + Toggle the metadata options that you wish to be created. + + Multiple targets may be used. + + +
+
+ +
+ + + +
+ + + + + + +
+ + +
+
+
+
+ +
+ + All non-absolute folder locations are relative to + + + + +
+ + +
+
+
+
+`; diff --git a/themes-default/slim/test/specs/__snapshots__/config-textbox-number.spec.js.snap b/themes-default/slim/test/specs/__snapshots__/config-textbox-number.spec.js.snap new file mode 100644 index 0000000000..7c861c5140 --- /dev/null +++ b/themes-default/slim/test/specs/__snapshots__/config-textbox-number.spec.js.snap @@ -0,0 +1,92 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ConfigTextboxNumber.test.js renders 1`] = ` +
+
+
+ + +
+ + +

+ explanation 1 +

+

+ explanation 2 +

+ +
+
+
+
+`; + +exports[`ConfigTextboxNumber.test.js renders with min and max 1`] = ` +
+
+
+ + +
+ + +

+ explanation 1 +

+

+ explanation 2 +

+ +
+
+
+
+`; diff --git a/themes-default/slim/test/specs/__snapshots__/config-textbox.spec.js.snap b/themes-default/slim/test/specs/__snapshots__/config-textbox.spec.js.snap new file mode 100644 index 0000000000..9f3828a50f --- /dev/null +++ b/themes-default/slim/test/specs/__snapshots__/config-textbox.spec.js.snap @@ -0,0 +1,44 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ConfigTextbox.test.js renders 1`] = ` +
+
+
+ + +
+ + +

+ explanation 1 +

+

+ explanation 2 +

+ +
+
+
+
+`; diff --git a/themes-default/slim/test/specs/__snapshots__/config-toggle-slider.spec.js.snap b/themes-default/slim/test/specs/__snapshots__/config-toggle-slider.spec.js.snap new file mode 100644 index 0000000000..c533da6ad9 --- /dev/null +++ b/themes-default/slim/test/specs/__snapshots__/config-toggle-slider.spec.js.snap @@ -0,0 +1,47 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ConfigToggleSlider.test.js renders 1`] = ` +
+
+
+ + +
+ + +

+ explanation 1 +

+

+ explanation 2 +

+ +
+
+
+
+`; diff --git a/themes-default/slim/test/specs/__snapshots__/config.spec.js.snap b/themes-default/slim/test/specs/__snapshots__/config.spec.js.snap new file mode 100644 index 0000000000..be131d3bc0 --- /dev/null +++ b/themes-default/slim/test/specs/__snapshots__/config.spec.js.snap @@ -0,0 +1,335 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Config.test.js renders 1`] = ` +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + Medusa Info: + + + Branch: + + + + master + + + +
+ + Commit: + + + + f5973b28465246e67465d7d86bdc8aa74d13e659 + + + +
+ + Version: + + + + v0.2.8 + + + +
+ + Database: + + + 44.11 + +
+ + Python Version: + + 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] +
+ + SSL Version: + + +
+ + OS: + + +
+ + Locale: + + +
+   + +   +
+   + +   +
+ + User: + + +
+ + Program Folder: + + +
+ + Config File: + + +
+ + Database File: + + +
+ + Cache Folder: + + +
+ + Log Folder: + + +
+ + Arguments: + +
+          [
+    "--nolaunch",
+    "--datadir=C:\\\\Medusa\\\\Data"
+]
+        
+
+   + +   +
+   + +   +
+ + Website: + + + + +
+ + Wiki: + + + + +
+ + Source: + + + https://github.com/pymedusa/Medusa + +
+ + IRC Chat: + + + + #pymedusa + + on + + irc.freenode.net + + +
+
+`; diff --git a/themes-default/slim/test/specs/__snapshots__/irc.spec.js.snap b/themes-default/slim/test/specs/__snapshots__/irc.spec.js.snap new file mode 100644 index 0000000000..477024ad27 --- /dev/null +++ b/themes-default/slim/test/specs/__snapshots__/irc.spec.js.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`IRC.test.js renders 1`] = ` +' - -## renders with username - -> Snapshot 1 - - '' diff --git a/themes-default/slim/test/specs/snapshots/irc.spec.js.snap b/themes-default/slim/test/specs/snapshots/irc.spec.js.snap deleted file mode 100644 index 3ea1ae1884..0000000000 Binary files a/themes-default/slim/test/specs/snapshots/irc.spec.js.snap and /dev/null differ diff --git a/themes-default/slim/test/specs/snapshots/login.spec.js.md b/themes-default/slim/test/specs/snapshots/login.spec.js.md deleted file mode 100644 index d0d7348f6c..0000000000 --- a/themes-default/slim/test/specs/snapshots/login.spec.js.md +++ /dev/null @@ -1,11 +0,0 @@ -# Snapshot report for `test/specs/login.spec.js` - -The actual snapshot is saved in `login.spec.js.snap`. - -Generated by [AVA](https://ava.li). - -## renders - -> Snapshot 1 - - '' diff --git a/themes-default/slim/test/specs/snapshots/login.spec.js.snap b/themes-default/slim/test/specs/snapshots/login.spec.js.snap deleted file mode 100644 index c4960c94df..0000000000 Binary files a/themes-default/slim/test/specs/snapshots/login.spec.js.snap and /dev/null differ diff --git a/themes-default/slim/test/specs/snapshots/name-pattern.spec.js.md b/themes-default/slim/test/specs/snapshots/name-pattern.spec.js.md deleted file mode 100644 index 9a9c7370b0..0000000000 --- a/themes-default/slim/test/specs/snapshots/name-pattern.spec.js.md +++ /dev/null @@ -1,11 +0,0 @@ -# Snapshot report for `test/specs/name-pattern.spec.js` - -The actual snapshot is saved in `name-pattern.spec.js.snap`. - -Generated by [AVA](https://ava.li). - -## renders - -> Snapshot 1 - - '

Single-EP Sample:

Multi-EP sample:

' diff --git a/themes-default/slim/test/specs/snapshots/name-pattern.spec.js.snap b/themes-default/slim/test/specs/snapshots/name-pattern.spec.js.snap deleted file mode 100644 index 8a58c89a41..0000000000 Binary files a/themes-default/slim/test/specs/snapshots/name-pattern.spec.js.snap and /dev/null differ diff --git a/themes-default/slim/test/specs/snapshots/plot-info.spec.js.md b/themes-default/slim/test/specs/snapshots/plot-info.spec.js.md deleted file mode 100644 index 36e503f864..0000000000 --- a/themes-default/slim/test/specs/snapshots/plot-info.spec.js.md +++ /dev/null @@ -1,11 +0,0 @@ -# Snapshot report for `test/specs/plot-info.spec.js` - -The actual snapshot is saved in `plot-info.spec.js.snap`. - -Generated by [AVA](https://ava.li). - -## renders - -> Snapshot 1 - - '' diff --git a/themes-default/slim/test/specs/snapshots/plot-info.spec.js.snap b/themes-default/slim/test/specs/snapshots/plot-info.spec.js.snap deleted file mode 100644 index 70979c07ca..0000000000 Binary files a/themes-default/slim/test/specs/snapshots/plot-info.spec.js.snap and /dev/null differ diff --git a/themes-default/slim/test/specs/snapshots/quality-pill.spec.js.md b/themes-default/slim/test/specs/snapshots/quality-pill.spec.js.md deleted file mode 100644 index 85972b44a7..0000000000 --- a/themes-default/slim/test/specs/snapshots/quality-pill.spec.js.md +++ /dev/null @@ -1,149 +0,0 @@ -# Snapshot report for `test/specs/quality-pill.spec.js` - -The actual snapshot is saved in `quality-pill.spec.js.snap`. - -Generated by [AVA](https://ava.li). - -## renders quality pills correctly - -> No qualities - - 'N/A' - -> No qualities, with show-title - - `N/A` - -> Unknown, allowed - - 'Unknown' - -> SDTV, allowed - - 'SDTV' - -> SD DVD, allowed - - 'SD DVD' - -> RawHD, allowed - - 'RawHD' - -> SD (TV+DVD), allowed - - 'SD' - -> 1080p WEB-DL, allowed - - '1080p WEB-DL' - -> All 720p and all 1080p, allowed - - 'HD' - -> WEB-DL 720p + 4K UHD WEB-DL, allowed - - 'WEB-DL' - -> 720p WEB-DL allowed + 1080p WEB-DL preferred, with show title - - `WEB-DL` - -> Custom pill using overrides - - 'Proper' - -> Quality set: Any HDTV, with show title - - `HDTV` - -> Both quality lists are of HDTV source, with show title - - `HDTV` - -> Both quality lists are of WEB-DL source, with show title - - `WEB-DL` - -> Both quality lists are of BluRay source, with show title - - `BluRay` - -> Both quality lists are of 720p resolution, with show title - - `720p` - -> Both quality lists are of 1080p resolution, with show title - - `1080p` - -> Both quality lists are of 4K UHD resolution, with show title - - `UHD-4K` - -> Both quality lists are of 8K UHD resolution, with show title - - `UHD-8K` - -> Custom quality lists, with show title - - `Custom` diff --git a/themes-default/slim/test/specs/snapshots/quality-pill.spec.js.snap b/themes-default/slim/test/specs/snapshots/quality-pill.spec.js.snap deleted file mode 100644 index 2ab392ca3a..0000000000 Binary files a/themes-default/slim/test/specs/snapshots/quality-pill.spec.js.snap and /dev/null differ diff --git a/themes-default/slim/test/specs/snapshots/root-dirs.spec.js.md b/themes-default/slim/test/specs/snapshots/root-dirs.spec.js.md deleted file mode 100644 index 174c9635ae..0000000000 --- a/themes-default/slim/test/specs/snapshots/root-dirs.spec.js.md +++ /dev/null @@ -1,23 +0,0 @@ -# Snapshot report for `test/specs/root-dirs.spec.js` - -The actual snapshot is saved in `root-dirs.spec.js.snap`. - -Generated by [AVA](https://ava.li). - -## renders and changing default/selected - -> Base snapshot - - `
` - -> After changing the default root dir - - `
` diff --git a/themes-default/slim/test/specs/snapshots/root-dirs.spec.js.snap b/themes-default/slim/test/specs/snapshots/root-dirs.spec.js.snap deleted file mode 100644 index 03e2b6f3da..0000000000 Binary files a/themes-default/slim/test/specs/snapshots/root-dirs.spec.js.snap and /dev/null differ diff --git a/themes-default/slim/test/specs/snapshots/scroll-buttons.spec.js.md b/themes-default/slim/test/specs/snapshots/scroll-buttons.spec.js.md deleted file mode 100644 index 0508fffc17..0000000000 --- a/themes-default/slim/test/specs/snapshots/scroll-buttons.spec.js.md +++ /dev/null @@ -1,11 +0,0 @@ -# Snapshot report for `test/specs/scroll-buttons.spec.js` - -The actual snapshot is saved in `scroll-buttons.spec.js.snap`. - -Generated by [AVA](https://ava.li). - -## renders - -> Snapshot 1 - - '
' diff --git a/themes-default/slim/test/specs/snapshots/scroll-buttons.spec.js.snap b/themes-default/slim/test/specs/snapshots/scroll-buttons.spec.js.snap deleted file mode 100644 index 16315db238..0000000000 Binary files a/themes-default/slim/test/specs/snapshots/scroll-buttons.spec.js.snap and /dev/null differ diff --git a/themes-default/slim/test/specs/snapshots/select-list.spec.js.md b/themes-default/slim/test/specs/snapshots/select-list.spec.js.md deleted file mode 100644 index e262dafad8..0000000000 --- a/themes-default/slim/test/specs/snapshots/select-list.spec.js.md +++ /dev/null @@ -1,17 +0,0 @@ -# Snapshot report for `test/specs/select-list.spec.js` - -The actual snapshot is saved in `select-list.spec.js.snap`. - -Generated by [AVA](https://ava.li). - -## renders - -> Snapshot 1 - - '
' - -## renders with values - -> Snapshot 1 - - '
' diff --git a/themes-default/slim/test/specs/snapshots/select-list.spec.js.snap b/themes-default/slim/test/specs/snapshots/select-list.spec.js.snap deleted file mode 100644 index 07183028c1..0000000000 Binary files a/themes-default/slim/test/specs/snapshots/select-list.spec.js.snap and /dev/null differ diff --git a/themes-default/slim/test/specs/snapshots/show-selector.spec.js.md b/themes-default/slim/test/specs/snapshots/show-selector.spec.js.md deleted file mode 100644 index 4e2adcff1c..0000000000 --- a/themes-default/slim/test/specs/snapshots/show-selector.spec.js.md +++ /dev/null @@ -1,35 +0,0 @@ -# Snapshot report for `test/specs/show-selector.spec.js` - -The actual snapshot is saved in `show-selector.spec.js.snap`. - -Generated by [AVA](https://ava.li). - -## renders "loading..." with empty show array - -> Snapshot 1 - - 'Loading...' - -## renders with articles(The|A|An) ignored - -> Snapshot 1 - - '
' - -## renders with shows - -> Snapshot 1 - - '
' - -## renders with split sections - -> Snapshot 1 - - '
' - -## renders without placeholder - -> Snapshot 1 - - '
' diff --git a/themes-default/slim/test/specs/snapshots/show-selector.spec.js.snap b/themes-default/slim/test/specs/snapshots/show-selector.spec.js.snap deleted file mode 100644 index c5a344821e..0000000000 Binary files a/themes-default/slim/test/specs/snapshots/show-selector.spec.js.snap and /dev/null differ diff --git a/themes-default/slim/test/specs/snapshots/state-switch.spec.js.md b/themes-default/slim/test/specs/snapshots/state-switch.spec.js.md deleted file mode 100644 index a8c4c7fb33..0000000000 --- a/themes-default/slim/test/specs/snapshots/state-switch.spec.js.md +++ /dev/null @@ -1,35 +0,0 @@ -# Snapshot report for `test/specs/state-switch.spec.js` - -The actual snapshot is saved in `state-switch.spec.js.snap`. - -Generated by [AVA](https://ava.li). - -## renders - -> loading with `null` - - 'Loading' - -> loading with string - - 'Loading' - -> loading with `theme` prop - - 'Loading' - -> yes with `true` - - 'Yes' - -> yes with string - - 'Yes' - -> no with `false` - - 'No' - -> no with string - - 'No' diff --git a/themes-default/slim/test/specs/snapshots/state-switch.spec.js.snap b/themes-default/slim/test/specs/snapshots/state-switch.spec.js.snap deleted file mode 100644 index 1cf49aa74d..0000000000 Binary files a/themes-default/slim/test/specs/snapshots/state-switch.spec.js.snap and /dev/null differ diff --git a/themes-default/slim/test/specs/state-switch.spec.js b/themes-default/slim/test/specs/state-switch.spec.js index e60ab9a517..d47f1648b4 100644 --- a/themes-default/slim/test/specs/state-switch.spec.js +++ b/themes-default/slim/test/specs/state-switch.spec.js @@ -1,41 +1,45 @@ -import test from 'ava'; import { createLocalVue } from '@vue/test-utils'; import { StateSwitch } from '../../src/components'; import { generatePropTest } from '../helpers/generators'; -test.beforeEach(t => { - t.context.localVue = createLocalVue(); -}); - -const stateTestCase = generatePropTest(StateSwitch); +describe('StateSwitch.test.js', () => { + let localVue; + const store = {}; -test('renders', t => { - stateTestCase(t, 'loading with `null`', { - state: null + beforeEach(() => { + localVue = createLocalVue(); }); - stateTestCase(t, 'loading with string', { - state: 'loading' - }); + const stateTestCase = generatePropTest(StateSwitch); - stateTestCase(t, 'loading with `theme` prop', { - theme: 'light', - state: 'loading' - }); + it('renders', () => { + stateTestCase(localVue, store, 'loading with `null`', { + state: null + }); - stateTestCase(t, 'yes with `true`', { - state: true - }); + stateTestCase(localVue, store, 'loading with string', { + state: 'loading' + }); - stateTestCase(t, 'yes with string', { - state: 'yes' - }); + stateTestCase(localVue, store, 'loading with `theme` prop', { + theme: 'light', + state: 'loading' + }); - stateTestCase(t, 'no with `false`', { - state: false - }); + stateTestCase(localVue, store, 'yes with `true`', { + state: true + }); + + stateTestCase(localVue, store, 'yes with string', { + state: 'yes' + }); + + stateTestCase(localVue, store, 'no with `false`', { + state: false + }); - stateTestCase(t, 'no with string', { - state: 'no' + stateTestCase(localVue, store, 'no with string', { + state: 'no' + }); }); }); diff --git a/themes-default/slim/test/specs/utils.spec.js b/themes-default/slim/test/specs/utils.spec.js index 8bba0a9d90..bcc28de814 100644 --- a/themes-default/slim/test/specs/utils.spec.js +++ b/themes-default/slim/test/specs/utils.spec.js @@ -1,15 +1,17 @@ -import test from 'ava'; import { combineQualities } from '../../src/utils'; -const testCases = [ - /* C0 */ { allowed: [1, 2, 4], preferred: [], expected: 7 }, - /* C1 */ { allowed: [1], preferred: [2, 4], expected: 393217 }, - /* C2 */ { allowed: [32768], preferred: [32768], expected: 2147516416 } -]; -testCases.forEach(({ allowed, preferred, expected }, caseIndex) => { - const testTitle = `[C${caseIndex}] combineQualities(${JSON.stringify(allowed)}, ${JSON.stringify(preferred)})`; - test(testTitle, t => { - const actual = combineQualities(allowed, preferred); - t.is(actual, expected); +describe('combineQualities.test.js', () => { + const testCases = [ + /* C0 */ { allowed: [1, 2, 4], preferred: [], expected: 7 }, + /* C1 */ { allowed: [1], preferred: [2, 4], expected: 393217 }, + /* C2 */ { allowed: [32768], preferred: [32768], expected: 2147516416 } + ]; + + testCases.forEach(({ allowed, preferred, expected }, caseIndex) => { + const testTitle = `[C${caseIndex}] combineQualities(${JSON.stringify(allowed)}, ${JSON.stringify(preferred)})`; + it(testTitle, () => { + const actual = combineQualities(allowed, preferred); + expect(actual).toEqual(expected); + }); }); }); diff --git a/themes-default/slim/views/apiBuilder.mako b/themes-default/slim/views/apiBuilder.mako index 72499251bd..c319ec9798 100644 --- a/themes-default/slim/views/apiBuilder.mako +++ b/themes-default/slim/views/apiBuilder.mako @@ -1,6 +1,6 @@ <%! from medusa import app - from six import binary_type + from six import text_type %> @@ -133,7 +133,7 @@
diff --git a/themes-default/slim/views/config_general.mako b/themes-default/slim/views/config_general.mako index 4216de5faf..4465997f56 100644 --- a/themes-default/slim/views/config_general.mako +++ b/themes-default/slim/views/config_general.mako @@ -381,7 +381,7 @@ window.app = new Vue({ diff --git a/themes-default/slim/views/config_notifications.mako b/themes-default/slim/views/config_notifications.mako index f6ba873be2..4d64161460 100644 --- a/themes-default/slim/views/config_notifications.mako +++ b/themes-default/slim/views/config_notifications.mako @@ -153,7 +153,7 @@ window.app = new Vue({ enabled: null, api: [], messageTitle: null, - piority: null, + priority: null, notifyOnSnatch: null, notifyOnDownload: null, notifyOnSubtitleDownload: null @@ -451,7 +451,7 @@ window.app = new Vue({ const response = await apiRoute('home/testTwitter'); const { data } = response; this.twitterTestInfo = data; - } catch { + } catch (e) { this.twitterTestInfo = 'Error while trying to request for a test on the twitter api.' } }, @@ -1659,7 +1659,7 @@ window.app = new Vue({ - + @@ -1668,7 +1668,7 @@ window.app = new Vue({ - + +
diff --git a/themes-default/slim/views/config_search.mako b/themes-default/slim/views/config_search.mako index 318e56986f..a164434a65 100644 --- a/themes-default/slim/views/config_search.mako +++ b/themes-default/slim/views/config_search.mako @@ -48,7 +48,8 @@ window.app = new Vue({ labelOption: true, labelAnimeOption: true, seedTimeOption: true, - pausedOption: true + pausedOption: true, + testStatus: 'Click below to test' }, transmission: { title: 'Transmission', @@ -58,6 +59,7 @@ window.app = new Vue({ seedLocationOption: true, seedTimeOption: true, pausedOption: true, + testStatus: 'Click below to test' }, deluge: { title: 'Deluge (via WebUI)', @@ -69,7 +71,8 @@ window.app = new Vue({ labelAnimeOption: true, seedLocationOption: true, pausedOption: true, - verifyCertOption: true + verifyCertOption: true, + testStatus: 'Click below to test' }, deluged: { title: 'Deluge (via Daemon)', @@ -81,12 +84,14 @@ window.app = new Vue({ labelAnimeOption: true, seedLocationOption: true, pausedOption: true, - verifyCertOption: true + verifyCertOption: true, + testStatus: 'Click below to test' }, downloadstation: { title: 'Synology DS', description: 'URL to your Synology DS client (e.g. http://localhost:5000)', - pathOption: true + pathOption: true, + testStatus: 'Click below to test' }, rtorrent: { title: 'rTorrent', @@ -94,19 +99,22 @@ window.app = new Vue({ pathOption: true, labelOption: true, labelAnimeOption: true, - verifyCertOption: true + verifyCertOption: true, + testStatus: 'Click below to test' }, qbittorrent: { title: 'qBittorrent', description: 'URL to your qBittorrent client (e.g. http://localhost:8080)', labelOption: true, labelAnimeOption: true, - pausedOption: true + pausedOption: true, + testStatus: 'Click below to test' }, mlnet: { title: 'MLDonkey', description: 'URL to your MLDonkey (e.g. http://localhost:4080)', - verifyCertOption: true + verifyCertOption: true, + testStatus: 'Click below to test' } }, nzb: { @@ -138,7 +146,7 @@ window.app = new Vue({ method: null, path: null, paused: null, - rpcurl: null, + rpcUrl: null, seedLocation: null, seedTime: null, username: null, @@ -457,7 +465,7 @@ window.app = new Vue({
- +

time in minutes between searches (min. {{search.general.minBacklogFrequency}})

diff --git a/themes-default/slim/views/displayShow.mako b/themes-default/slim/views/displayShow.mako index 1bf57ac7d7..75738eb48e 100644 --- a/themes-default/slim/views/displayShow.mako +++ b/themes-default/slim/views/displayShow.mako @@ -9,12 +9,14 @@ %> <%block name="scripts"> <%block name="scripts" /> diff --git a/themes-default/slim/views/partials/footer.mako b/themes-default/slim/views/partials/footer.mako index 555009f14f..697e1356bd 100644 --- a/themes-default/slim/views/partials/footer.mako +++ b/themes-default/slim/views/partials/footer.mako @@ -6,6 +6,7 @@ import re from medusa import app from medusa.helper.common import pretty_file_size + from medusa.sbdatetime import sbdatetime from medusa.show.show import Show mem_usage = None @@ -50,7 +51,7 @@ % endif Load time: ${"%.4f" % (time() - sbStartTime)}s / Mako: ${"%.4f" % (time() - makoStartTime)}s | Branch: ${app.BRANCH} | - Now: ${datetime.now().strftime(app.DATE_PRESET+" "+app.TIME_PRESET).decode(app.SYS_ENCODING)} + Now: ${sbdatetime.now().sbfdatetime(d_preset=app.DATE_PRESET, t_preset=app.TIME_PRESET)}
diff --git a/themes-default/slim/views/partials/home/banner.mako b/themes-default/slim/views/partials/home/banner.mako index 8f8d9d08ca..aa57699878 100644 --- a/themes-default/slim/views/partials/home/banner.mako +++ b/themes-default/slim/views/partials/home/banner.mako @@ -114,7 +114,7 @@ else: den = 1 download_stat_tip = "Unaired" - progressbar_percent = nom * 100 / den + progressbar_percent = nom * 100 // den %> % if cur_airs_next: diff --git a/themes-default/slim/views/partials/home/poster.mako b/themes-default/slim/views/partials/home/poster.mako index a79a95dbed..19bd7d8308 100644 --- a/themes-default/slim/views/partials/home/poster.mako +++ b/themes-default/slim/views/partials/home/poster.mako @@ -87,7 +87,7 @@ else: den = 1 download_stat_tip = "Unaired" - progressbar_percent = nom * 100 / den + progressbar_percent = nom * 100 // den data_date = '6000000000.0' if cur_airs_next: data_date = calendar.timegm(sbdatetime.sbdatetime.convert_to_setting(network_timezones.parse_date_time(cur_airs_next, cur_show.airs, cur_show.network)).timetuple()) diff --git a/themes-default/slim/views/partials/home/simple.mako b/themes-default/slim/views/partials/home/simple.mako index b99e248710..a90ba2d533 100644 --- a/themes-default/slim/views/partials/home/simple.mako +++ b/themes-default/slim/views/partials/home/simple.mako @@ -115,7 +115,7 @@ else: den = 1 download_stat_tip = "Unaired" - progressbar_percent = nom * 100 / den + progressbar_percent = nom * 100 // den %> % if cur_airs_next: diff --git a/themes-default/slim/views/partials/home/small.mako b/themes-default/slim/views/partials/home/small.mako index aa45fef442..18b73b25a7 100644 --- a/themes-default/slim/views/partials/home/small.mako +++ b/themes-default/slim/views/partials/home/small.mako @@ -114,7 +114,7 @@ else: den = 1 download_stat_tip = "Unaired" - progressbar_percent = nom * 100 / den + progressbar_percent = nom * 100 // den %> % if cur_airs_next: diff --git a/themes-default/slim/views/partials/schedule/banner.mako b/themes-default/slim/views/partials/schedule/banner.mako index 8bdbf99890..9fe2bdbef1 100644 --- a/themes-default/slim/views/partials/schedule/banner.mako +++ b/themes-default/slim/views/partials/schedule/banner.mako @@ -4,7 +4,7 @@ from medusa import app from medusa.indexers.indexer_api import indexerApi from medusa.indexers.utils import indexer_id_to_name - from medusa import sbdatetime + from medusa.sbdatetime import sbdatetime %> <% @@ -59,17 +59,17 @@ <% too_late_header = True %> % elif cur_ep_enddate >= today and cur_ep_airdate < next_week.date(): % if cur_ep_airdate == today.date(): -

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()}[Today]

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()}[Today]

<% today_header = True %> % else: -

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()}

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()}

% endif % endif <% cur_segment = cur_ep_airdate %> % endif % if cur_ep_airdate == today.date() and not today_header:
-

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()} [Today]

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()} [Today]

<% today_header = True %> % endif @@ -128,7 +128,7 @@
Next Episode: ${'S%02iE%02i' % (int(cur_result['season']), int(cur_result['episode']))} - ${cur_result['name']}
- Airs: ${sbdatetime.sbdatetime.sbfdatetime(cur_result['localtime'])}${('', ' on %s' % cur_result['network'])[bool(cur_result['network'])]} + Airs: ${sbdatetime.sbfdatetime(cur_result['localtime'])}${('', ' on %s' % cur_result['network'])[bool(cur_result['network'])]}
Quality: diff --git a/themes-default/slim/views/partials/schedule/calendar.mako b/themes-default/slim/views/partials/schedule/calendar.mako index 2d2055724f..7c788767ba 100644 --- a/themes-default/slim/views/partials/schedule/calendar.mako +++ b/themes-default/slim/views/partials/schedule/calendar.mako @@ -5,7 +5,7 @@ from medusa import app from medusa.indexers.utils import indexer_id_to_name - from medusa import sbdatetime + from medusa.sbdatetime import sbdatetime %> <% dates = [today.date() + datetime.timedelta(days = i) for i in range(7)] %> @@ -15,7 +15,7 @@ % for day in dates: <% tbl_day += 1 %> - + <% day_has_show = False %> % for cur_result in results: @@ -28,7 +28,7 @@ % if airday == day: % try: <% day_has_show = True %> - <% airtime = sbdatetime.sbdatetime.fromtimestamp(time.mktime(cur_result['localtime'].timetuple())).sbftime().decode(app.SYS_ENCODING) %> + <% airtime = sbdatetime.fromtimestamp(time.mktime(cur_result['localtime'].timetuple())).sbftime() %> % if app.TRIM_ZERO: <% airtime = re.sub(r'0(\d:\d\d)', r'\1', airtime, 0, re.IGNORECASE | re.MULTILINE) %> % endif diff --git a/themes-default/slim/views/partials/schedule/poster.mako b/themes-default/slim/views/partials/schedule/poster.mako index ab7e98b9e4..557b119c89 100644 --- a/themes-default/slim/views/partials/schedule/poster.mako +++ b/themes-default/slim/views/partials/schedule/poster.mako @@ -4,7 +4,7 @@ from medusa import app from medusa.indexers.indexer_api import indexerApi from medusa.indexers.utils import indexer_id_to_name - from medusa import sbdatetime + from medusa.sbdatetime import sbdatetime %> <% @@ -59,17 +59,17 @@ <% too_late_header = True %> % elif cur_ep_enddate >= today and cur_ep_airdate < next_week.date(): % if cur_ep_airdate == today.date(): -

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()}[Today]

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()}[Today]

<% today_header = True %> % else: -

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()}

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()}

% endif % endif <% cur_segment = cur_ep_airdate %> % endif % if cur_ep_airdate == today.date() and not today_header:
-

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()} [Today]

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()} [Today]

<% today_header = True %> % endif @@ -126,7 +126,7 @@ Next Episode:${'S%02iE%02i' % (int(cur_result['season']), int(cur_result['episode']))} - ${cur_result['name']}
- Airs: ${sbdatetime.sbdatetime.sbfdatetime(cur_result['localtime'])}${('', ' on %s' % cur_result['network'])[bool(cur_result['network'])]} + Airs: ${sbdatetime.sbfdatetime(cur_result['localtime'])}${('', ' on %s' % cur_result['network'])[bool(cur_result['network'])]}
Quality: diff --git a/themes-default/slim/views/partials/showheader.mako b/themes-default/slim/views/partials/showheader.mako deleted file mode 100644 index 43cc528228..0000000000 --- a/themes-default/slim/views/partials/showheader.mako +++ /dev/null @@ -1,274 +0,0 @@ -<%! - import json - import operator - - from medusa import app, helpers, subtitles, network_timezones - from medusa.common import SKIPPED, WANTED, ARCHIVED, IGNORED, FAILED, DOWNLOADED - from medusa.common import Quality, qualityPresets, statusStrings, Overview - from medusa.helper.common import pretty_file_size - from medusa.indexers.indexer_api import indexerApi -%> -
- ## @TODO: Remove data attributes - ## @SEE: https://github.com/pymedusa/Medusa/pull/5087#discussion_r214074436 -
-
- ## @TODO: Remove data attributes - ## @SEE: https://github.com/pymedusa/Medusa/pull/5087#discussion_r214077142 -

- {{ show.title }} -

-
- -
- - Manual search for:
- {{ show.title }} / Season {{ season }} -
-
-
- - Display Specials: {{ config.layout.show.specials ? 'Hide' : 'Show' }} - - -
- - - - -
-
-
-
- -% if show_message: -
-
- ${show_message} -
-
-% endif - -
-
-
-
-
- -
-
-
- -
- -
-
- -
- - - - - - - [trakt] - - - - - % if xem_numbering or xem_absolute_numbering: - - [xem] - - % endif - [fanart.tv] -
-
-
    - %if show.genre: -
  • {{ genre }}
  • - % elif show.imdb_info.get('genres'): - % for imdbgenre in show.imdb_info['genres'].replace('Sci-Fi', 'Science-Fiction').split('|'): -
  • ${imdbgenre}
  • - % endfor - % endif -
-
-
- -
- -
-
-
${day.strftime('%A').decode(app.SYS_ENCODING).capitalize()}
${sbdatetime.sbftime(dt=day, t_preset='%A').capitalize()}
- - - - - <% allowed_qualities, preferred_qualities = Quality.split_quality(int(show.quality)) %> - - - - - - - % if showLoc[1]: - - % else: - - % endif - % if all_scene_exceptions: - - % endif - % if show.show_words().required_words: - - % endif - % if show.show_words().ignored_words: - - % endif - % if show.show_words().preferred_words: - - % endif - % if show.show_words().undesired_words: - - % endif - % if bwl and bwl.whitelist: - - - - - % endif - % if bwl and bwl.blacklist: - - - - - % endif - -
- -
Quality: - % if show.quality in qualityPresets: - - % else: - % if allowed_qualities: - <% allowed_as_json = json.dumps(sorted(allowed_qualities)) %> - Allowed: - - ${'
' if preferred_qualities else ''} - % endif - % if preferred_qualities: - <% preferred_as_json = json.dumps(sorted(preferred_qualities)) %> - Preferred: - - % endif - % endif -
Originally Airs: {{ show.airs }} ${"" if network_timezones.test_timeformat(show.airs) else "(invalid Timeformat)"} on {{ show.network }}
Originally Airs: {{ show.network }}
Originally Airs: {{ show.airs }} ${"" if network_timezones.test_timeformat(show.airs) else "(invalid Timeformat)"}
Show Status: {{ show.status }}
Default EP Status: {{ show.config.defaultEpisodeStatus }}
Location: ${showLoc[0]}
Location: ${showLoc[0]} (Missing)
Scene Name:${all_scene_exceptions}
Required Words: ${', '.join(show.show_words().required_words)}
Ignored Words: ${', '.join(show.show_words().ignored_words)}
Preferred Words: ${', '.join(show.show_words().preferred_words)}
Undesired Words: ${', '.join(show.show_words().undesired_words)}
Wanted Group${"s" if len(bwl.whitelist) > 1 else ""}:${', '.join(bwl.whitelist)}
Unwanted Group${"s" if len(bwl.blacklist) > 1 else ""}:${', '.join(bwl.blacklist)}
Size:${pretty_file_size(helpers.get_size(showLoc[0]))}
-
- - -
- - <% info_flag = subtitles.code_from_code(show.lang) if show.lang else '' %> - - - - - - - - - -
Info Language:${show.lang}
Subtitles:
Season Folders:
Paused:
Air-by-Date:
Sports:
Anime:
DVD Order:
Scene Numbering:
-
-
-
-
-
- - -
-
-
-
-
- <% total_snatched = ep_counts[Overview.SNATCHED] + ep_counts[Overview.SNATCHED_PROPER] + ep_counts[Overview.SNATCHED_BEST] %> - - - - - - - -
-
- - - - - - -
-
-
-
-
-
diff --git a/themes-default/slim/views/snatchSelection.mako b/themes-default/slim/views/snatchSelection.mako index f6283c0c86..90b46c5697 100644 --- a/themes-default/slim/views/snatchSelection.mako +++ b/themes-default/slim/views/snatchSelection.mako @@ -2,6 +2,7 @@ <%! from datetime import datetime from medusa import app + from medusa.sbdatetime import sbdatetime %> <%block name="scripts"> @@ -11,7 +12,11 @@
- <%include file="/partials/showheader.mako"/> +
@@ -137,12 +142,11 @@ - <% user_preset = app.DATE_PRESET + ' ' + app.TIME_PRESET %> - ${hItem['pubdate'].strftime(user_preset).decode(app.SYS_ENCODING) if hItem['pubdate'] else 'N/A'} + ${sbdatetime.sbfdatetime(dt=hItem['pubdate'], d_preset=app.DATE_PRESET, t_preset=app.TIME_PRESET) if hItem['pubdate'] else 'N/A'} - ${hItem['date_added'].strftime(user_preset).decode(app.SYS_ENCODING) if hItem['date_added'] else 'N/A'} + ${sbdatetime.sbfdatetime(dt=hItem['date_added'], d_preset=app.DATE_PRESET, t_preset=app.TIME_PRESET) if hItem['date_added'] else 'N/A'} search diff --git a/themes-default/slim/views/status.mako b/themes-default/slim/views/status.mako index 59cf56017e..0f92672d63 100644 --- a/themes-default/slim/views/status.mako +++ b/themes-default/slim/views/status.mako @@ -5,6 +5,7 @@ from medusa.show_queue import ShowQueueActions from medusa.helper.common import dateTimeFormat from random import choice + from six import iteritems %> <%block name="scripts"> \n\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./anidb-release-group-ui.vue?vue&type=template&id=10f4092b&scoped=true&\"\nimport script from \"./anidb-release-group-ui.vue?vue&type=script&lang=js&\"\nexport * from \"./anidb-release-group-ui.vue?vue&type=script&lang=js&\"\nimport style0 from \"./anidb-release-group-ui.vue?vue&type=style&index=0&id=10f4092b&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"10f4092b\",\n null\n \n)\n\ncomponent.options.__file = \"anidb-release-group-ui.vue\"\nexport default component.exports","\n\n\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-show-options.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-show-options.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./add-show-options.vue?vue&type=template&id=699d27b6&\"\nimport script from \"./add-show-options.vue?vue&type=script&lang=js&\"\nexport * from \"./add-show-options.vue?vue&type=script&lang=js&\"\nimport style0 from \"./add-show-options.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"add-show-options.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"nav\",\n {\n staticClass: \"navbar navbar-default navbar-fixed-top hidden-print\",\n attrs: { role: \"navigation\" }\n },\n [\n _c(\"div\", { staticClass: \"container-fluid\" }, [\n _c(\n \"div\",\n { staticClass: \"navbar-header\" },\n [\n _c(\n \"button\",\n {\n staticClass: \"navbar-toggle collapsed\",\n attrs: {\n type: \"button\",\n \"data-toggle\": \"collapse\",\n \"data-target\": \"#main_nav\"\n }\n },\n [\n _vm.toolsBadgeCount > 0\n ? _c(\n \"span\",\n { class: \"floating-badge\" + _vm.toolsBadgeClass },\n [_vm._v(_vm._s(_vm.toolsBadgeCount))]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"span\", { staticClass: \"sr-only\" }, [\n _vm._v(\"Toggle navigation\")\n ]),\n _vm._v(\" \"),\n _c(\"span\", { staticClass: \"icon-bar\" }),\n _vm._v(\" \"),\n _c(\"span\", { staticClass: \"icon-bar\" }),\n _vm._v(\" \"),\n _c(\"span\", { staticClass: \"icon-bar\" })\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"app-link\",\n {\n staticClass: \"navbar-brand\",\n attrs: { href: \"home/\", title: \"Medusa\" }\n },\n [\n _c(\"img\", {\n staticClass: \"img-responsive pull-left\",\n staticStyle: { height: \"50px\" },\n attrs: { alt: \"Medusa\", src: \"images/medusa.png\" }\n })\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _vm.isAuthenticated\n ? _c(\n \"div\",\n {\n staticClass: \"collapse navbar-collapse\",\n attrs: { id: \"main_nav\" }\n },\n [\n _c(\"ul\", { staticClass: \"nav navbar-nav navbar-right\" }, [\n _c(\n \"li\",\n {\n staticClass: \"navbar-split dropdown\",\n class: { active: _vm.topMenu === \"home\" },\n attrs: { id: \"NAVhome\" }\n },\n [\n _c(\n \"app-link\",\n {\n staticClass: \"dropdown-toggle\",\n attrs: {\n href: \"home/\",\n \"aria-haspopup\": \"true\",\n \"data-toggle\": \"dropdown\",\n \"data-hover\": \"dropdown\"\n }\n },\n [\n _c(\"span\", [_vm._v(\"Shows\")]),\n _vm._v(\" \"),\n _c(\"b\", { staticClass: \"caret\" })\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"ul\",\n { staticClass: \"dropdown-menu\" },\n [\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"home/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-home\" }),\n _vm._v(\" Show List\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"addShows/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-addshow\" }),\n _vm._v(\" Add Shows\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"addRecommended/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-addshow\" }),\n _vm._v(\" Add Recommended Shows\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"home/postprocess/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-postprocess\"\n }),\n _vm._v(\" Manual Post-Processing\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _vm.recentShows.length > 0\n ? [\n _c(\"li\", {\n staticClass: \"divider\",\n attrs: { role: \"separator\" }\n }),\n _vm._v(\" \"),\n _vm._l(_vm.recentShows, function(recentShow) {\n return _c(\n \"li\",\n { key: recentShow.link },\n [\n _c(\n \"app-link\",\n { attrs: { href: recentShow.link } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-addshow\"\n }),\n _vm._v(\n \" \" +\n _vm._s(recentShow.name) +\n \"\\n \"\n )\n ]\n )\n ],\n 1\n )\n })\n ]\n : _vm._e()\n ],\n 2\n ),\n _vm._v(\" \"),\n _c(\"div\", { staticStyle: { clear: \"both\" } })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n {\n class: { active: _vm.topMenu === \"schedule\" },\n attrs: { id: \"NAVschedule\" }\n },\n [\n _c(\"app-link\", { attrs: { href: \"schedule/\" } }, [\n _vm._v(\"Schedule\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n {\n class: { active: _vm.topMenu === \"history\" },\n attrs: { id: \"NAVhistory\" }\n },\n [\n _c(\"app-link\", { attrs: { href: \"history/\" } }, [\n _vm._v(\"History\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n {\n staticClass: \"navbar-split dropdown\",\n class: { active: _vm.topMenu === \"manage\" },\n attrs: { id: \"NAVmanage\" }\n },\n [\n _c(\n \"app-link\",\n {\n staticClass: \"dropdown-toggle\",\n attrs: {\n href: \"manage/episodeStatuses/\",\n \"aria-haspopup\": \"true\",\n \"data-toggle\": \"dropdown\",\n \"data-hover\": \"dropdown\"\n }\n },\n [\n _c(\"span\", [_vm._v(\"Manage\")]),\n _vm._v(\" \"),\n _c(\"b\", { staticClass: \"caret\" })\n ]\n ),\n _vm._v(\" \"),\n _c(\"ul\", { staticClass: \"dropdown-menu\" }, [\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"manage/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-manage\" }),\n _vm._v(\" Mass Update\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"manage/backlogOverview/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-backlog-view\"\n }),\n _vm._v(\" Backlog Overview\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"manage/manageSearches/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-manage-searches\"\n }),\n _vm._v(\" Manage Searches\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"manage/episodeStatuses/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-manage2\" }),\n _vm._v(\" Episode Status Management\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _vm.linkVisible.plex\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"home/updatePLEX/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-plex\" }),\n _vm._v(\" Update PLEX\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.linkVisible.kodi\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"home/updateKODI/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-kodi\" }),\n _vm._v(\" Update KODI\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.linkVisible.emby\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"home/updateEMBY/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-emby\" }),\n _vm._v(\" Update Emby\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.linkVisible.manageTorrents\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href: \"manage/manageTorrents/\",\n target: \"_blank\"\n }\n },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-bittorrent\"\n }),\n _vm._v(\" Manage Torrents\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.linkVisible.failedDownloads\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: { href: \"manage/failedDownloads/\" }\n },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-failed-download\"\n }),\n _vm._v(\" Failed Downloads\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.linkVisible.subtitleMissed\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"manage/subtitleMissed/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-backlog\"\n }),\n _vm._v(\" Missed Subtitle Management\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.linkVisible.subtitleMissedPP\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: { href: \"manage/subtitleMissedPP/\" }\n },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-backlog\"\n }),\n _vm._v(\n \" Missed Subtitle in Post-Process folder\"\n )\n ]\n )\n ],\n 1\n )\n : _vm._e()\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticStyle: { clear: \"both\" } })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n {\n staticClass: \"navbar-split dropdown\",\n class: { active: _vm.topMenu === \"config\" },\n attrs: { id: \"NAVconfig\" }\n },\n [\n _c(\n \"app-link\",\n {\n staticClass: \"dropdown-toggle\",\n attrs: {\n href: \"config/\",\n \"aria-haspopup\": \"true\",\n \"data-toggle\": \"dropdown\",\n \"data-hover\": \"dropdown\"\n }\n },\n [\n _c(\"span\", { staticClass: \"visible-xs-inline\" }, [\n _vm._v(\"Config\")\n ]),\n _c(\"img\", {\n staticClass: \"navbaricon hidden-xs\",\n attrs: { src: \"images/menu/system18.png\" }\n }),\n _vm._v(\" \"),\n _c(\"b\", { staticClass: \"caret\" })\n ]\n ),\n _vm._v(\" \"),\n _c(\"ul\", { staticClass: \"dropdown-menu\" }, [\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"config/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-help\" }),\n _vm._v(\" Help & Info\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/general/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-config\" }),\n _vm._v(\" General\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/backuprestore/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-backup\" }),\n _vm._v(\" Backup & Restore\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/search/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-manage-searches\"\n }),\n _vm._v(\" Search Settings\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/providers/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-provider\" }),\n _vm._v(\" Search Providers\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/subtitles/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-backlog\" }),\n _vm._v(\" Subtitles Settings\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/postProcessing/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-postprocess\"\n }),\n _vm._v(\" Post Processing\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/notifications/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-notification\"\n }),\n _vm._v(\" Notifications\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/anime/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-anime\" }),\n _vm._v(\" Anime\")\n ]\n )\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticStyle: { clear: \"both\" } })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n {\n staticClass: \"navbar-split dropdown\",\n class: { active: _vm.topMenu === \"system\" },\n attrs: { id: \"NAVsystem\" }\n },\n [\n _c(\n \"app-link\",\n {\n staticClass: \"padding-right-15 dropdown-toggle\",\n attrs: {\n href: \"home/status/\",\n \"aria-haspopup\": \"true\",\n \"data-toggle\": \"dropdown\",\n \"data-hover\": \"dropdown\"\n }\n },\n [\n _c(\"span\", { staticClass: \"visible-xs-inline\" }, [\n _vm._v(\"Tools\")\n ]),\n _c(\"img\", {\n staticClass: \"navbaricon hidden-xs\",\n attrs: { src: \"images/menu/system18-2.png\" }\n }),\n _vm._v(\" \"),\n _vm.toolsBadgeCount > 0\n ? _c(\n \"span\",\n { class: \"badge\" + _vm.toolsBadgeClass },\n [_vm._v(_vm._s(_vm.toolsBadgeCount))]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"b\", { staticClass: \"caret\" })\n ]\n ),\n _vm._v(\" \"),\n _c(\"ul\", { staticClass: \"dropdown-menu\" }, [\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"news/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-news\" }),\n _vm._v(\" News \"),\n _vm.config.news.unread > 0\n ? _c(\"span\", { staticClass: \"badge\" }, [\n _vm._v(_vm._s(_vm.config.news.unread))\n ])\n : _vm._e()\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"IRC/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-irc\" }),\n _vm._v(\" IRC\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"changes/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-changelog\" }),\n _vm._v(\" Changelog\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: _vm.config.donationsUrl } },\n [\n _c(\"i\", { staticClass: \"menu-icon-support\" }),\n _vm._v(\" Support Medusa\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\"li\", {\n staticClass: \"divider\",\n attrs: { role: \"separator\" }\n }),\n _vm._v(\" \"),\n _vm.config.logs.numErrors > 0\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"errorlogs/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-error\" }),\n _vm._v(\" View Errors \"),\n _c(\n \"span\",\n { staticClass: \"badge btn-danger\" },\n [\n _vm._v(\n _vm._s(_vm.config.logs.numErrors)\n )\n ]\n )\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.config.logs.numWarnings > 0\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href:\n \"errorlogs/?level=\" + _vm.warningLevel\n }\n },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-viewlog-errors\"\n }),\n _vm._v(\" View Warnings \"),\n _c(\n \"span\",\n { staticClass: \"badge btn-warning\" },\n [\n _vm._v(\n _vm._s(_vm.config.logs.numWarnings)\n )\n ]\n )\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"errorlogs/viewlog/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-viewlog\" }),\n _vm._v(\" View Log\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\"li\", {\n staticClass: \"divider\",\n attrs: { role: \"separator\" }\n }),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href: \"home/updateCheck?pid=\" + _vm.config.pid\n }\n },\n [\n _c(\"i\", { staticClass: \"menu-icon-update\" }),\n _vm._v(\" Check For Updates\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href: \"home/restart/?pid=\" + _vm.config.pid\n },\n nativeOn: {\n click: function($event) {\n $event.preventDefault()\n _vm.confirmDialog($event, \"restart\")\n }\n }\n },\n [\n _c(\"i\", { staticClass: \"menu-icon-restart\" }),\n _vm._v(\" Restart\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href: \"home/shutdown/?pid=\" + _vm.config.pid\n },\n nativeOn: {\n click: function($event) {\n $event.preventDefault()\n _vm.confirmDialog($event, \"shutdown\")\n }\n }\n },\n [\n _c(\"i\", { staticClass: \"menu-icon-shutdown\" }),\n _vm._v(\" Shutdown\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _vm.username\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: { href: \"logout\" },\n nativeOn: {\n click: function($event) {\n $event.preventDefault()\n _vm.confirmDialog($event, \"logout\")\n }\n }\n },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-shutdown\"\n }),\n _vm._v(\" Logout\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"li\", {\n staticClass: \"divider\",\n attrs: { role: \"separator\" }\n }),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"home/status/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-info\" }),\n _vm._v(\" Server Status\")\n ]\n )\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticStyle: { clear: \"both\" } })\n ],\n 1\n )\n ])\n ]\n )\n : _vm._e()\n ])\n ]\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./app-header.vue?vue&type=template&id=33b81de2&\"\nimport script from \"./app-header.vue?vue&type=script&lang=js&\"\nexport * from \"./app-header.vue?vue&type=script&lang=js&\"\nimport style0 from \"./app-header.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"app-header.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\")\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./backstretch.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./backstretch.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./backstretch.vue?vue&type=template&id=630a2e1f&\"\nimport script from \"./backstretch.vue?vue&type=script&lang=js&\"\nexport * from \"./backstretch.vue?vue&type=script&lang=js&\"\nimport style0 from \"./backstretch.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"backstretch.vue\"\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./home.vue?vue&type=script&lang=js&\"\nexport * from \"./home.vue?vue&type=script&lang=js&\"\nimport style0 from \"./home.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"home.vue\"\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manual-post-process.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manual-post-process.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./manual-post-process.vue?vue&type=script&lang=js&\"\nexport * from \"./manual-post-process.vue?vue&type=script&lang=js&\"\nimport style0 from \"./manual-post-process.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"manual-post-process.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"root-dirs-wrapper\" } }, [\n _c(\"div\", { staticClass: \"root-dirs-selectbox\" }, [\n _c(\n \"select\",\n _vm._g(\n _vm._b(\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.selectedRootDir,\n expression: \"selectedRootDir\"\n }\n ],\n ref: \"rootDirs\",\n attrs: { name: \"rootDir\", id: \"rootDirs\", size: \"6\" },\n on: {\n change: function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val = \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.selectedRootDir = $event.target.multiple\n ? $$selectedVal\n : $$selectedVal[0]\n }\n }\n },\n \"select\",\n _vm.$attrs,\n false\n ),\n _vm.$listeners\n ),\n _vm._l(_vm.rootDirs, function(curDir) {\n return _c(\n \"option\",\n { key: curDir.path, domProps: { value: curDir.path } },\n [\n _vm._v(\n \"\\n \" +\n _vm._s(_vm._f(\"markDefault\")(curDir)) +\n \"\\n \"\n )\n ]\n )\n })\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"root-dirs-controls\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa\",\n attrs: { type: \"button\" },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.add($event)\n }\n }\n },\n [_vm._v(\"New\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa\",\n attrs: { type: \"button\", disabled: !_vm.selectedRootDir },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.edit($event)\n }\n }\n },\n [_vm._v(\"Edit\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa\",\n attrs: { type: \"button\", disabled: !_vm.selectedRootDir },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.remove($event)\n }\n }\n },\n [_vm._v(\"Delete\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa\",\n attrs: { type: \"button\", disabled: !_vm.selectedRootDir },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.setDefault($event)\n }\n }\n },\n [_vm._v(\"Set as Default *\")]\n )\n ])\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./root-dirs.vue?vue&type=template&id=76f972d6&\"\nimport script from \"./root-dirs.vue?vue&type=script&lang=js&\"\nexport * from \"./root-dirs.vue?vue&type=script&lang=js&\"\nimport style0 from \"./root-dirs.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"root-dirs.vue\"\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./show.vue?vue&type=script&lang=js&\"\nexport * from \"./show.vue?vue&type=script&lang=js&\"\nimport style0 from \"./show.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"show.vue\"\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./snatch-selection.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./snatch-selection.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./snatch-selection.vue?vue&type=script&lang=js&\"\nexport * from \"./snatch-selection.vue?vue&type=script&lang=js&\"\nimport style0 from \"./snatch-selection.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"snatch-selection.vue\"\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./status.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./status.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./status.vue?vue&type=script&lang=js&\"\nexport * from \"./status.vue?vue&type=script&lang=js&\"\nimport style0 from \"./status.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"status.vue\"\nexport default component.exports","export { default as AddRecommended } from './add-recommended.vue';\nexport { default as AddShowOptions } from './add-show-options.vue';\nexport { default as AddShows } from './add-shows.vue';\nexport { default as AnidbReleaseGroupUi } from './anidb-release-group-ui.vue';\nexport { default as AppHeader } from './app-header.vue';\nexport { default as Backstretch } from './backstretch.vue';\nexport { default as Config } from './config.vue';\nexport { default as ConfigPostProcessing } from './config-post-processing.vue';\nexport { default as Home } from './home.vue';\nexport { default as IRC } from './irc.vue';\nexport { default as Login } from './login.vue';\nexport { default as ManualPostProcess } from './manual-post-process.vue';\nexport { default as RootDirs } from './root-dirs.vue';\nexport { default as Show } from './show.vue';\nexport { default as SnatchSelection } from './snatch-selection.vue';\nexport { default as Status } from './status.vue';\nexport * from './http';\nexport * from './helpers';\n","import axios from 'axios';\n\nconst webRoot = document.body.getAttribute('web-root');\nconst apiKey = document.body.getAttribute('api-key');\n\n/**\n * Api client based on the axios client, to communicate with medusa's web routes, which return json data.\n */\nconst apiRoute = axios.create({ // eslint-disable-line no-unused-vars\n baseURL: webRoot + '/',\n timeout: 30000,\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json'\n }\n});\n\n/**\n * Api client based on the axios client, to communicate with medusa's api v1.\n */\nconst apiv1 = axios.create({ // eslint-disable-line no-unused-vars\n baseURL: webRoot + '/api/v1/' + apiKey + '/',\n timeout: 30000,\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json'\n }\n});\n\n/**\n * Api client based on the axios client, to communicate with medusa's api v2.\n */\nconst api = axios.create({ // eslint-disable-line no-unused-vars\n baseURL: webRoot + '/api/v2/',\n timeout: 30000,\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n 'X-Api-Key': apiKey\n }\n});\n\nexport {\n webRoot,\n apiKey,\n apiRoute,\n apiv1,\n api\n};\n","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n _vm.linkProperties.is,\n {\n tag: \"component\",\n class: { \"router-link\": _vm.linkProperties.is === \"router-link\" },\n attrs: {\n to: _vm.linkProperties.to,\n href: _vm.linkProperties.href,\n target: _vm.linkProperties.target,\n rel: _vm.linkProperties.rel,\n \"false-link\": _vm.linkProperties.falseLink\n }\n },\n [_vm._t(\"default\")],\n 2\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./app-link.vue?vue&type=template&id=3da1d90a&\"\nimport script from \"./app-link.vue?vue&type=script&lang=js&\"\nexport * from \"./app-link.vue?vue&type=script&lang=js&\"\nimport style0 from \"./app-link.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"app-link.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return !_vm.link\n ? _c(\"img\", {\n class: _vm.cls,\n attrs: { src: _vm.src },\n on: {\n error: function($event) {\n _vm.error = true\n }\n }\n })\n : _c(\"app-link\", { attrs: { href: _vm.href } }, [\n _c(\"img\", {\n class: _vm.cls,\n attrs: { src: _vm.src },\n on: {\n error: function($event) {\n _vm.error = true\n }\n }\n })\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./asset.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./asset.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./asset.vue?vue&type=template&id=4d502334&\"\nimport script from \"./asset.vue?vue&type=script&lang=js&\"\nexport * from \"./asset.vue?vue&type=script&lang=js&\"\nimport style0 from \"./asset.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"asset.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"config-template-content\" } }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: _vm.labelFor }\n },\n [_c(\"span\", [_vm._v(_vm._s(_vm.label))])]\n ),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [_vm._t(\"default\")], 2)\n ])\n ])\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-template.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-template.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./config-template.vue?vue&type=template&id=0da1fcab&\"\nimport script from \"./config-template.vue?vue&type=script&lang=js&\"\nexport * from \"./config-template.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-template.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"config-template.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"config-textbox-number-content\" } }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: _vm.id } },\n [_c(\"span\", [_vm._v(_vm._s(_vm.label))])]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\n \"input\",\n _vm._b(\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.localValue,\n expression: \"localValue\"\n }\n ],\n attrs: { type: \"number\" },\n domProps: { value: _vm.localValue },\n on: {\n input: [\n function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.localValue = $event.target.value\n },\n function($event) {\n _vm.updateValue()\n }\n ]\n }\n },\n \"input\",\n {\n min: _vm.min,\n max: _vm.max,\n step: _vm.step,\n id: _vm.id,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n },\n false\n )\n ),\n _vm._v(\" \"),\n _vm._l(_vm.explanations, function(explanation, index) {\n return _c(\"p\", { key: index }, [_vm._v(_vm._s(explanation))])\n }),\n _vm._v(\" \"),\n _vm._t(\"default\")\n ],\n 2\n )\n ])\n ])\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./config-textbox-number.vue?vue&type=template&id=159c522c&\"\nimport script from \"./config-textbox-number.vue?vue&type=script&lang=js&\"\nexport * from \"./config-textbox-number.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-textbox-number.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"config-textbox-number.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"config-textbox\" } }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: _vm.id } },\n [_c(\"span\", [_vm._v(_vm._s(_vm.label))])]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n {\n id: _vm.id,\n type: _vm.type,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n }.type === \"checkbox\"\n ? _c(\n \"input\",\n _vm._b(\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.localValue,\n expression: \"localValue\"\n }\n ],\n attrs: { type: \"checkbox\" },\n domProps: {\n checked: Array.isArray(_vm.localValue)\n ? _vm._i(_vm.localValue, null) > -1\n : _vm.localValue\n },\n on: {\n input: function($event) {\n _vm.updateValue()\n },\n change: function($event) {\n var $$a = _vm.localValue,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 && (_vm.localValue = $$a.concat([$$v]))\n } else {\n $$i > -1 &&\n (_vm.localValue = $$a\n .slice(0, $$i)\n .concat($$a.slice($$i + 1)))\n }\n } else {\n _vm.localValue = $$c\n }\n }\n }\n },\n \"input\",\n {\n id: _vm.id,\n type: _vm.type,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n },\n false\n )\n )\n : {\n id: _vm.id,\n type: _vm.type,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n }.type === \"radio\"\n ? _c(\n \"input\",\n _vm._b(\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.localValue,\n expression: \"localValue\"\n }\n ],\n attrs: { type: \"radio\" },\n domProps: { checked: _vm._q(_vm.localValue, null) },\n on: {\n input: function($event) {\n _vm.updateValue()\n },\n change: function($event) {\n _vm.localValue = null\n }\n }\n },\n \"input\",\n {\n id: _vm.id,\n type: _vm.type,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n },\n false\n )\n )\n : _c(\n \"input\",\n _vm._b(\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.localValue,\n expression: \"localValue\"\n }\n ],\n attrs: {\n type: {\n id: _vm.id,\n type: _vm.type,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n }.type\n },\n domProps: { value: _vm.localValue },\n on: {\n input: [\n function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.localValue = $event.target.value\n },\n function($event) {\n _vm.updateValue()\n }\n ]\n }\n },\n \"input\",\n {\n id: _vm.id,\n type: _vm.type,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n },\n false\n )\n ),\n _vm._v(\" \"),\n _vm._l(_vm.explanations, function(explanation, index) {\n return _c(\"p\", { key: index }, [_vm._v(_vm._s(explanation))])\n }),\n _vm._v(\" \"),\n _vm._t(\"default\")\n ],\n 2\n )\n ])\n ])\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./config-textbox.vue?vue&type=template&id=788aa398&\"\nimport script from \"./config-textbox.vue?vue&type=script&lang=js&\"\nexport * from \"./config-textbox.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-textbox.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"config-textbox.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"config-toggle-slider-content\" } }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: _vm.id } },\n [_c(\"span\", [_vm._v(_vm._s(_vm.label))])]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\n \"toggle-button\",\n _vm._b(\n {\n attrs: { width: 45, height: 22, sync: \"\" },\n on: {\n input: function($event) {\n _vm.updateValue()\n }\n },\n model: {\n value: _vm.localChecked,\n callback: function($$v) {\n _vm.localChecked = $$v\n },\n expression: \"localChecked\"\n }\n },\n \"toggle-button\",\n { id: _vm.id, name: _vm.id, disabled: _vm.disabled },\n false\n )\n ),\n _vm._v(\" \"),\n _vm._l(_vm.explanations, function(explanation, index) {\n return _c(\"p\", { key: index }, [_vm._v(_vm._s(explanation))])\n }),\n _vm._v(\" \"),\n _vm._t(\"default\")\n ],\n 2\n )\n ])\n ])\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./config-toggle-slider.vue?vue&type=template&id=61641df4&\"\nimport script from \"./config-toggle-slider.vue?vue&type=script&lang=js&\"\nexport * from \"./config-toggle-slider.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-toggle-slider.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"config-toggle-slider.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { staticClass: \"file-browser max-width\" }, [\n _c(\n \"div\",\n { class: _vm.showBrowseButton ? \"input-group\" : \"input-group-no-btn\" },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.currentPath,\n expression: \"currentPath\"\n }\n ],\n ref: \"locationInput\",\n staticClass: \"form-control input-sm fileBrowserField\",\n attrs: { name: _vm.name, type: \"text\" },\n domProps: { value: _vm.currentPath },\n on: {\n input: function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.currentPath = $event.target.value\n }\n }\n }),\n _vm._v(\" \"),\n _vm.showBrowseButton\n ? _c(\n \"div\",\n {\n staticClass: \"input-group-btn\",\n attrs: { title: _vm.title, alt: _vm.title },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.openDialog($event)\n }\n }\n },\n [_vm._m(0)]\n )\n : _vm._e()\n ]\n ),\n _vm._v(\" \"),\n _c(\"div\", {\n ref: \"fileBrowserDialog\",\n staticClass: \"fileBrowserDialog\",\n staticStyle: { display: \"none\" }\n }),\n _vm._v(\" \"),\n _c(\"input\", {\n ref: \"fileBrowserSearchBox\",\n staticClass: \"form-control\",\n staticStyle: { display: \"none\" },\n attrs: { type: \"text\" },\n domProps: { value: _vm.currentPath },\n on: {\n keyup: function($event) {\n if (\n !(\"button\" in $event) &&\n _vm._k($event.keyCode, \"enter\", 13, $event.key, \"Enter\")\n ) {\n return null\n }\n _vm.browse($event.target.value)\n }\n }\n }),\n _vm._v(\" \"),\n _c(\n \"ul\",\n { ref: \"fileBrowserFileList\", staticStyle: { display: \"none\" } },\n _vm._l(_vm.files, function(file) {\n return _c(\n \"li\",\n { key: file.name, staticClass: \"ui-state-default ui-corner-all\" },\n [\n _c(\n \"a\",\n {\n on: {\n mouseover: function($event) {\n _vm.toggleFolder(file, $event)\n },\n mouseout: function($event) {\n _vm.toggleFolder(file, $event)\n },\n click: function($event) {\n _vm.fileClicked(file)\n }\n }\n },\n [\n _c(\"span\", {\n class:\n \"ui-icon \" +\n (file.isFile ? \"ui-icon-blank\" : \"ui-icon-folder-collapsed\")\n }),\n _vm._v(\" \" + _vm._s(file.name) + \"\\n \")\n ]\n )\n ]\n )\n })\n )\n ])\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n {\n staticClass: \"btn btn-default input-sm\",\n staticStyle: { \"font-size\": \"14px\" }\n },\n [_c(\"i\", { staticClass: \"glyphicon glyphicon-open\" })]\n )\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./file-browser.vue?vue&type=template&id=5a327762&scoped=true&\"\nimport script from \"./file-browser.vue?vue&type=script&lang=js&\"\nexport * from \"./file-browser.vue?vue&type=script&lang=js&\"\nimport style0 from \"./file-browser.vue?vue&type=style&index=0&id=5a327762&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"5a327762\",\n null\n \n)\n\ncomponent.options.__file = \"file-browser.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"select\")\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./language-select.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./language-select.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./language-select.vue?vue&type=template&id=f30eee9c&\"\nimport script from \"./language-select.vue?vue&type=script&lang=js&\"\nexport * from \"./language-select.vue?vue&type=script&lang=js&\"\nimport style0 from \"./language-select.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"language-select.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"name-pattern-wrapper\" } }, [\n _vm.type\n ? _c(\"div\", { staticClass: \"form-group\" }, [\n _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"enable_naming_custom\" }\n },\n [_c(\"span\", [_vm._v(\"Custom \" + _vm._s(_vm.type))])]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"enable_naming_custom\",\n name: \"enable_naming_custom\",\n sync: \"\"\n },\n on: {\n input: function($event) {\n _vm.update()\n }\n },\n model: {\n value: _vm.isEnabled,\n callback: function($$v) {\n _vm.isEnabled = $$v\n },\n expression: \"isEnabled\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Name \" +\n _vm._s(_vm.type) +\n \" shows differently than regular shows?\"\n )\n ])\n ],\n 1\n )\n ])\n : _vm._e(),\n _vm._v(\" \"),\n !_vm.type || _vm.isEnabled\n ? _c(\"div\", { staticClass: \"episode-naming\" }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(0),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\n \"select\",\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.selectedNamingPattern,\n expression: \"selectedNamingPattern\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: { id: \"name_presets\" },\n on: {\n change: [\n function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val = \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.selectedNamingPattern = $event.target.multiple\n ? $$selectedVal\n : $$selectedVal[0]\n },\n _vm.updatePatternSamples\n ],\n input: function($event) {\n _vm.update()\n }\n }\n },\n _vm._l(_vm.presets, function(preset) {\n return _c(\n \"option\",\n { key: preset.pattern, attrs: { id: preset.pattern } },\n [_vm._v(_vm._s(preset.example))]\n )\n })\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { attrs: { id: \"naming_custom\" } }, [\n _vm.isCustom\n ? _c(\n \"div\",\n {\n staticClass: \"form-group\",\n staticStyle: { \"padding-top\": \"0\" }\n },\n [\n _vm._m(1),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.customName,\n expression: \"customName\"\n }\n ],\n staticClass:\n \"form-control-inline-max input-sm max-input350\",\n attrs: {\n type: \"text\",\n name: \"naming_pattern\",\n id: \"naming_pattern\"\n },\n domProps: { value: _vm.customName },\n on: {\n change: _vm.updatePatternSamples,\n input: [\n function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.customName = $event.target.value\n },\n function($event) {\n _vm.update()\n }\n ]\n }\n }),\n _vm._v(\" \"),\n _c(\"img\", {\n staticClass: \"legend\",\n attrs: {\n src: \"images/legend16.png\",\n width: \"16\",\n height: \"16\",\n alt: \"[Toggle Key]\",\n id: \"show_naming_key\",\n title: \"Toggle Naming Legend\"\n },\n on: {\n click: function($event) {\n _vm.showLegend = !_vm.showLegend\n }\n }\n })\n ])\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.showLegend && _vm.isCustom\n ? _c(\n \"div\",\n { staticClass: \"nocheck\", attrs: { id: \"naming_key\" } },\n [\n _c(\"table\", { staticClass: \"Key\" }, [\n _vm._m(2),\n _vm._v(\" \"),\n _vm._m(3),\n _vm._v(\" \"),\n _c(\"tbody\", [\n _vm._m(4),\n _vm._v(\" \"),\n _vm._m(5),\n _vm._v(\" \"),\n _vm._m(6),\n _vm._v(\" \"),\n _vm._m(7),\n _vm._v(\" \"),\n _vm._m(8),\n _vm._v(\" \"),\n _vm._m(9),\n _vm._v(\" \"),\n _vm._m(10),\n _vm._v(\" \"),\n _vm._m(11),\n _vm._v(\" \"),\n _vm._m(12),\n _vm._v(\" \"),\n _vm._m(13),\n _vm._v(\" \"),\n _vm._m(14),\n _vm._v(\" \"),\n _vm._m(15),\n _vm._v(\" \"),\n _vm._m(16),\n _vm._v(\" \"),\n _vm._m(17),\n _vm._v(\" \"),\n _vm._m(18),\n _vm._v(\" \"),\n _vm._m(19),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(20),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%M\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(_vm._s(_vm.getDateFormat(\"M\")))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%D\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(_vm._s(_vm.getDateFormat(\"D\")))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%Y\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(_vm._s(_vm.getDateFormat(\"YY\")))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(21),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%CM\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(_vm._s(_vm.getDateFormat(\"M\")))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%CD\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(_vm._s(_vm.getDateFormat(\"D\")))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%CY\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(_vm._s(_vm.getDateFormat(\"YY\")))])\n ]),\n _vm._v(\" \"),\n _vm._m(22),\n _vm._v(\" \"),\n _vm._m(23),\n _vm._v(\" \"),\n _vm._m(24),\n _vm._v(\" \"),\n _vm._m(25),\n _vm._v(\" \"),\n _vm._m(26),\n _vm._v(\" \"),\n _vm._m(27),\n _vm._v(\" \"),\n _vm._m(28),\n _vm._v(\" \"),\n _vm._m(29),\n _vm._v(\" \"),\n _vm._m(30)\n ])\n ])\n ]\n )\n : _vm._e()\n ]),\n _vm._v(\" \"),\n _vm.selectedMultiEpStyle\n ? _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(31),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\n \"select\",\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.selectedMultiEpStyle,\n expression: \"selectedMultiEpStyle\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: { id: \"naming_multi_ep\", name: \"naming_multi_ep\" },\n on: {\n change: [\n function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val = \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.selectedMultiEpStyle = $event.target.multiple\n ? $$selectedVal\n : $$selectedVal[0]\n },\n _vm.updatePatternSamples\n ],\n input: function($event) {\n _vm.update($event)\n }\n }\n },\n _vm._l(_vm.availableMultiEpStyles, function(multiEpStyle) {\n return _c(\n \"option\",\n {\n key: multiEpStyle.value,\n attrs: { id: \"multiEpStyle\" },\n domProps: { value: multiEpStyle.value }\n },\n [_vm._v(_vm._s(multiEpStyle.text))]\n )\n })\n )\n ])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group row\" }, [\n _c(\"h3\", { staticClass: \"col-sm-12\" }, [\n _vm._v(\"Single-EP Sample:\")\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"example col-sm-12\" }, [\n _c(\n \"span\",\n { staticClass: \"jumbo\", attrs: { id: \"naming_example\" } },\n [_vm._v(_vm._s(_vm.namingExample))]\n )\n ])\n ]),\n _vm._v(\" \"),\n _vm.isMulti\n ? _c(\"div\", { staticClass: \"form-group row\" }, [\n _c(\"h3\", { staticClass: \"col-sm-12\" }, [\n _vm._v(\"Multi-EP sample:\")\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"example col-sm-12\" }, [\n _c(\n \"span\",\n {\n staticClass: \"jumbo\",\n attrs: { id: \"naming_example_multi\" }\n },\n [_vm._v(_vm._s(_vm.namingExampleMulti))]\n )\n ])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _vm.animeType > 0\n ? _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(32),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.animeType,\n expression: \"animeType\"\n }\n ],\n attrs: {\n type: \"radio\",\n name: \"naming_anime\",\n id: \"naming_anime\",\n value: \"1\"\n },\n domProps: { checked: _vm._q(_vm.animeType, \"1\") },\n on: {\n change: [\n function($event) {\n _vm.animeType = \"1\"\n },\n _vm.updatePatternSamples\n ],\n input: function($event) {\n _vm.update()\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Add the absolute number to the season/episode format?\"\n )\n ]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"Only applies to animes. (e.g. S15E45 - 310 vs S15E45)\"\n )\n ])\n ])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _vm.animeType > 0\n ? _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(33),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.animeType,\n expression: \"animeType\"\n }\n ],\n attrs: {\n type: \"radio\",\n name: \"naming_anime\",\n id: \"naming_anime_only\",\n value: \"2\"\n },\n domProps: { checked: _vm._q(_vm.animeType, \"2\") },\n on: {\n change: [\n function($event) {\n _vm.animeType = \"2\"\n },\n _vm.updatePatternSamples\n ],\n input: function($event) {\n _vm.update()\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\"Replace season/episode format with absolute number\")\n ]),\n _vm._v(\" \"),\n _c(\"p\", [_vm._v(\"Only applies to animes.\")])\n ])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _vm.animeType > 0\n ? _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(34),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.animeType,\n expression: \"animeType\"\n }\n ],\n attrs: {\n type: \"radio\",\n name: \"naming_anime\",\n id: \"naming_anime_none\",\n value: \"3\"\n },\n domProps: { checked: _vm._q(_vm.animeType, \"3\") },\n on: {\n change: [\n function($event) {\n _vm.animeType = \"3\"\n },\n _vm.updatePatternSamples\n ],\n input: function($event) {\n _vm.update()\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [_vm._v(\"Don't include the absolute number\")]),\n _vm._v(\" \"),\n _c(\"p\", [_vm._v(\"Only applies to animes.\")])\n ])\n ])\n : _vm._e()\n ])\n : _vm._e()\n ])\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"name_presets\" } },\n [_c(\"span\", [_vm._v(\"Name Pattern:\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"label\", { staticClass: \"col-sm-2 control-label\" }, [\n _c(\"span\", [_vm._v(\" \")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"thead\", [\n _c(\"tr\", [\n _c(\"th\", { staticClass: \"align-right\" }, [_vm._v(\"Meaning\")]),\n _vm._v(\" \"),\n _c(\"th\", [_vm._v(\"Pattern\")]),\n _vm._v(\" \"),\n _c(\"th\", { attrs: { width: \"60%\" } }, [_vm._v(\"Result\")])\n ])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tfoot\", [\n _c(\"tr\", [\n _c(\"th\", { attrs: { colspan: \"3\" } }, [\n _vm._v(\n \"Use lower case if you want lower case names (eg. %sn, %e.n, %q_n etc)\"\n )\n ])\n ])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Show Name:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%SN\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Show Name\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%S.N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Show.Name\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%S_N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Show_Name\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Season Number:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%S\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"2\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%0S\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"02\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"XEM Season Number:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%XS\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"2\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%0XS\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"02\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Episode Number:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%E\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"3\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%0E\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"03\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"XEM Episode Number:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%XE\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"3\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%0XE\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"03\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Absolute Episode Number:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%AB\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"003\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Xem Absolute Episode Number:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%XAB\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"003\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Episode Name:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%EN\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Episode Name\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%E.N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Episode.Name\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%E_N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Episode_Name\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Air Date:\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Post-Processing Date:\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", { staticClass: \"align-right\" }, [_c(\"b\", [_vm._v(\"Quality:\")])]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%QN\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"720p BluRay\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%Q.N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"720p.BluRay\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%Q_N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"720p_BluRay\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Scene Quality:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%SQN\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"720p HDTV x264\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%SQ.N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"720p.HDTV.x264\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%SQ_N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"720p_HDTV_x264\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-info-sign\",\n attrs: { title: \"Multi-EP style is ignored\" }\n }),\n _vm._v(\" \"),\n _c(\"b\", [_vm._v(\"Release Name:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%RN\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Show.Name.S02E03.HDTV.x264-RLSGROUP\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-info-sign\",\n attrs: {\n title:\n \"UNKNOWN_RELEASE_GROUP is used in place of RLSGROUP if it could not be properly detected\"\n }\n }),\n _vm._v(\" \"),\n _c(\"b\", [_vm._v(\"Release Group:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%RG\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"RLSGROUP\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-info-sign\",\n attrs: { title: \"If episode is proper/repack add 'proper' to name.\" }\n }),\n _vm._v(\" \"),\n _c(\"b\", [_vm._v(\"Release Type:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%RT\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"PROPER\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"naming_multi_ep\" }\n },\n [_c(\"span\", [_vm._v(\"Multi-Episode Style:\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"naming_anime\" } },\n [_c(\"span\", [_vm._v(\"Add Absolute Number\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"naming_anime_only\" }\n },\n [_c(\"span\", [_vm._v(\"Only Absolute Number\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"naming_anime_none\" }\n },\n [_c(\"span\", [_vm._v(\"No Absolute Number\")])]\n )\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./name-pattern.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./name-pattern.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./name-pattern.vue?vue&type=template&id=462c525e&\"\nimport script from \"./name-pattern.vue?vue&type=script&lang=js&\"\nexport * from \"./name-pattern.vue?vue&type=script&lang=js&\"\nimport style0 from \"./name-pattern.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"name-pattern.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"img\", {\n class: _vm.plotInfoClass,\n attrs: { src: \"images/info32.png\", width: \"16\", height: \"16\", alt: \"\" }\n })\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./plot-info.vue?vue&type=template&id=6b17b4d1&\"\nimport script from \"./plot-info.vue?vue&type=script&lang=js&\"\nexport * from \"./plot-info.vue?vue&type=script&lang=js&\"\nimport style0 from \"./plot-info.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"plot-info.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"span\",\n {\n class: _vm.override.class || [\"quality\", _vm.pill.class],\n attrs: { title: _vm.title }\n },\n [_vm._v(_vm._s(_vm.override.text || _vm.pill.text))]\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./quality-pill.vue?vue&type=template&id=b683ee7a&scoped=true&\"\nimport script from \"./quality-pill.vue?vue&type=script&lang=js&\"\nexport * from \"./quality-pill.vue?vue&type=script&lang=js&\"\nimport style0 from \"./quality-pill.vue?vue&type=style&index=0&id=b683ee7a&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"b683ee7a\",\n null\n \n)\n\ncomponent.options.__file = \"quality-pill.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"scroll-buttons-wrapper\" } }, [\n _c(\n \"div\",\n {\n staticClass: \"scroll-wrapper top\",\n class: { show: _vm.showToTop },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.scrollTop($event)\n }\n }\n },\n [_vm._m(0)]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n {\n staticClass: \"scroll-wrapper left\",\n class: { show: _vm.showLeftRight }\n },\n [\n _c(\"span\", { staticClass: \"scroll-left-inner\" }, [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-circle-arrow-left\",\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.scrollLeft($event)\n }\n }\n })\n ])\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n {\n staticClass: \"scroll-wrapper right\",\n class: { show: _vm.showLeftRight }\n },\n [\n _c(\"span\", { staticClass: \"scroll-right-inner\" }, [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-circle-arrow-right\",\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.scrollRight($event)\n }\n }\n })\n ])\n ]\n )\n ])\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"span\", { staticClass: \"scroll-top-inner\" }, [\n _c(\"i\", { staticClass: \"glyphicon glyphicon-circle-arrow-up\" })\n ])\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./scroll-buttons.vue?vue&type=template&id=96ee7e7e&\"\nimport script from \"./scroll-buttons.vue?vue&type=script&lang=js&\"\nexport * from \"./scroll-buttons.vue?vue&type=script&lang=js&\"\nimport style0 from \"./scroll-buttons.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"scroll-buttons.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n _vm._b(\n { staticClass: \"select-list max-width\" },\n \"div\",\n { disabled: _vm.disabled },\n false\n ),\n [\n _c(\"i\", {\n staticClass: \"switch-input glyphicon glyphicon-refresh\",\n attrs: { title: \"Switch between a list and comma separated values\" },\n on: {\n click: function($event) {\n _vm.switchFields()\n }\n }\n }),\n _vm._v(\" \"),\n !_vm.csvMode\n ? _c(\n \"ul\",\n [\n _vm._l(_vm.editItems, function(item) {\n return _c(\"li\", { key: item.id }, [\n _c(\"div\", { staticClass: \"input-group\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: item.value,\n expression: \"item.value\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: { type: \"text\" },\n domProps: { value: item.value },\n on: {\n input: [\n function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.$set(item, \"value\", $event.target.value)\n },\n function($event) {\n _vm.removeEmpty(item)\n }\n ]\n }\n }),\n _vm._v(\" \"),\n _c(\n \"div\",\n {\n staticClass: \"input-group-btn\",\n on: {\n click: function($event) {\n _vm.deleteItem(item)\n }\n }\n },\n [_vm._m(0, true)]\n )\n ])\n ])\n }),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"new-item\" }, [\n _c(\"div\", { staticClass: \"input-group\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.newItem,\n expression: \"newItem\"\n }\n ],\n ref: \"newItemInput\",\n staticClass: \"form-control input-sm\",\n attrs: {\n type: \"text\",\n placeholder: \"add new values per line\"\n },\n domProps: { value: _vm.newItem },\n on: {\n input: function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.newItem = $event.target.value\n }\n }\n }),\n _vm._v(\" \"),\n _c(\n \"div\",\n {\n staticClass: \"input-group-btn\",\n on: {\n click: function($event) {\n _vm.addNewItem()\n }\n }\n },\n [_vm._m(1)]\n )\n ])\n ]),\n _vm._v(\" \"),\n _vm.newItem.length > 0\n ? _c(\"div\", { staticClass: \"new-item-help\" }, [\n _vm._v(\"\\n Click \"),\n _c(\"i\", { staticClass: \"glyphicon glyphicon-plus\" }),\n _vm._v(\" to finish adding the value.\\n \")\n ])\n : _vm._e()\n ],\n 2\n )\n : _c(\"div\", { staticClass: \"csv\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.csv,\n expression: \"csv\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: {\n type: \"text\",\n placeholder: \"add values comma separated\"\n },\n domProps: { value: _vm.csv },\n on: {\n input: function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.csv = $event.target.value\n }\n }\n })\n ])\n ]\n )\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n {\n staticClass: \"btn btn-default input-sm\",\n staticStyle: { \"font-size\": \"14px\" }\n },\n [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-remove\",\n attrs: { title: \"Remove\" }\n })\n ]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n {\n staticClass: \"btn btn-default input-sm\",\n staticStyle: { \"font-size\": \"14px\" }\n },\n [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-plus\",\n attrs: { title: \"Add\" }\n })\n ]\n )\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./select-list.vue?vue&type=template&id=391728a9&scoped=true&\"\nimport script from \"./select-list.vue?vue&type=script&lang=js&\"\nexport * from \"./select-list.vue?vue&type=script&lang=js&\"\nimport style0 from \"./select-list.vue?vue&type=style&index=0&id=391728a9&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"391728a9\",\n null\n \n)\n\ncomponent.options.__file = \"select-list.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _vm.shows.length === 0\n ? _c(\"span\", [_vm._v(\"Loading...\")])\n : _c(\"div\", { staticClass: \"show-selector form-inline hidden-print\" }, [\n _c(\n \"div\",\n { staticClass: \"select-show-group pull-left top-5 bottom-5\" },\n [\n _c(\n \"select\",\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.selectedShowSlug,\n expression: \"selectedShowSlug\"\n }\n ],\n class: _vm.selectClass,\n on: {\n change: [\n function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val = \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.selectedShowSlug = $event.target.multiple\n ? $$selectedVal\n : $$selectedVal[0]\n },\n function($event) {\n _vm.$emit(\"change\", _vm.selectedShowSlug)\n }\n ]\n }\n },\n [\n _vm.placeholder\n ? _c(\n \"option\",\n {\n attrs: { disabled: \"\", hidden: \"\" },\n domProps: {\n value: _vm.placeholder,\n selected: !_vm.selectedShowSlug\n }\n },\n [_vm._v(_vm._s(_vm.placeholder))]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.whichList === -1\n ? _vm._l(_vm.showLists, function(curShowList) {\n return _c(\n \"optgroup\",\n {\n key: curShowList.type,\n attrs: { label: curShowList.type }\n },\n _vm._l(curShowList.shows, function(show) {\n return _c(\n \"option\",\n {\n key: show.id.slug,\n domProps: { value: show.id.slug }\n },\n [_vm._v(_vm._s(show.title))]\n )\n })\n )\n })\n : _vm._l(_vm.showLists[_vm.whichList].shows, function(show) {\n return _c(\n \"option\",\n {\n key: show.id.slug,\n domProps: { value: show.id.slug }\n },\n [_vm._v(_vm._s(show.title))]\n )\n })\n ],\n 2\n )\n ]\n )\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./show-selector.vue?vue&type=template&id=8ca36d42&\"\nimport script from \"./show-selector.vue?vue&type=script&lang=js&\"\nexport * from \"./show-selector.vue?vue&type=script&lang=js&\"\nimport style0 from \"./show-selector.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"show-selector.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"img\",\n _vm._b(\n { attrs: { height: \"16\", width: \"16\" } },\n \"img\",\n { src: _vm.src, alt: _vm.alt },\n false\n )\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./state-switch.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./state-switch.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./state-switch.vue?vue&type=template&id=676026e5&\"\nimport script from \"./state-switch.vue?vue&type=script&lang=js&\"\nexport * from \"./state-switch.vue?vue&type=script&lang=js&\"\nimport style0 from \"./state-switch.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"state-switch.vue\"\nexport default component.exports","export { default as AppLink } from './app-link.vue';\nexport { default as Asset } from './asset.vue';\nexport { default as ConfigTemplate } from './config-template.vue';\nexport { default as ConfigTextboxNumber } from './config-textbox-number.vue';\nexport { default as ConfigTextbox } from './config-textbox.vue';\nexport { default as ConfigToggleSlider } from './config-toggle-slider.vue';\nexport { default as FileBrowser } from './file-browser.vue';\nexport { default as LanguageSelect } from './language-select.vue';\nexport { default as NamePattern } from './name-pattern.vue';\nexport { default as PlotInfo } from './plot-info.vue';\nexport { default as QualityPill } from './quality-pill.vue';\nexport { default as ScrollButtons } from './scroll-buttons.vue';\nexport { default as SelectList } from './select-list.vue';\nexport { default as ShowSelector } from './show-selector.vue';\nexport { default as StateSwitch } from './state-switch.vue';\n","const isDevelopment = process.env.NODE_ENV === 'development';\n\n/**\n * Calculate the combined value of the selected qualities.\n * @param {number[]} allowedQualities - Array of allowed qualities.\n * @param {number[]} preferredQualities - Array of preferred qualities.\n * @returns {number} - An unsigned integer.\n */\nconst combineQualities = (allowedQualities, preferredQualities) => {\n const reducer = (accumulator, currentValue) => accumulator | currentValue;\n const allowed = allowedQualities.reduce(reducer, 0);\n const preferred = preferredQualities.reduce(reducer, 0);\n\n return (allowed | (preferred << 16)) >>> 0; // Unsigned int\n};\n\nexport {\n combineQualities,\n isDevelopment\n};\n","import VueRouter from 'vue-router';\n\nconst AddRecommended = () => import('./components/add-recommended.vue');\nconst AddShows = () => import('./components/add-shows.vue');\nconst Config = () => import('./components/config.vue');\nconst ConfigPostProcessing = () => import('./components/config-post-processing.vue');\nconst IRC = () => import('./components/irc.vue');\nconst Login = () => import('./components/login.vue');\nconst NotFound = () => import('./components/http/404.vue');\n\nconst homeRoutes = [{\n path: '/home',\n name: 'home',\n meta: {\n title: 'Home',\n header: 'Show List',\n topMenu: 'home'\n }\n}, {\n path: '/home/editShow',\n name: 'editShow',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/home/displayShow',\n name: 'show',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/home/snatchSelection',\n name: 'snatchSelection',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/home/testRename',\n name: 'testRename',\n meta: {\n title: 'Preview Rename',\n header: 'Preview Rename',\n topMenu: 'home'\n }\n}, {\n path: '/home/postprocess',\n name: 'postprocess',\n meta: {\n title: 'Manual Post-Processing',\n header: 'Manual Post-Processing',\n topMenu: 'home'\n }\n}, {\n path: '/home/status',\n name: 'status',\n meta: {\n title: 'Status',\n topMenu: 'system'\n }\n}, {\n path: '/home/restart',\n name: 'restart',\n meta: {\n title: 'Restarting...',\n header: 'Performing Restart',\n topMenu: 'system'\n }\n}, {\n path: '/home/shutdown',\n name: 'shutdown',\n meta: {\n header: 'Shutting down',\n topMenu: 'system'\n }\n}, {\n path: '/home/update',\n name: 'update',\n meta: {\n topMenu: 'system'\n }\n}];\n\nconst configRoutes = [{\n path: '/config',\n name: 'config',\n meta: {\n title: 'Help & Info',\n header: 'Medusa Configuration',\n topMenu: 'config',\n converted: true\n },\n component: Config\n}, {\n path: '/config/anime',\n name: 'configAnime',\n meta: {\n title: 'Config - Anime',\n header: 'Anime',\n topMenu: 'config'\n }\n}, {\n path: '/config/backuprestore',\n name: 'configBackupRestore',\n meta: {\n title: 'Config - Backup/Restore',\n header: 'Backup/Restore',\n topMenu: 'config'\n }\n}, {\n path: '/config/general',\n name: 'configGeneral',\n meta: {\n title: 'Config - General',\n header: 'General Configuration',\n topMenu: 'config'\n }\n}, {\n path: '/config/notifications',\n name: 'configNotifications',\n meta: {\n title: 'Config - Notifications',\n header: 'Notifications',\n topMenu: 'config'\n }\n}, {\n path: '/config/postProcessing',\n name: 'configPostProcessing',\n meta: {\n title: 'Config - Post Processing',\n header: 'Post Processing',\n topMenu: 'config'\n },\n component: ConfigPostProcessing\n}, {\n path: '/config/providers',\n name: 'configSearchProviders',\n meta: {\n title: 'Config - Providers',\n header: 'Search Providers',\n topMenu: 'config'\n }\n}, {\n path: '/config/search',\n name: 'configSearchSettings',\n meta: {\n title: 'Config - Episode Search',\n header: 'Search Settings',\n topMenu: 'config'\n }\n}, {\n path: '/config/subtitles',\n name: 'configSubtitles',\n meta: {\n title: 'Config - Subtitles',\n header: 'Subtitles',\n topMenu: 'config'\n }\n}];\n\nconst addShowRoutes = [{\n path: '/addShows',\n name: 'addShows',\n meta: {\n title: 'Add Shows',\n header: 'Add Shows',\n topMenu: 'home',\n converted: true\n },\n component: AddShows\n}, {\n path: '/addShows/addExistingShows',\n name: 'addExistingShows',\n meta: {\n title: 'Add Existing Shows',\n header: 'Add Existing Shows',\n topMenu: 'home'\n }\n}, {\n path: '/addShows/newShow',\n name: 'addNewShow',\n meta: {\n title: 'Add New Show',\n header: 'Add New Show',\n topMenu: 'home'\n }\n}, {\n path: '/addShows/trendingShows',\n name: 'addTrendingShows',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/addShows/popularShows',\n name: 'addPopularShows',\n meta: {\n title: 'Popular Shows',\n header: 'Popular Shows',\n topMenu: 'home'\n }\n}, {\n path: '/addShows/popularAnime',\n name: 'addPopularAnime',\n meta: {\n title: 'Popular Anime Shows',\n header: 'Popular Anime Shows',\n topMenu: 'home'\n }\n}];\n\nconst loginRoute = {\n path: '/login',\n name: 'login',\n meta: {\n title: 'Login'\n },\n component: Login\n};\n\nconst addRecommendedRoute = {\n path: '/addRecommended',\n name: 'addRecommended',\n meta: {\n title: 'Add Recommended Shows',\n header: 'Add Recommended Shows',\n topMenu: 'home'\n },\n component: AddRecommended\n};\n\nconst scheduleRoute = {\n path: '/schedule',\n name: 'schedule',\n meta: {\n title: 'Schedule',\n header: 'Schedule',\n topMenu: 'schedule'\n }\n};\n\nconst historyRoute = {\n path: '/history',\n name: 'history',\n meta: {\n title: 'History',\n header: 'History',\n topMenu: 'history'\n }\n};\n\nconst manageRoutes = [{\n path: '/manage',\n name: 'manage',\n meta: {\n title: 'Mass Update',\n header: 'Mass Update',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/backlogOverview',\n name: 'manageBacklogOverview',\n meta: {\n title: 'Backlog Overview',\n header: 'Backlog Overview',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/episodeStatuses',\n name: 'manageEpisodeOverview',\n meta: {\n title: 'Episode Overview',\n header: 'Episode Overview',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/failedDownloads',\n name: 'manageFailedDownloads',\n meta: {\n title: 'Failed Downloads',\n header: 'Failed Downlaods',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/manageSearches',\n name: 'manageManageSearches',\n meta: {\n title: 'Manage Searches',\n header: 'Manage Searches',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/massEdit',\n name: 'manageMassEdit',\n meta: {\n title: 'Mass Edit',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/subtitleMissed',\n name: 'manageSubtitleMissed',\n meta: {\n title: 'Missing Subtitles',\n header: 'Missing Subtitles',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/subtitleMissedPP',\n name: 'manageSubtitleMissedPP',\n meta: {\n title: 'Missing Subtitles in Post-Process folder',\n header: 'Missing Subtitles in Post-Process folder',\n topMenu: 'manage'\n }\n}];\n\nconst errorLogsRoutes = [{\n path: '/errorlogs',\n name: 'errorlogs',\n meta: {\n title: 'Logs & Errors',\n topMenu: 'system'\n }\n}, {\n path: '/errorlogs/viewlog',\n name: 'viewlog',\n meta: {\n title: 'Logs',\n header: 'Log File',\n topMenu: 'system'\n }\n}];\n\nconst newsRoute = {\n path: '/news',\n name: 'news',\n meta: {\n title: 'News',\n header: 'News',\n topMenu: 'system'\n }\n};\n\nconst changesRoute = {\n path: '/changes',\n name: 'changes',\n meta: {\n title: 'Changelog',\n header: 'Changelog',\n topMenu: 'system'\n }\n};\n\nconst ircRoute = {\n path: '/IRC',\n name: 'IRC',\n meta: {\n title: 'IRC',\n topMenu: 'system'\n },\n component: IRC\n};\n\nconst notFoundRoute = {\n path: '/not-found',\n name: 'not-found',\n meta: {\n title: '404',\n header: '404 - page not found'\n },\n component: NotFound\n};\n\n// @NOTE: Redirect can only be added once all routes are vue\n/*\nconst notFoundRedirect = {\n path: '*',\n redirect: '/not-found'\n};\n*/\n\nconst routes = [\n ...homeRoutes,\n ...configRoutes,\n ...addShowRoutes,\n loginRoute,\n addRecommendedRoute,\n scheduleRoute,\n historyRoute,\n ...manageRoutes,\n ...errorLogsRoutes,\n newsRoute,\n changesRoute,\n ircRoute,\n notFoundRoute\n];\n\nconst router = new VueRouter({\n base: document.body.getAttribute('web-root') + '/',\n mode: 'history',\n routes\n});\n\nrouter.beforeEach((to, from, next) => {\n const { meta } = to;\n const { title } = meta;\n\n // If there's no title then it's not a .vue route\n // or it's handling its own title\n if (title) {\n document.title = `${title} | Medusa`;\n }\n\n // Always call next otherwise the will be empty\n next();\n});\n\nexport default router;\n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./404.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./404.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./404.vue?vue&type=template&id=a851d9c2&\"\nimport script from \"./404.vue?vue&type=script&lang=js&\"\nexport * from \"./404.vue?vue&type=script&lang=js&\"\nimport style0 from \"./404.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"404.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { attrs: { id: \"addShowPortal\" } },\n [\n _c(\n \"app-link\",\n {\n staticClass: \"btn-medusa btn-large\",\n attrs: {\n href: \"addShows/trendingShows/?traktList=anticipated\",\n id: \"btnNewShow\"\n }\n },\n [\n _c(\"div\", { staticClass: \"button\" }, [\n _c(\"div\", { staticClass: \"add-list-icon-addtrakt\" })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"buttontext\" }, [\n _c(\"h3\", [_vm._v(\"Add From Trakt Lists\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"For shows that you haven't downloaded yet, this option lets you choose from a show from one of the Trakt lists to add to Medusa .\"\n )\n ])\n ])\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"app-link\",\n {\n staticClass: \"btn-medusa btn-large\",\n attrs: { href: \"addShows/popularShows/\", id: \"btnNewShow\" }\n },\n [\n _c(\"div\", { staticClass: \"button\" }, [\n _c(\"div\", { staticClass: \"add-list-icon-addimdb\" })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"buttontext\" }, [\n _c(\"h3\", [_vm._v(\"Add From IMDB's Popular Shows\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"View IMDB's list of the most popular shows. This feature uses IMDB's MOVIEMeter algorithm to identify popular TV Shows.\"\n )\n ])\n ])\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"app-link\",\n {\n staticClass: \"btn-medusa btn-large\",\n attrs: { href: \"addShows/popularAnime/\", id: \"btnNewShow\" }\n },\n [\n _c(\"div\", { staticClass: \"button\" }, [\n _c(\"div\", { staticClass: \"add-list-icon-addanime\" })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"buttontext\" }, [\n _c(\"h3\", [_vm._v(\"Add From Anidb's Hot Anime list\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n 'View Anidb\\'s list of the most popular anime shows. Anidb provides lists for Popular Anime, using the \"Hot Anime\" list.'\n )\n ])\n ])\n ]\n )\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-recommended.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-recommended.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./add-recommended.vue?vue&type=template&id=a2186b24&\"\nimport script from \"./add-recommended.vue?vue&type=script&lang=js&\"\nexport * from \"./add-recommended.vue?vue&type=script&lang=js&\"\nimport style0 from \"./add-recommended.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"add-recommended.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _vm._m(0)\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { staticClass: \"login\" }, [\n _c(\"form\", { attrs: { action: \"\", method: \"post\" } }, [\n _c(\"h1\", [_vm._v(\"Medusa\")]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"ctrlHolder\" }, [\n _c(\"input\", {\n staticClass: \"inlay\",\n attrs: {\n name: \"username\",\n type: \"text\",\n placeholder: \"Username\",\n autocomplete: \"off\"\n }\n })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"ctrlHolder\" }, [\n _c(\"input\", {\n staticClass: \"inlay\",\n attrs: {\n name: \"password\",\n type: \"password\",\n placeholder: \"Password\",\n autocomplete: \"off\"\n }\n })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"ctrlHolder\" }, [\n _c(\n \"label\",\n { staticClass: \"remember_me\", attrs: { title: \"for 30 days\" } },\n [\n _c(\"input\", {\n staticClass: \"inlay\",\n attrs: {\n id: \"remember_me\",\n name: \"remember_me\",\n type: \"checkbox\",\n value: \"1\",\n checked: \"checked\"\n }\n }),\n _vm._v(\" Remember me\")\n ]\n ),\n _vm._v(\" \"),\n _c(\"input\", {\n staticClass: \"button\",\n attrs: { name: \"submit\", type: \"submit\", value: \"Login\" }\n })\n ])\n ])\n ])\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./login.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./login.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./login.vue?vue&type=template&id=013dd286&\"\nimport script from \"./login.vue?vue&type=script&lang=js&\"\nexport * from \"./login.vue?vue&type=script&lang=js&\"\nimport style0 from \"./login.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"login.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"config-content\" } }, [\n _c(\n \"table\",\n {\n staticClass: \"infoTable\",\n attrs: {\n cellspacing: \"1\",\n border: \"0\",\n cellpadding: \"0\",\n width: \"100%\"\n }\n },\n [\n _c(\"tr\", [\n _vm._m(0),\n _vm._v(\" \"),\n _c(\"td\", [\n _vm._v(\"\\n Branch:\\n \"),\n _vm.config.branch\n ? _c(\n \"span\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href:\n _vm.config.sourceUrl + \"/tree/\" + _vm.config.branch\n }\n },\n [_vm._v(_vm._s(_vm.config.branch))]\n )\n ],\n 1\n )\n : _c(\"span\", [_vm._v(\"Unknown\")]),\n _vm._v(\" \"),\n _c(\"br\"),\n _vm._v(\"\\n Commit:\\n \"),\n _vm.config.commitHash\n ? _c(\n \"span\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href:\n _vm.config.sourceUrl +\n \"/commit/\" +\n _vm.config.commitHash\n }\n },\n [_vm._v(_vm._s(_vm.config.commitHash))]\n )\n ],\n 1\n )\n : _c(\"span\", [_vm._v(\"Unknown\")]),\n _vm._v(\" \"),\n _c(\"br\"),\n _vm._v(\"\\n Version:\\n \"),\n _vm.config.release\n ? _c(\n \"span\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href:\n _vm.config.sourceUrl +\n \"/releases/tag/\" +\n _vm.config.release\n }\n },\n [_vm._v(_vm._s(_vm.config.release))]\n )\n ],\n 1\n )\n : _c(\"span\", [_vm._v(\"Unknown\")]),\n _vm._v(\" \"),\n _c(\"br\"),\n _vm._v(\"\\n Database:\\n \"),\n _vm.config.databaseVersion\n ? _c(\"span\", [\n _vm._v(\n _vm._s(_vm.config.databaseVersion.major) +\n \".\" +\n _vm._s(_vm.config.databaseVersion.minor)\n )\n ])\n : _c(\"span\", [_vm._v(\"Unknown\")])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(1),\n _c(\"td\", [_vm._v(_vm._s(_vm.config.pythonVersion))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(2),\n _c(\"td\", [_vm._v(_vm._s(_vm.config.sslVersion))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [_vm._m(3), _c(\"td\", [_vm._v(_vm._s(_vm.config.os))])]),\n _vm._v(\" \"),\n _c(\"tr\", [_vm._m(4), _c(\"td\", [_vm._v(_vm._s(_vm.config.locale))])]),\n _vm._v(\" \"),\n _vm._m(5),\n _vm._v(\" \"),\n _vm._m(6),\n _vm._v(\" \"),\n _c(\"tr\", [_vm._m(7), _c(\"td\", [_vm._v(_vm._s(_vm.config.localUser))])]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(8),\n _c(\"td\", [_vm._v(_vm._s(_vm.config.programDir))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(9),\n _c(\"td\", [_vm._v(_vm._s(_vm.config.configFile))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [_vm._m(10), _c(\"td\", [_vm._v(_vm._s(_vm.config.dbPath))])]),\n _vm._v(\" \"),\n _c(\"tr\", [_vm._m(11), _c(\"td\", [_vm._v(_vm._s(_vm.config.cacheDir))])]),\n _vm._v(\" \"),\n _c(\"tr\", [_vm._m(12), _c(\"td\", [_vm._v(_vm._s(_vm.config.logDir))])]),\n _vm._v(\" \"),\n _vm.config.appArgs\n ? _c(\"tr\", [\n _vm._m(13),\n _c(\"td\", [\n _c(\"pre\", [\n _vm._v(_vm._s(_vm._f(\"prettyPrintJSON\")(_vm.config.appArgs)))\n ])\n ])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _vm.config.webRoot\n ? _c(\"tr\", [\n _vm._m(14),\n _c(\"td\", [_vm._v(_vm._s(_vm.config.webRoot))])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _vm.config.runsInDocker\n ? _c(\"tr\", [\n _vm._m(15),\n _c(\"td\", [_vm._v(_vm._s(_vm.config.runsInDocker ? \"yes\" : \"no\"))])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _vm._m(16),\n _vm._v(\" \"),\n _vm._m(17),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(18),\n _c(\n \"td\",\n [\n _c(\"app-link\", { attrs: { href: _vm.config.githubUrl } }, [\n _vm._v(_vm._s(_vm.config.githubUrl))\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(19),\n _c(\n \"td\",\n [\n _c(\"app-link\", { attrs: { href: _vm.config.wikiUrl } }, [\n _vm._v(_vm._s(_vm.config.wikiUrl))\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(20),\n _c(\n \"td\",\n [\n _c(\"app-link\", { attrs: { href: _vm.config.sourceUrl } }, [\n _vm._v(_vm._s(_vm.config.sourceUrl))\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(21),\n _c(\n \"td\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"irc://irc.freenode.net/#pymedusa\" } },\n [\n _c(\"i\", [_vm._v(\"#pymedusa\")]),\n _vm._v(\" on \"),\n _c(\"i\", [_vm._v(\"irc.freenode.net\")])\n ]\n )\n ],\n 1\n )\n ])\n ]\n )\n ])\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-application\" }),\n _vm._v(\" Medusa Info:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-python\" }),\n _vm._v(\" Python Version:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-ssl\" }),\n _vm._v(\" SSL Version:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-os\" }),\n _vm._v(\" OS:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-locale\" }),\n _vm._v(\" Locale:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [_c(\"td\", [_vm._v(\" \")]), _c(\"td\", [_vm._v(\" \")])])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"infoTableSeperator\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _c(\"td\", [_vm._v(\" \")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-user\" }),\n _vm._v(\" User:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-dir\" }),\n _vm._v(\" Program Folder:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-config\" }),\n _vm._v(\" Config File:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-db\" }),\n _vm._v(\" Database File:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-cache\" }),\n _vm._v(\" Cache Folder:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-log\" }),\n _vm._v(\" Log Folder:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-arguments\" }),\n _vm._v(\" Arguments:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-dir\" }),\n _vm._v(\" Web Root:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-docker\" }),\n _vm._v(\" Runs in docker:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [_c(\"td\", [_vm._v(\" \")]), _c(\"td\", [_vm._v(\" \")])])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"infoTableSeperator\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _c(\"td\", [_vm._v(\" \")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-web\" }),\n _vm._v(\" Website:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-wiki\" }),\n _vm._v(\" Wiki:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-github\" }),\n _vm._v(\" Source:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-mirc\" }),\n _vm._v(\" IRC Chat:\")\n ])\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./config.vue?vue&type=template&id=2ad9ae57&\"\nimport script from \"./config.vue?vue&type=script&lang=js&\"\nexport * from \"./config.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"config.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { attrs: { id: \"addShowPortal\" } },\n [\n _c(\n \"app-link\",\n {\n staticClass: \"btn-medusa btn-large\",\n attrs: { href: \"addShows/newShow/\", id: \"btnNewShow\" }\n },\n [\n _c(\"div\", { staticClass: \"button\" }, [\n _c(\"div\", { staticClass: \"add-list-icon-addnewshow\" })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"buttontext\" }, [\n _c(\"h3\", [_vm._v(\"Add New Show\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"For shows that you haven't downloaded yet, this option finds a show on your preferred indexer, creates a directory for it's episodes, and adds it to Medusa.\"\n )\n ])\n ])\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"app-link\",\n {\n staticClass: \"btn-medusa btn-large\",\n attrs: { href: \"addShows/existingShows/\", id: \"btnExistingShow\" }\n },\n [\n _c(\"div\", { staticClass: \"button\" }, [\n _c(\"div\", { staticClass: \"add-list-icon-addexistingshow\" })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"buttontext\" }, [\n _c(\"h3\", [_vm._v(\"Add Existing Shows\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"Use this option to add shows that already have a folder created on your hard drive. Medusa will scan your existing metadata/episodes and add the show accordingly.\"\n )\n ])\n ])\n ]\n )\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-shows.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-shows.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./add-shows.vue?vue&type=template&id=4812b86a&\"\nimport script from \"./add-shows.vue?vue&type=script&lang=js&\"\nexport * from \"./add-shows.vue?vue&type=script&lang=js&\"\nimport style0 from \"./add-shows.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"add-shows.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"iframe\", {\n staticClass: \"irc-frame loading-spinner\",\n attrs: { src: _vm.frameSrc }\n })\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./irc.vue?vue&type=template&id=60f89f30&scoped=true&\"\nimport script from \"./irc.vue?vue&type=script&lang=js&\"\nexport * from \"./irc.vue?vue&type=script&lang=js&\"\nimport style0 from \"./irc.vue?vue&type=style&index=0&id=60f89f30&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"60f89f30\",\n null\n \n)\n\ncomponent.options.__file = \"irc.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"config\" } }, [\n _c(\"div\", { attrs: { id: \"config-content\" } }, [\n _c(\n \"form\",\n {\n staticClass: \"form-horizontal\",\n attrs: { id: \"configForm\" },\n on: {\n submit: function($event) {\n $event.preventDefault()\n _vm.save()\n }\n }\n },\n [\n _c(\"div\", { attrs: { id: \"config-components\" } }, [\n _c(\"ul\", [\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"#post-processing\" } }, [\n _vm._v(\"Post Processing\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"#episode-naming\" } }, [\n _vm._v(\"Episode Naming\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"#metadata\" } }, [\n _vm._v(\"Metadata\")\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { attrs: { id: \"post-processing\" } }, [\n _c(\"div\", { staticClass: \"row component-group\" }, [\n _vm._m(0),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-xs-12 col-md-10\" }, [\n _c(\"fieldset\", { staticClass: \"component-group-list\" }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(1),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"process_automatically\",\n name: \"process_automatically\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.processAutomatically,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"processAutomatically\",\n $$v\n )\n },\n expression: \"postProcessing.processAutomatically\"\n }\n }),\n _vm._v(\" \"),\n _vm._m(2),\n _vm._v(\" \"),\n _vm._m(3)\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\n \"div\",\n {\n directives: [\n {\n name: \"show\",\n rawName: \"v-show\",\n value: _vm.postProcessing.processAutomatically,\n expression: \"postProcessing.processAutomatically\"\n }\n ],\n attrs: { id: \"post-process-toggle-wrapper\" }\n },\n [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(4),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"file-browser\", {\n attrs: {\n id: \"tv_download_dir\",\n name: \"tv_download_dir\",\n title: \"Select series download location\",\n \"initial-dir\":\n _vm.postProcessing.showDownloadDir\n },\n on: {\n update: function($event) {\n _vm.postProcessing.showDownloadDir = $event\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", { staticClass: \"clear-left\" }, [\n _vm._v(\n \"The folder where your download client puts the completed TV downloads.\"\n )\n ]),\n _vm._v(\" \"),\n _vm._m(5)\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(6),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\n \"select\",\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.postProcessing.processMethod,\n expression: \"postProcessing.processMethod\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: {\n id: \"naming_multi_ep\",\n name: \"naming_multi_ep\"\n },\n on: {\n change: function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val =\n \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.$set(\n _vm.postProcessing,\n \"processMethod\",\n $event.target.multiple\n ? $$selectedVal\n : $$selectedVal[0]\n )\n }\n }\n },\n _vm._l(_vm.processMethods, function(option) {\n return _c(\n \"option\",\n {\n key: option.value,\n domProps: { value: option.value }\n },\n [_vm._v(_vm._s(option.text))]\n )\n })\n ),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"What method should be used to put files into the library?\"\n )\n ]),\n _vm._v(\" \"),\n _vm._m(7),\n _vm._v(\" \"),\n _vm.postProcessing.processMethod == \"reflink\"\n ? _c(\n \"p\",\n [\n _vm._v(\"To use reference linking, the \"),\n _c(\n \"app-link\",\n {\n attrs: {\n href:\n \"http://www.dereferer.org/?https://pypi.python.org/pypi/reflink/0.1.4\"\n }\n },\n [_vm._v(\"reflink package\")]\n ),\n _vm._v(\" needs to be installed.\")\n ],\n 1\n )\n : _vm._e()\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(8),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model.number\",\n value:\n _vm.postProcessing\n .autoPostprocessorFrequency,\n expression:\n \"postProcessing.autoPostprocessorFrequency\",\n modifiers: { number: true }\n }\n ],\n staticClass: \"form-control input-sm input75\",\n attrs: {\n type: \"number\",\n min: \"10\",\n step: \"1\",\n name: \"autopostprocessor_frequency\",\n id: \"autopostprocessor_frequency\"\n },\n domProps: {\n value:\n _vm.postProcessing.autoPostprocessorFrequency\n },\n on: {\n input: function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.$set(\n _vm.postProcessing,\n \"autoPostprocessorFrequency\",\n _vm._n($event.target.value)\n )\n },\n blur: function($event) {\n _vm.$forceUpdate()\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Time in minutes to check for new files to auto post-process (min 10)\"\n )\n ])\n ])\n ])\n ]\n )\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"row component-group\" }, [\n _vm._m(9),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-xs-12 col-md-10\" }, [\n _c(\"fieldset\", { staticClass: \"component-group-list\" }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(10),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"postpone_if_sync_files\",\n name: \"postpone_if_sync_files\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.postponeIfSyncFiles,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"postponeIfSyncFiles\",\n $$v\n )\n },\n expression: \"postProcessing.postponeIfSyncFiles\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Wait to process a folder if sync files are present.\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(11),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"select-list\", {\n attrs: {\n name: \"sync_files\",\n id: \"sync_files\",\n \"csv-enabled\": \"\",\n \"list-items\": _vm.postProcessing.syncFiles\n },\n on: { change: _vm.onChangeSyncFiles }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"comma seperated list of extensions or filename globs Medusa ignores when Post Processing\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(12),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"postpone_if_no_subs\",\n name: \"postpone_if_no_subs\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.postponeIfNoSubs,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"postponeIfNoSubs\",\n $$v\n )\n },\n expression: \"postProcessing.postponeIfNoSubs\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Wait to process a file until subtitles are present\"\n )\n ]),\n _c(\"br\"),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Language names are allowed in subtitle filename (en.srt, pt-br.srt, ita.srt, etc.)\"\n )\n ]),\n _c(\"br\"),\n _vm._v(\" \"),\n _vm._m(13),\n _c(\"br\"),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"If you have any active show with subtitle search disabled, you must enable Automatic post processor.\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(14),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"rename_episodes\",\n name: \"rename_episodes\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.renameEpisodes,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"renameEpisodes\",\n $$v\n )\n },\n expression: \"postProcessing.renameEpisodes\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Rename episode using the Episode Naming settings?\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(15),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"create_missing_show_dirs\",\n name: \"create_missing_show_dirs\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.createMissingShowDirs,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"createMissingShowDirs\",\n $$v\n )\n },\n expression: \"postProcessing.createMissingShowDirs\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Create missing show directories when they get deleted\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(16),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"add_shows_wo_dir\",\n name: \"add_shows_wo_dir\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.addShowsWithoutDir,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"addShowsWithoutDir\",\n $$v\n )\n },\n expression: \"postProcessing.addShowsWithoutDir\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Add shows without creating a directory (not recommended)\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(17),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"move_associated_files\",\n name: \"move_associated_files\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.moveAssociatedFiles,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"moveAssociatedFiles\",\n $$v\n )\n },\n expression: \"postProcessing.moveAssociatedFiles\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Delete srt/srr/sfv/etc files while post processing?\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(18),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"select-list\", {\n attrs: {\n name: \"allowed_extensions\",\n id: \"allowed_extensions\",\n \"csv-enabled\": \"\",\n \"list-items\": _vm.postProcessing.allowedExtensions\n },\n on: { change: _vm.onChangeAllowedExtensions }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Comma seperated list of associated file extensions Medusa should keep while post processing.\"\n )\n ]),\n _c(\"br\"),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Leaving it empty means all associated files will be deleted\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(19),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"nfo_rename\",\n name: \"nfo_rename\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.nfoRename,\n callback: function($$v) {\n _vm.$set(_vm.postProcessing, \"nfoRename\", $$v)\n },\n expression: \"postProcessing.nfoRename\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Rename the original .nfo file to .nfo-orig to avoid conflicts?\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(20),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"airdate_episodes\",\n name: \"airdate_episodes\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.airdateEpisodes,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"airdateEpisodes\",\n $$v\n )\n },\n expression: \"postProcessing.airdateEpisodes\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Set last modified filedate to the date that the episode aired?\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(21),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\n \"select\",\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.postProcessing.fileTimestampTimezone,\n expression:\n \"postProcessing.fileTimestampTimezone\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: {\n id: \"file_timestamp_timezone\",\n name: \"file_timestamp_timezone\"\n },\n on: {\n change: function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val = \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.$set(\n _vm.postProcessing,\n \"fileTimestampTimezone\",\n $event.target.multiple\n ? $$selectedVal\n : $$selectedVal[0]\n )\n }\n }\n },\n _vm._l(_vm.timezoneOptions, function(option) {\n return _c(\n \"option\",\n {\n key: option.value,\n domProps: { value: option.value }\n },\n [_vm._v(_vm._s(option.text))]\n )\n })\n ),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"What timezone should be used to change File Date?\"\n )\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(22),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"unpack\",\n name: \"unpack\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.unpack,\n callback: function($$v) {\n _vm.$set(_vm.postProcessing, \"unpack\", $$v)\n },\n expression: \"postProcessing.unpack\"\n }\n }),\n _vm._v(\" \"),\n _vm._m(23),\n _c(\"br\"),\n _vm._v(\" \"),\n _vm._m(24)\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(25),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"del_rar_contents\",\n name: \"del_rar_contents\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.deleteRarContent,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"deleteRarContent\",\n $$v\n )\n },\n expression: \"postProcessing.deleteRarContent\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Delete content of RAR files, even if Process Method not set to move?\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(26),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"no_delete\",\n name: \"no_delete\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.noDelete,\n callback: function($$v) {\n _vm.$set(_vm.postProcessing, \"noDelete\", $$v)\n },\n expression: \"postProcessing.noDelete\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\"Leave empty folders when Post Processing?\")\n ]),\n _c(\"br\"),\n _vm._v(\" \"),\n _vm._m(27)\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(28),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"select-list\", {\n attrs: {\n name: \"extra_scripts\",\n id: \"extra_scripts\",\n \"csv-enabled\": \"\",\n \"list-items\": _vm.postProcessing.extraScripts\n },\n on: { change: _vm.onChangeExtraScripts }\n }),\n _vm._v(\" \"),\n _c(\n \"span\",\n [\n _vm._v(\"See \"),\n _c(\n \"app-link\",\n {\n staticClass: \"wikie\",\n attrs: {\n href: _vm.postProcessing.extraScriptsUrl\n }\n },\n [_c(\"strong\", [_vm._v(\"Wiki\")])]\n ),\n _vm._v(\n \" for script arguments description and usage.\"\n )\n ],\n 1\n )\n ],\n 1\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"input\", {\n staticClass: \"btn-medusa config_submitter\",\n attrs: { type: \"submit\", value: \"Save Changes\" }\n })\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { attrs: { id: \"episode-naming\" } }, [\n _c(\"div\", { staticClass: \"row component-group\" }, [\n _vm._m(29),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-xs-12 col-md-10\" }, [\n _c(\n \"fieldset\",\n { staticClass: \"component-group-list\" },\n [\n _c(\"name-pattern\", {\n staticClass: \"component-item\",\n attrs: {\n \"naming-pattern\": _vm.postProcessing.naming.pattern,\n \"naming-presets\": _vm.presets,\n \"multi-ep-style\": _vm.postProcessing.naming.multiEp,\n \"multi-ep-styles\": _vm.multiEpStringsSelect,\n \"flag-loaded\": _vm.configLoaded\n },\n on: { change: _vm.saveNaming }\n }),\n _vm._v(\" \"),\n _c(\"name-pattern\", {\n staticClass: \"component-item\",\n attrs: {\n enabled:\n _vm.postProcessing.naming.enableCustomNamingSports,\n \"naming-pattern\":\n _vm.postProcessing.naming.patternSports,\n \"naming-presets\": _vm.presets,\n type: \"sports\",\n \"enabled-naming-custom\":\n _vm.postProcessing.naming.enableCustomNamingSports,\n \"flag-loaded\": _vm.configLoaded\n },\n on: { change: _vm.saveNamingSports }\n }),\n _vm._v(\" \"),\n _c(\"name-pattern\", {\n staticClass: \"component-item\",\n attrs: {\n enabled:\n _vm.postProcessing.naming\n .enableCustomNamingAirByDate,\n \"naming-pattern\":\n _vm.postProcessing.naming.patternAirByDate,\n \"naming-presets\": _vm.presets,\n type: \"airs by date\",\n \"enabled-naming-custom\":\n _vm.postProcessing.naming\n .enableCustomNamingAirByDate,\n \"flag-loaded\": _vm.configLoaded\n },\n on: { change: _vm.saveNamingAbd }\n }),\n _vm._v(\" \"),\n _c(\"name-pattern\", {\n staticClass: \"component-item\",\n attrs: {\n enabled:\n _vm.postProcessing.naming.enableCustomNamingAnime,\n \"naming-pattern\":\n _vm.postProcessing.naming.patternAnime,\n \"naming-presets\": _vm.presets,\n type: \"anime\",\n \"multi-ep-style\":\n _vm.postProcessing.naming.animeMultiEp,\n \"multi-ep-styles\": _vm.multiEpStringsSelect,\n \"anime-naming-type\":\n _vm.postProcessing.naming.animeNamingType,\n \"enabled-naming-custom\":\n _vm.postProcessing.naming.enableCustomNamingAnime,\n \"flag-loaded\": _vm.configLoaded\n },\n on: { change: _vm.saveNamingAnime }\n }),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group component-item\" }, [\n _vm._m(30),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"naming_strip_year\",\n name: \"naming_strip_year\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.naming.stripYear,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing.naming,\n \"stripYear\",\n $$v\n )\n },\n expression: \"postProcessing.naming.stripYear\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Remove the TV show's year when renaming the file?\"\n )\n ]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"Only applies to shows that have year inside parentheses\"\n )\n ])\n ],\n 1\n )\n ])\n ],\n 1\n )\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { attrs: { id: \"metadata\" } }, [\n _c(\"div\", { staticClass: \"row component-group\" }, [\n _vm._m(31),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-xs-12 col-md-10\" }, [\n _c(\n \"fieldset\",\n { staticClass: \"component-group-list\" },\n [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(32),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\n \"select\",\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.metadataProviderSelected,\n expression: \"metadataProviderSelected\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: {\n id: \"metadataType\",\n name: \"metadataType\"\n },\n on: {\n change: function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val =\n \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.metadataProviderSelected = $event.target\n .multiple\n ? $$selectedVal\n : $$selectedVal[0]\n }\n }\n },\n _vm._l(_vm.metadataProviders, function(option) {\n return _c(\n \"option\",\n {\n key: option.id,\n domProps: { value: option.id }\n },\n [_vm._v(_vm._s(option.name))]\n )\n })\n ),\n _vm._v(\" \"),\n _vm._m(33)\n ])\n ]),\n _vm._v(\" \"),\n _vm._l(_vm.metadataProviders, function(provider) {\n return _c(\n \"div\",\n {\n directives: [\n {\n name: \"show\",\n rawName: \"v-show\",\n value:\n provider.id === _vm.metadataProviderSelected,\n expression:\n \"provider.id === metadataProviderSelected\"\n }\n ],\n key: provider.id,\n staticClass: \"metadataDiv\",\n attrs: { id: \"provider.id\" }\n },\n [\n _c(\n \"div\",\n { staticClass: \"metadata_options_wrapper\" },\n [\n _c(\"h4\", [_vm._v(\"Create:\")]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"metadata_options\" }, [\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_show_metadata\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.showMetadata,\n expression: \"provider.showMetadata\"\n }\n ],\n staticClass: \"metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_show_metadata\"\n },\n domProps: {\n checked: Array.isArray(\n provider.showMetadata\n )\n ? _vm._i(\n provider.showMetadata,\n null\n ) > -1\n : provider.showMetadata\n },\n on: {\n change: function($event) {\n var $$a = provider.showMetadata,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"showMetadata\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"showMetadata\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"showMetadata\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Show Metadata\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_episode_metadata\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.episodeMetadata,\n expression:\n \"provider.episodeMetadata\"\n }\n ],\n staticClass: \"metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_episode_metadata\",\n disabled: provider.example.episodeMetadata.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.episodeMetadata\n )\n ? _vm._i(\n provider.episodeMetadata,\n null\n ) > -1\n : provider.episodeMetadata\n },\n on: {\n change: function($event) {\n var $$a = provider.episodeMetadata,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"episodeMetadata\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"episodeMetadata\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"episodeMetadata\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Episode Metadata\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n { attrs: { for: provider.id + \"_fanart\" } },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.fanart,\n expression: \"provider.fanart\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_fanart\",\n disabled: provider.example.fanart.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.fanart\n )\n ? _vm._i(provider.fanart, null) > -1\n : provider.fanart\n },\n on: {\n change: function($event) {\n var $$a = provider.fanart,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"fanart\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"fanart\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(provider, \"fanart\", $$c)\n }\n }\n }\n }),\n _vm._v(\" Show Fanart\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n { attrs: { for: provider.id + \"_poster\" } },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.poster,\n expression: \"provider.poster\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_poster\",\n disabled: provider.example.poster.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.poster\n )\n ? _vm._i(provider.poster, null) > -1\n : provider.poster\n },\n on: {\n change: function($event) {\n var $$a = provider.poster,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"poster\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"poster\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(provider, \"poster\", $$c)\n }\n }\n }\n }),\n _vm._v(\" Show Poster\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n { attrs: { for: provider.id + \"_banner\" } },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.banner,\n expression: \"provider.banner\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_banner\",\n disabled: provider.example.banner.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.banner\n )\n ? _vm._i(provider.banner, null) > -1\n : provider.banner\n },\n on: {\n change: function($event) {\n var $$a = provider.banner,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"banner\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"banner\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(provider, \"banner\", $$c)\n }\n }\n }\n }),\n _vm._v(\" Show Banner\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_episode_thumbnails\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.episodeThumbnails,\n expression:\n \"provider.episodeThumbnails\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id:\n provider.id + \"_episode_thumbnails\",\n disabled: provider.example.episodeThumbnails.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.episodeThumbnails\n )\n ? _vm._i(\n provider.episodeThumbnails,\n null\n ) > -1\n : provider.episodeThumbnails\n },\n on: {\n change: function($event) {\n var $$a =\n provider.episodeThumbnails,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"episodeThumbnails\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"episodeThumbnails\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"episodeThumbnails\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Episode Thumbnails\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_posters\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.seasonPosters,\n expression: \"provider.seasonPosters\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_season_posters\",\n disabled: provider.example.seasonPosters.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.seasonPosters\n )\n ? _vm._i(\n provider.seasonPosters,\n null\n ) > -1\n : provider.seasonPosters\n },\n on: {\n change: function($event) {\n var $$a = provider.seasonPosters,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"seasonPosters\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"seasonPosters\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"seasonPosters\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Season Posters\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_banners\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.seasonBanners,\n expression: \"provider.seasonBanners\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_season_banners\",\n disabled: provider.example.seasonBanners.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.seasonBanners\n )\n ? _vm._i(\n provider.seasonBanners,\n null\n ) > -1\n : provider.seasonBanners\n },\n on: {\n change: function($event) {\n var $$a = provider.seasonBanners,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"seasonBanners\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"seasonBanners\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"seasonBanners\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Season Banners\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_all_poster\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.seasonAllPoster,\n expression:\n \"provider.seasonAllPoster\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id:\n provider.id + \"_season_all_poster\",\n disabled: provider.example.seasonAllPoster.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.seasonAllPoster\n )\n ? _vm._i(\n provider.seasonAllPoster,\n null\n ) > -1\n : provider.seasonAllPoster\n },\n on: {\n change: function($event) {\n var $$a = provider.seasonAllPoster,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"seasonAllPoster\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"seasonAllPoster\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"seasonAllPoster\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Season All Poster\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_all_banner\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.seasonAllBanner,\n expression:\n \"provider.seasonAllBanner\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id:\n provider.id + \"_season_all_banner\",\n disabled: provider.example.seasonAllBanner.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.seasonAllBanner\n )\n ? _vm._i(\n provider.seasonAllBanner,\n null\n ) > -1\n : provider.seasonAllBanner\n },\n on: {\n change: function($event) {\n var $$a = provider.seasonAllBanner,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"seasonAllBanner\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"seasonAllBanner\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"seasonAllBanner\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Season All Banner\")\n ]\n )\n ])\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"metadata_example_wrapper\" },\n [\n _c(\"h4\", [_vm._v(\"Results:\")]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"metadata_example\" }, [\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_show_metadata\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.showMetadata\n },\n attrs: {\n id:\n provider.id + \"_eg_show_metadata\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .showMetadata +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_episode_metadata\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.episodeMetadata\n },\n attrs: {\n id:\n provider.id +\n \"_eg_episode_metadata\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .episodeMetadata +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n { attrs: { for: provider.id + \"_fanart\" } },\n [\n _c(\n \"span\",\n {\n class: { disabled: !provider.fanart },\n attrs: {\n id: provider.id + \"_eg_fanart\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example.fanart +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n { attrs: { for: provider.id + \"_poster\" } },\n [\n _c(\n \"span\",\n {\n class: { disabled: !provider.poster },\n attrs: {\n id: provider.id + \"_eg_poster\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example.poster +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n { attrs: { for: provider.id + \"_banner\" } },\n [\n _c(\n \"span\",\n {\n class: { disabled: !provider.banner },\n attrs: {\n id: provider.id + \"_eg_banner\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example.banner +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_episode_thumbnails\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.episodeThumbnails\n },\n attrs: {\n id:\n provider.id +\n \"_eg_episode_thumbnails\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .episodeThumbnails +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_posters\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.seasonPosters\n },\n attrs: {\n id:\n provider.id + \"_eg_season_posters\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .seasonPosters +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_banners\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.seasonBanners\n },\n attrs: {\n id:\n provider.id + \"_eg_season_banners\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .seasonBanners +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_all_poster\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.seasonAllPoster\n },\n attrs: {\n id:\n provider.id +\n \"_eg_season_all_poster\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .seasonAllPoster +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_all_banner\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.seasonAllBanner\n },\n attrs: {\n id:\n provider.id +\n \"_eg_season_all_banner\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .seasonAllBanner +\n \"\"\n )\n }\n })\n ]\n )\n ]\n )\n ])\n ]\n )\n ]\n )\n })\n ],\n 2\n ),\n _vm._v(\" \"),\n _c(\"input\", {\n staticClass: \"btn-medusa config_submitter\",\n attrs: { type: \"submit\", value: \"Save Changes\" }\n }),\n _c(\"br\")\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"h6\", { staticClass: \"pull-right\" }, [\n _c(\"b\", [\n _vm._v(\"All non-absolute folder locations are relative to \"),\n _c(\"span\", { staticClass: \"path\" }, [\n _vm._v(_vm._s(_vm.config.dataDir))\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"input\", {\n staticClass: \"btn-medusa pull-left config_submitter button\",\n attrs: { type: \"submit\", value: \"Save Changes\" }\n })\n ])\n ]\n )\n ])\n ])\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"component-group-desc col-xs-12 col-md-2\" },\n [\n _c(\"h3\", [_vm._v(\"Scheduled Post-Processing\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"Settings that dictate how Medusa should process completed downloads.\"\n )\n ]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"The scheduled postprocessor will periodically scan a folder for media to process.\"\n )\n ])\n ]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"process_automatically\" }\n },\n [_c(\"span\", [_vm._v(\"Scheduled Postprocessor\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"p\", [\n _vm._v(\n \"Enable the scheduled post processor to scan and process any files in your \"\n ),\n _c(\"i\", [_vm._v(\"Post Processing Dir\")]),\n _vm._v(\"?\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { staticClass: \"clear-left\" }, [\n _c(\"p\", [\n _c(\"b\", [_vm._v(\"NOTE:\")]),\n _vm._v(\" Do not use if you use an external Post Processing script\")\n ])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"tv_download_dir\" }\n },\n [_c(\"span\", [_vm._v(\"Post Processing Dir\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { staticClass: \"clear-left\" }, [\n _c(\"p\", [\n _c(\"b\", [_vm._v(\"NOTE:\")]),\n _vm._v(\n \" Please use seperate downloading and completed folders in your download client if possible.\"\n )\n ])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"process_method\" }\n },\n [_c(\"span\", [_vm._v(\"Processing Method\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"p\", [\n _c(\"b\", [_vm._v(\"NOTE:\")]),\n _vm._v(\n \" If you keep seeding torrents after they finish, please avoid the 'move' processing method to prevent errors.\"\n )\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"autopostprocessor_frequency\" }\n },\n [_c(\"span\", [_vm._v(\"Auto Post-Processing Frequency\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"component-group-desc col-xs-12 col-md-2\" },\n [\n _c(\"h3\", [_vm._v(\"General Post-Processing\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"Generic postprocessing settings that apply both to the scheduled postprocessor as external scripts\"\n )\n ])\n ]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"postpone_if_sync_files\" }\n },\n [_c(\"span\", [_vm._v(\"Postpone post processing\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"sync_files\" } },\n [_c(\"span\", [_vm._v(\"Sync File Extensions\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"postpone_if_no_subs\" }\n },\n [_c(\"span\", [_vm._v(\"Postpone if no subtitle\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"span\", [\n _c(\"b\", [_vm._v(\"NOTE:\")]),\n _vm._v(\n \" Automatic post processor should be disabled to avoid files with pending subtitles being processed over and over.\"\n )\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"rename_episodes\" }\n },\n [_c(\"span\", [_vm._v(\"Rename Episodes\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"create_missing_show_dirs\" }\n },\n [_c(\"span\", [_vm._v(\"Create missing show directories\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"add_shows_wo_dir\" }\n },\n [_c(\"span\", [_vm._v(\"Add shows without directory\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"move_associated_files\" }\n },\n [_c(\"span\", [_vm._v(\"Delete associated files\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"label\", { staticClass: \"col-sm-2 control-label\" }, [\n _c(\"span\", [_vm._v(\"Keep associated file extensions\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"nfo_rename\" } },\n [_c(\"span\", [_vm._v(\"Rename .nfo file\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"airdate_episodes\" }\n },\n [_c(\"span\", [_vm._v(\"Change File Date\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"file_timestamp_timezone\" }\n },\n [_c(\"span\", [_vm._v(\"Timezone for File Date:\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"unpack\" } },\n [_c(\"span\", [_vm._v(\"Unpack\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"span\", [\n _vm._v(\"Unpack any TV releases in your \"),\n _c(\"i\", [_vm._v(\"TV Download Dir\")]),\n _vm._v(\"?\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"span\", [\n _c(\"b\", [_vm._v(\"NOTE:\")]),\n _vm._v(\" Only working with RAR archive\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"del_rar_contents\" }\n },\n [_c(\"span\", [_vm._v(\"Delete RAR contents\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"no_delete\" } },\n [_c(\"span\", [_vm._v(\"Don't delete empty folders\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"span\", [\n _c(\"b\", [_vm._v(\"NOTE:\")]),\n _vm._v(\" Can be overridden using manual Post Processing\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"label\", { staticClass: \"col-sm-2 control-label\" }, [\n _c(\"span\", [_vm._v(\"Extra Scripts\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"component-group-desc col-xs-12 col-md-2\" },\n [\n _c(\"h3\", [_vm._v(\"Episode Naming\")]),\n _vm._v(\" \"),\n _c(\"p\", [_vm._v(\"How Medusa will name and sort your episodes.\")])\n ]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"naming_strip_year\" }\n },\n [_c(\"span\", [_vm._v(\"Strip Show Year\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"component-group-desc col-xs-12 col-md-2\" },\n [\n _c(\"h3\", [_vm._v(\"Metadata\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"The data associated to the data. These are files associated to a TV show in the form of images and text that, when supported, will enhance the viewing experience.\"\n )\n ])\n ]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"metadataType\" } },\n [_c(\"span\", [_vm._v(\"Metadata Type\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"span\", { staticClass: \"d-block\" }, [\n _vm._v(\"Toggle the metadata options that you wish to be created. \"),\n _c(\"b\", [_vm._v(\"Multiple targets may be used.\")])\n ])\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-post-processing.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-post-processing.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./config-post-processing.vue?vue&type=template&id=78fe0fd3&\"\nimport script from \"./config-post-processing.vue?vue&type=script&lang=js&\"\nexport * from \"./config-post-processing.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-post-processing.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"config-post-processing.vue\"\nexport default component.exports","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/*\\n@NOTE: This fixes the header blocking elements when using a hash link\\ne.g. displayShow?indexername=tvdb&seriesid=83462#season-5\\n*/\\n[false-link]::before {\\n content: '';\\n display: block;\\n position: absolute;\\n height: 100px;\\n margin-top: -100px;\\n z-index: -100;\\n}\\n.router-link,\\n.router-link-active {\\n cursor: pointer;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./asset.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./asset.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-template.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-template.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.form-control {\\n color: rgb(0, 0, 0);\\n}\\n.input75 {\\n width: 75px;\\n margin-top: -4px;\\n}\\n.input250 {\\n width: 250px;\\n margin-top: -4px;\\n}\\n.input350 {\\n width: 350px;\\n margin-top: -4px;\\n}\\n.input450 {\\n width: 450px;\\n margin-top: -4px;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.input75 {\\n width: 75px;\\n margin-top: -4px;\\n}\\n.input250 {\\n width: 250px;\\n margin-top: -4px;\\n}\\n.input350 {\\n width: 350px;\\n margin-top: -4px;\\n}\\n.input450 {\\n width: 450px;\\n margin-top: -4px;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.input75 {\\n width: 75px;\\n margin-top: -4px;\\n}\\n.input250 {\\n width: 250px;\\n margin-top: -4px;\\n}\\n.input350 {\\n width: 350px;\\n margin-top: -4px;\\n}\\n.input450 {\\n width: 450px;\\n margin-top: -4px;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=style&index=0&id=5a327762&scoped=true&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=style&index=0&id=5a327762&scoped=true&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\ndiv.file-browser.max-width[data-v-5a327762] {\\n max-width: 450px;\\n}\\ndiv.file-browser .input-group-no-btn[data-v-5a327762] {\\n display: flex;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./language-select.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./language-select.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./name-pattern.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./name-pattern.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.plotInfo {\\n cursor: help;\\n float: right;\\n position: relative;\\n top: 2px;\\n}\\n.plotInfoNone {\\n cursor: help;\\n float: right;\\n position: relative;\\n top: 2px;\\n opacity: 0.4;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=style&index=0&id=b683ee7a&scoped=true&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=style&index=0&id=b683ee7a&scoped=true&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.quality[data-v-b683ee7a] {\\n font: 12px/13px \\\"Open Sans\\\", verdana, sans-serif;\\n background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n background-image: -o-linear-gradient(top, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), inset 0 -1px 3px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 2px rgba(0, 0, 0, 0.15);\\n text-shadow: 0 1px rgba(0, 0, 0, 0.8);\\n color: rgb(255, 255, 255);\\n display: inline-block;\\n padding: 2px 4px;\\n text-align: center;\\n vertical-align: baseline;\\n border-radius: 4px;\\n white-space: nowrap;\\n}\\n.any-hd[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n /* stylelint-disable declaration-block-no-shorthand-property-overrides */\\n background:\\n repeating-linear-gradient(\\n -45deg,\\n rgb(38, 114, 182),\\n rgb(38, 114, 182) 10px,\\n rgb(91, 153, 13) 10px,\\n rgb(91, 153, 13) 20px\\n );\\n /* stylelint-enable */\\n}\\n.Custom[data-v-b683ee7a] {\\n background-color: rgb(98, 25, 147);\\n}\\n.HD[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n}\\n.HDTV[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n}\\n.HD720p[data-v-b683ee7a] {\\n background-color: rgb(91, 153, 13);\\n}\\n.HD1080p[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n}\\n.UHD-4K[data-v-b683ee7a] {\\n background-color: rgb(117, 0, 255);\\n}\\n.UHD-8K[data-v-b683ee7a] {\\n background-color: rgb(65, 0, 119);\\n}\\n.RawHD[data-v-b683ee7a] {\\n background-color: rgb(205, 115, 0);\\n}\\n.RawHDTV[data-v-b683ee7a] {\\n background-color: rgb(205, 115, 0);\\n}\\n.SD[data-v-b683ee7a] {\\n background-color: rgb(190, 38, 37);\\n}\\n.SDTV[data-v-b683ee7a] {\\n background-color: rgb(190, 38, 37);\\n}\\n.SDDVD[data-v-b683ee7a] {\\n background-color: rgb(190, 38, 37);\\n}\\n.Any[data-v-b683ee7a] {\\n background-color: rgb(102, 102, 102);\\n}\\n.Unknown[data-v-b683ee7a] {\\n background-color: rgb(153, 153, 153);\\n}\\n.Proper[data-v-b683ee7a] {\\n background-color: rgb(63, 127, 0);\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.scroll-wrapper {\\n position: fixed;\\n opacity: 0;\\n visibility: hidden;\\n overflow: hidden;\\n text-align: center;\\n font-size: 20px;\\n z-index: 999;\\n background-color: #777;\\n color: #eee;\\n width: 50px;\\n height: 48px;\\n line-height: 48px;\\n right: 30px;\\n bottom: 30px;\\n padding-top: 2px;\\n border-radius: 10px;\\n -webkit-transition: all 0.5s ease-in-out;\\n -moz-transition: all 0.5s ease-in-out;\\n -ms-transition: all 0.5s ease-in-out;\\n -o-transition: all 0.5s ease-in-out;\\n transition: all 0.5s ease-in-out;\\n}\\n.scroll-wrapper.show {\\n visibility: visible;\\n cursor: pointer;\\n opacity: 1;\\n}\\n.scroll-wrapper.left {\\n position: fixed;\\n right: 150px;\\n}\\n.scroll-wrapper.right {\\n position: fixed;\\n right: 90px;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=style&index=0&id=391728a9&scoped=true&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=style&index=0&id=391728a9&scoped=true&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\ndiv.select-list ul[data-v-391728a9] {\\n padding-left: 0;\\n}\\ndiv.select-list li[data-v-391728a9] {\\n list-style-type: none;\\n display: flex;\\n}\\ndiv.select-list .new-item[data-v-391728a9] {\\n display: flex;\\n}\\ndiv.select-list .new-item-help[data-v-391728a9] {\\n font-weight: bold;\\n padding-top: 5px;\\n}\\ndiv.select-list input[data-v-391728a9],\\ndiv.select-list img[data-v-391728a9] {\\n display: inline-block;\\n box-sizing: border-box;\\n}\\ndiv.select-list.max-width[data-v-391728a9] {\\n max-width: 450px;\\n}\\ndiv.select-list .switch-input[data-v-391728a9] {\\n left: -8px;\\n top: 4px;\\n position: absolute;\\n z-index: 10;\\n opacity: 0.6;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\nselect.select-show {\\n display: inline-block;\\n height: 25px;\\n padding: 1px;\\n}\\n.show-selector {\\n height: 31px;\\n display: table-cell;\\n left: 20px;\\n margin-bottom: 5px;\\n}\\n@media (max-width: 767px) and (min-width: 341px) {\\n.select-show-group,\\n .select-show {\\n width: 100%;\\n}\\n}\\n@media (max-width: 340px) {\\n.select-show-group {\\n width: 100%;\\n}\\n}\\n@media (max-width: 767px) {\\n.show-selector {\\n float: left;\\n width: 100%;\\n}\\n.select-show {\\n width: 100%;\\n}\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./state-switch.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./state-switch.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-recommended.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-recommended.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=style&index=0&id=10f4092b&scoped=true&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=style&index=0&id=10f4092b&scoped=true&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\ndiv.anidb-release-group-ui-wrapper[data-v-10f4092b] {\\n clear: both;\\n margin-bottom: 20px;\\n}\\ndiv.anidb-release-group-ui-wrapper ul[data-v-10f4092b] {\\n border-style: solid;\\n border-width: thin;\\n padding: 5px 2px 2px 5px;\\n list-style: none;\\n}\\ndiv.anidb-release-group-ui-wrapper li.active[data-v-10f4092b] {\\n background-color: cornflowerblue;\\n}\\ndiv.anidb-release-group-ui-wrapper div.arrow img[data-v-10f4092b] {\\n cursor: pointer;\\n height: 32px;\\n width: 32px;\\n}\\ndiv.anidb-release-group-ui-wrapper img.deleteFromWhitelist[data-v-10f4092b],\\ndiv.anidb-release-group-ui-wrapper img.deleteFromBlacklist[data-v-10f4092b] {\\n float: right;\\n}\\ndiv.anidb-release-group-ui-wrapper #add-new-release-group p > img[data-v-10f4092b] {\\n height: 16px;\\n width: 16px;\\n background-color: rgb(204, 204, 204);\\n}\\ndiv.anidb-release-group-ui-wrapper.placeholder[data-v-10f4092b] {\\n height: 32px;\\n}\\ndiv.anidb-release-group-ui-wrapper.max-width[data-v-10f4092b] {\\n max-width: 960px;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-show-options.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-show-options.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-shows.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-shows.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.floating-badge {\\n position: absolute;\\n top: -5px;\\n right: -8px;\\n padding: 0 4px;\\n background-color: #777;\\n border: 2px solid #959595;\\n border-radius: 100px;\\n font-size: 12px;\\n font-weight: bold;\\n text-decoration: none;\\n color: white;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./backstretch.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./backstretch.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.infoTable tr td:first-child {\\n vertical-align: top;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-post-processing.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-post-processing.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=style&index=0&id=60f89f30&scoped=true&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=style&index=0&id=60f89f30&scoped=true&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.irc-frame[data-v-60f89f30] {\\n width: 100%;\\n height: 500px;\\n border: 1px #000 solid;\\n}\\n.loading-spinner[data-v-60f89f30] {\\n background-position: center center;\\n background-repeat: no-repeat;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./login.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./login.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manual-post-process.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manual-post-process.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.root-dirs-selectbox,\\n.root-dirs-selectbox select,\\n.root-dirs-controls {\\n width: 100%;\\n max-width: 430px;\\n}\\n.root-dirs-selectbox {\\n padding: 0 0 5px;\\n}\\n.root-dirs-controls {\\n text-align: center;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./snatch-selection.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./snatch-selection.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./status.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./status.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./404.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./404.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///./src/components/anidb-release-group-ui.vue?0ea6","webpack:///src/components/anidb-release-group-ui.vue","webpack:///./src/components/anidb-release-group-ui.vue","webpack:///./src/components/anidb-release-group-ui.vue?c1d7","webpack:///src/components/add-show-options.vue","webpack:///./src/components/add-show-options.vue?75eb","webpack:///./src/components/add-show-options.vue","webpack:///./src/components/add-show-options.vue?adcc","webpack:///./src/components/app-header.vue?e200","webpack:///./src/components/app-header.vue","webpack:///./src/components/app-header.vue?2a72","webpack:///./src/components/backstretch.vue?12be","webpack:///./src/components/backstretch.vue","webpack:///./src/components/backstretch.vue?58f8","webpack:///./src/components/home.vue?3366","webpack:///./src/components/home.vue","webpack:///./src/components/manual-post-process.vue?7c6f","webpack:///./src/components/manual-post-process.vue","webpack:///./src/components/root-dirs.vue?4383","webpack:///./src/components/root-dirs.vue","webpack:///./src/components/root-dirs.vue?b188","webpack:///./src/components/show.vue?04f2","webpack:///./src/components/show.vue","webpack:///./src/components/snatch-selection.vue?a09a","webpack:///./src/components/snatch-selection.vue","webpack:///./src/components/status.vue?6c0c","webpack:///./src/components/status.vue","webpack:///./src/components/index.js","webpack:///./src/api.js","webpack:///./src/components/helpers/app-link.vue?ecce","webpack:///src/components/helpers/app-link.vue","webpack:///./src/components/helpers/app-link.vue?62b8","webpack:///./src/components/helpers/app-link.vue","webpack:///./src/components/helpers/asset.vue?3066","webpack:///src/components/helpers/asset.vue","webpack:///./src/components/helpers/asset.vue","webpack:///./src/components/helpers/asset.vue?8b94","webpack:///./src/components/helpers/config-template.vue?2b56","webpack:///src/components/helpers/config-template.vue","webpack:///./src/components/helpers/config-template.vue","webpack:///./src/components/helpers/config-template.vue?461f","webpack:///./src/components/helpers/config-textbox-number.vue?74e9","webpack:///src/components/helpers/config-textbox-number.vue","webpack:///./src/components/helpers/config-textbox-number.vue","webpack:///./src/components/helpers/config-textbox-number.vue?edd2","webpack:///./src/components/helpers/config-textbox.vue?7539","webpack:///src/components/helpers/config-textbox.vue","webpack:///./src/components/helpers/config-textbox.vue","webpack:///./src/components/helpers/config-textbox.vue?c301","webpack:///./src/components/helpers/config-toggle-slider.vue?bcb1","webpack:///src/components/helpers/config-toggle-slider.vue","webpack:///./src/components/helpers/config-toggle-slider.vue","webpack:///./src/components/helpers/config-toggle-slider.vue?a5af","webpack:///./src/components/helpers/file-browser.vue?7d64","webpack:///./src/components/helpers/file-browser.vue","webpack:///./src/components/helpers/file-browser.vue?d9c9","webpack:///./src/components/helpers/language-select.vue?ed6a","webpack:///./src/components/helpers/language-select.vue","webpack:///./src/components/helpers/language-select.vue?f23b","webpack:///./src/components/helpers/name-pattern.vue?b2bc","webpack:///./src/components/helpers/name-pattern.vue","webpack:///./src/components/helpers/name-pattern.vue?9c2d","webpack:///./src/components/helpers/plot-info.vue?9d72","webpack:///./src/components/helpers/plot-info.vue","webpack:///./src/components/helpers/plot-info.vue?508c","webpack:///src/components/helpers/quality-pill.vue","webpack:///./src/components/helpers/quality-pill.vue?cb0d","webpack:///./src/components/helpers/quality-pill.vue","webpack:///./src/components/helpers/quality-pill.vue?677b","webpack:///./src/components/helpers/scroll-buttons.vue?4a49","webpack:///./src/components/helpers/scroll-buttons.vue","webpack:///./src/components/helpers/scroll-buttons.vue?f23f","webpack:///./src/components/helpers/select-list.vue?3a99","webpack:///src/components/helpers/select-list.vue","webpack:///./src/components/helpers/select-list.vue","webpack:///./src/components/helpers/select-list.vue?b180","webpack:///src/components/helpers/show-selector.vue","webpack:///./src/components/helpers/show-selector.vue?306a","webpack:///./src/components/helpers/show-selector.vue","webpack:///./src/components/helpers/show-selector.vue?e322","webpack:///./src/components/helpers/state-switch.vue?9500","webpack:///src/components/helpers/state-switch.vue","webpack:///./src/components/helpers/state-switch.vue","webpack:///./src/components/helpers/state-switch.vue?8b88","webpack:///./src/components/helpers/index.js","webpack:///./src/utils.js","webpack:///./src/components/show-header.vue?b52c","webpack:///./src/components/show-header.vue?6f87","webpack:///./src/components/show-header.vue","webpack:///./src/router.js","webpack:///./src/components/helpers/app-link.vue?609c","webpack:///./src/components/helpers/config-textbox-number.vue?c110","webpack:///./src/components/helpers/config-textbox.vue?d09a","webpack:///./src/components/helpers/config-toggle-slider.vue?b7c8","webpack:///src/components/helpers/file-browser.vue","webpack:///./src/components/helpers/file-browser.vue?be00","webpack:///src/components/helpers/language-select.vue","webpack:///src/components/helpers/name-pattern.vue","webpack:///src/components/helpers/plot-info.vue","webpack:///./src/components/helpers/plot-info.vue?6acf","webpack:///./src/components/helpers/quality-pill.vue?c100","webpack:///src/components/helpers/scroll-buttons.vue","webpack:///./src/components/helpers/scroll-buttons.vue?9417","webpack:///./src/components/helpers/select-list.vue?00bf","webpack:///./src/components/helpers/show-selector.vue?1e83","webpack:///./src/components/anidb-release-group-ui.vue?d4c6","webpack:///src/components/app-header.vue","webpack:///./src/components/app-header.vue?a433","webpack:///src/components/backstretch.vue","webpack:///./src/components/config.vue?74a6","webpack:///src/components/config-post-processing.vue","webpack:///src/components/home.vue","webpack:///./src/components/irc.vue?d114","webpack:///src/components/manual-post-process.vue","webpack:///src/components/root-dirs.vue","webpack:///./src/components/root-dirs.vue?1571","webpack:///src/components/show.vue","webpack:///src/components/show-header.vue","webpack:///./src/components/show-header.vue?f042","webpack:///src/components/snatch-selection.vue","webpack:///src/components/status.vue","webpack:///./src/store/mutation-types.js","webpack:///./src/store/modules/auth.js","webpack:///./src/store/modules/clients.js","webpack:///./src/store/modules/config.js","webpack:///./src/store/modules/defaults.js","webpack:///./src/store/modules/metadata.js","webpack:///./src/store/modules/notifications.js","webpack:///./src/store/modules/notifiers/boxcar2.js","webpack:///./src/store/modules/notifiers/email.js","webpack:///./src/store/modules/notifiers/emby.js","webpack:///./src/store/modules/notifiers/growl.js","webpack:///./src/store/modules/notifiers/kodi.js","webpack:///./src/store/modules/notifiers/libnotify.js","webpack:///./src/store/modules/notifiers/nmj.js","webpack:///./src/store/modules/notifiers/nmjv2.js","webpack:///./src/store/modules/notifiers/plex.js","webpack:///./src/store/modules/notifiers/prowl.js","webpack:///./src/store/modules/notifiers/pushalot.js","webpack:///./src/store/modules/notifiers/pushbullet.js","webpack:///./src/store/modules/notifiers/join.js","webpack:///./src/store/modules/notifiers/pushover.js","webpack:///./src/store/modules/notifiers/py-tivo.js","webpack:///./src/store/modules/notifiers/slack.js","webpack:///./src/store/modules/notifiers/synology.js","webpack:///./src/store/modules/notifiers/synology-index.js","webpack:///./src/store/modules/notifiers/telegram.js","webpack:///./src/store/modules/notifiers/trakt.js","webpack:///./src/store/modules/notifiers/twitter.js","webpack:///./src/store/modules/notifiers/index.js","webpack:///./src/store/modules/qualities.js","webpack:///./src/store/modules/shows.js","webpack:///./src/store/modules/search.js","webpack:///./src/store/modules/socket.js","webpack:///./src/store/modules/statuses.js","webpack:///./src/store/index.js","webpack:///./src/components/irc.vue?1ae7","webpack:///src/components/irc.vue","webpack:///./src/components/irc.vue?7a24","webpack:///./src/components/irc.vue","webpack:///./src/components/add-recommended.vue?e31e","webpack:///./src/components/add-recommended.vue?2753","webpack:///src/components/add-recommended.vue","webpack:///./src/components/add-recommended.vue","webpack:///./src/components/login.vue?073b","webpack:///./src/components/login.vue?57e6","webpack:///src/components/login.vue","webpack:///./src/components/login.vue","webpack:///./src/components/add-shows.vue?c057","webpack:///./src/components/add-shows.vue?9503","webpack:///src/components/add-shows.vue","webpack:///./src/components/add-shows.vue","webpack:///./src/components/config.vue?1065","webpack:///./src/components/config.vue?df93","webpack:///src/components/config.vue","webpack:///./src/components/config.vue","webpack:///./src/components/http/404.vue?0abf","webpack:///./src/components/http/404.vue?03e7","webpack:///src/components/http/404.vue","webpack:///./src/components/http/404.vue","webpack:///./src/components/config-post-processing.vue?c03b","webpack:///./src/components/config-post-processing.vue?e020","webpack:///./src/components/config-post-processing.vue","webpack:///./src/components/helpers/app-link.vue?b485","webpack:///./src/components/helpers/app-link.vue?216d","webpack:///./src/components/helpers/config-textbox-number.vue?489b","webpack:///./src/components/helpers/config-textbox-number.vue?bd5f","webpack:///./src/components/helpers/config-textbox.vue?93d8","webpack:///./src/components/helpers/config-textbox.vue?abb5","webpack:///./src/components/helpers/config-toggle-slider.vue?2913","webpack:///./src/components/helpers/config-toggle-slider.vue?5b3d","webpack:///./src/components/helpers/file-browser.vue?bd46","webpack:///./src/components/helpers/file-browser.vue?b533","webpack:///./src/components/helpers/plot-info.vue?67cc","webpack:///./src/components/helpers/plot-info.vue?3ca4","webpack:///./src/components/helpers/quality-pill.vue?d417","webpack:///./src/components/helpers/quality-pill.vue?15d1","webpack:///./src/components/helpers/scroll-buttons.vue?4082","webpack:///./src/components/helpers/scroll-buttons.vue?4d17","webpack:///./src/components/helpers/select-list.vue?4f20","webpack:///./src/components/helpers/select-list.vue?e247","webpack:///./src/components/helpers/show-selector.vue?b49a","webpack:///./src/components/helpers/show-selector.vue?f1c0","webpack:///./src/components/anidb-release-group-ui.vue?108b","webpack:///./src/components/anidb-release-group-ui.vue?7506","webpack:///./src/components/app-header.vue?7b5a","webpack:///./src/components/app-header.vue?51b0","webpack:///./src/components/config.vue?b8d8","webpack:///./src/components/config.vue?395f","webpack:///./src/components/irc.vue?ecce","webpack:///./src/components/irc.vue?e7e0","webpack:///./src/components/root-dirs.vue?73c7","webpack:///./src/components/root-dirs.vue?3e09","webpack:///./src/components/show-header.vue?f85b","webpack:///./src/components/show-header.vue?fa1f"],"names":["components_anidb_release_group_uivue_type_script_lang_js_","name","props","blacklist","type","Array","default","whitelist","allGroups","data","index","allReleaseGroups","newGroup","mounted","this","createIndexedObjects","methods","toggleItem","release","map","x","id","toggled","releaseGroups","list","_this","_iteratorNormalCompletion","_didIteratorError","_iteratorError","undefined","_step","_loop","value","itemAsObject","Object","assign","memberOf","filter","group","length","push","_iterator","Symbol","iterator","next","done","err","return","moveToList","_this2","_iteratorNormalCompletion2","_didIteratorError2","_iteratorError2","_step2","_loop2","inList","find","releaseGroup","_iterator2","deleteFromList","computed","itemsWhitelist","itemsBlacklist","itemsReleaseGroups","showDeleteFromWhitelist","showDeleteFromBlacklist","watch","handler","$emit","deep","newValue","anidb_release_group_ui","componentNormalizer","_vm","_h","$createElement","_c","_self","staticClass","_v","attrs","src","on","click","$event","_e","_l","key","class","active","_s","directives","rawName","expression","placeholder","domProps","input","target","composing","_m","components_add_show_optionsvue_type_script_lang_js_","components","AnidbReleaseGroupUi","ConfigToggleSlider","helpers","showName","String","required","enableAnimeOptions","Boolean","saving","selectedStatus","selectedStatusAfter","quality","allowed","preferred","selectedSubtitleEnabled","selectedSeasonFoldersEnabled","selectedAnimeEnabled","selectedSceneEnabled","allgroups","defaultConfig","update","status","statusAfter","$nextTick","$watch","vm","join","getReleaseGroups","params","series_name","api","get","timeout","then","response","catch","error","$snotify","warning","concat","console","warn","_this3","subtitles","seasonFolders","anime","scene","onChangeReleaseGroupsAnime","items","item","saveDefaults","_this4","$store","config","showDefaults","combinedQualities","dispatch","section","success","message","finally","_objectSpread","vuex_esm","state","namingForceFolders","subtitlesEnabled","enabled","episodeStatuses","statuses","defaultEpisodeStatusOptions","_this$episodeStatuses","strings","values","skipped","wanted","ignored","text","utils","saveDefaultsDisabled","every","asyncComputed","result","groups","Promise","resolve","immediate","add_show_options","overall-quality","update:quality:allowed","update:quality:preferred","label","explanations","change","$$selectedVal","prototype","call","options","o","selected","_value","multiple","option","disabled","all-groups","preventDefault","for","components_app_headervue_type_script_lang_js_","app_header","role","data-toggle","data-target","toolsBadgeCount","toolsBadgeClass","href","title","staticStyle","height","alt","topMenu","aria-haspopup","data-hover","recentShows","recentShow","link","clear","linkVisible","news","unread","donationsUrl","logs","numErrors","numWarnings","warningLevel","nativeOn","confirmDialog","components_backstretchvue_type_script_lang_js_","backstretch","components_homevue_type_script_lang_js_","home","home_render","home_staticRenderFns","components_manual_post_processvue_type_script_lang_js_","manual_post_process","manual_post_process_render","manual_post_process_staticRenderFns","components_root_dirsvue_type_script_lang_js_","root_dirs","_g","_b","ref","size","selectedRootDir","$attrs","$listeners","curDir","path","_f","add","edit","remove","setDefault","components_showvue_type_script_lang_js_","show","show_render","show_staticRenderFns","components_snatch_selectionvue_type_script_lang_js_","snatch_selection","snatch_selection_render","snatch_selection_staticRenderFns","components_statusvue_type_script_lang_js_","components_status","status_render","status_staticRenderFns","__webpack_require__","d","__webpack_exports__","webRoot","apiKey","apiRoute","apiv1","axios__WEBPACK_IMPORTED_MODULE_0__","axios__WEBPACK_IMPORTED_MODULE_0___default","n","document","body","getAttribute","axios","create","baseURL","headers","Accept","Content-Type","X-Api-Key","helpers_app_linkvue_type_script_lang_js_","to","indexerId","indexerName","indexers","keys","indexer","parseInt","computedBase","querySelectorAll","computedHref","replace","isIRC","startsWith","isAbsolute","test","isExternal","base","isHashPath","anonymisedHref","anonRedirect","matchingVueRoute","normalise","str","router","routes","_ref","linkProperties","is","_typeof","$route","meta","converted","window","loadMainApp","location","hash","newHash","endsWith","substr","URL","rel","falseLink","app_link","tag","router-link","false-link","_t","helpers_assetvue_type_script_lang_js_","AppLink","showSlug","cls","asset","helpers_config_templatevue_type_script_lang_js_","labelFor","config_template","helpers_config_textbox_numbervue_type_script_lang_js_","Number","inputClass","min","max","step","localValue","updateValue","config_textbox_number","explanation","helpers_config_textboxvue_type_script_lang_js_","config_textbox","checked","isArray","_i","$$a","$$el","$$c","$$i","slice","_q","helpers_config_toggle_slidervue_type_script_lang_js_","ToggleButton","localChecked","config_toggle_slider","width","sync","model","callback","$$v","helpers_file_browservue_type_script_lang_js_","file_browser","showBrowseButton","currentPath","openDialog","display","keyup","indexOf","_k","keyCode","browse","file","mouseover","toggleFolder","mouseout","fileClicked","isFile","font-size","helpers_language_selectvue_type_script_lang_js_","language_select","helpers_name_patternvue_type_script_lang_js_","name_pattern","isEnabled","selectedNamingPattern","updatePatternSamples","preset","pattern","example","padding-top","customName","showLegend","isCustom","getDateFormat","selectedMultiEpStyle","multiEpStyle","namingExample","namingExampleMulti","animeType","colspan","helpers_plot_infovue_type_script_lang_js_","plot_info","plotInfoClass","helpers_quality_pillvue_type_script_lang_js_","validator","showTitle","override","includes","quality_pillvue_type_script_lang_js_objectSpread","qualityValues","qualities","qualityValueStrings","qualityAnySets","anySets","qualityAnySetStrings","qualityPresets","presets","qualityPresetStrings","qualityCssClassStrings","cssClass","splitQuality","curQual","setHDTV","makeQualitySet","setWEBDL","setBluRay","set720p","set1080p","setUHD4K","setUHD8K","pill","sumAllowed","isSubsetOf","anyhdtv","anywebdl","anybluray","hdbluray","fullhdbluray","uhd4kbluray","uhd8kbluray","_toConsumableArray","sort","a","b","reduce","curQuality","_len","arguments","_key","set1","set2","quality_pill","helpers_scroll_buttonsvue_type_script_lang_js_","scroll_buttons","showToTop","scrollTop","showLeftRight","scrollLeft","scrollRight","helpers_select_listvue_type_script_lang_js_","listItems","unique","csvEnabled","editItems","newItem","indexCounter","csv","csvMode","created","unwatchProp","sanitize","addItem","i","addNewItem","deleteItem","e","$refs","newItemInput","focus","removeEmpty","syncValues","split","forEach","trim","switchFields","select_list","$set","helpers_show_selectorvue_type_script_lang_js_","followSelection","selectClass","selectedShowSlug","lock","show_selectorvue_type_script_lang_js_objectSpread","shows","showLists","animeSplitHome","sortArticle","lists","sortKey","toLowerCase","showA","showB","titleA","titleB","whichList","newSlug","selectedShow","slug","showId","show_selector","hidden","curShowList","helpers_state_switchvue_type_script_lang_js_","theme","realState","charAt","toUpperCase","null","true","false","state_switch","combineQualities","humanFileSize","isDevelopment","process","allowedQualities","preferredQualities","reducer","accumulator","currentValue","bytes","useDecimal","thresh","Math","abs","units","u","toFixed","components_show_headervue_type_script_lang_js_","component","data-showname","data-indexer-name","data-series-id","season","episode","manualSearchType","seasons","cursor","toggleSpecials","displaySpecials","position","jumpToSeason","data-season","reverse","$index","queueItem","action","show-slug","rating","imdb","qtip-content","votes","style","country","margin-left","vertical-align","imdbInfo","year","runtimes","runtime","margin-top","start","trakt","showIndexerUrl","indexerConfig","icon","tvdb","dedupeGenres","genres","genre","toString","summaryFanArt","fanartBackground","padding-bottom","clamp","less","plot","toggle","getPreset","network","airs","airsFormatValid","color","defaultEpisodeStatus","location-invalid","locationValid","aliases","requiredWords","ignoredWords","preferredWords","undesiredWords","undesired","airdateOffset","getCountryISO2ToISO3","language","onError","themeName","paused","airByDate","sports","dvdOrder","showHideRows","episodeSummary","Wanted","Allowed","Preferred","Skipped","Snatched","selectEpisodesClicked","clearEpisodeSelectionClicked","changeStatusClicked","vue_router__WEBPACK_IMPORTED_MODULE_0__","header","bind","VueRouter","mode","beforeEach","from","content","module","locals","exports","includeFiles","autocomplete","localStorageKey","initialDir","files","lastPath","url","autocompleteUrl","fileBrowserDialog","localStorageSupport","localStorage","getItem","log","testLocalStorage","fileBrowser","storedPath","locationInput","event","ui","set","newPath","children","classList","$","$el","fileBrowserSearchBox","debug","dialog","_api__WEBPACK_IMPORTED_MODULE_0__","shift","openFileBrowser","fileBrowserFileList","dialogClass","my","at","of","minWidth","maxHeight","maxWidth","modal","autoOpen","removeAttribute","append","resultField","query","collision","source","request","escapeRegex","term","ajax","dataType","matcher","RegExp","grep","open","removeClass","_renderItem","ul","resultItem","fullMatch","appendTo","available","blank","flags","bfhlanguages","evt","currentTarget","val","vue_js_toggle_button__WEBPACK_IMPORTED_MODULE_1__","namingPattern","namingPresets","multiEpStyles","animeNamingType","flagLoaded","availableMultiEpStyles","lastSelectedPattern","format","date_fns_format__WEBPACK_IMPORTED_MODULE_0___default","Date","testNaming","anime_type","multi","_api__WEBPACK_IMPORTED_MODULE_2__","res","checkNaming","isMulti","custom","el","qtip","content.text","style.classes","css","updateCustomName","presetsPatterns","foundPattern","newPattern","oldPattern","hasPlot","qt","statusText","solo","adjust","y","tip","corner","method","classes","scrollTo","animate","dest","offset","top","initHorizontalScroll","scrollDiv","scrollbarVisible","scrollWidth","clientWidth","_helpers__WEBPACK_IMPORTED_MODULE_1__","vuex__WEBPACK_IMPORTED_MODULE_0__","isAuthenticated","auth","username","user","loggingLevels","notifiers","torrents","failedDownloads","postProcessing","kodi","plex","emby","server","host","manageTorrents","subtitleMissed","subtitleMissedPP","postponeIfNoSubs","mouseenter","$target","stop","delay","fadeIn","attr","mouseleave","fadeOut","navigator","maxTouchPoints","confirmButton","cancelButton","post","button","confirm","$element","opacity","_helpers__WEBPACK_IMPORTED_MODULE_2__","FileBrowser","NamePattern","SelectList","processMethods","timezoneOptions","naming","multiEp","enableCustomNamingSports","enableCustomNamingAirByDate","patternSports","patternAirByDate","enableCustomNamingAnime","patternAnime","animeMultiEp","stripYear","showDownloadDir","processAutomatically","processMethod","deleteRarContent","unpack","noDelete","reflinkAvailable","postponeIfSyncFiles","autoPostprocessorFrequency","airdateEpisodes","moveAssociatedFiles","allowedExtensions","addShowsWithoutDir","createMissingShowDirs","renameEpisodes","nfoRename","syncFiles","fileTimestampTimezone","extraScripts","extraScriptsUrl","multiEpStrings","metadataProviders","metadataProviderSelected","onChangeSyncFiles","onChangeAllowedExtensions","onChangeExtraScripts","saveNaming","configLoaded","saveNamingSports","saveNamingAbd","saveNamingAnime","save","metadata","_config$postProcessin","rest","_objectWithoutProperties","getFirstEnabledMetadataProvider","firstEnabledProvider","provider","showMetadata","episodeMetadata","multiEpStringsSelect","k","beforeMount","tabs","config.postProcessing","metadata.metadataProviders","template","_helpers__WEBPACK_IMPORTED_MODULE_3__","layout","page","initializePosterSizeSlider","posterSize","resizePosters","newSize","fontSize","logoWidth","borderRadius","borderWidth","hide","Storage","isNaN","slider","setItem","isotope","trigger","lodash_debounce__WEBPACK_IMPORTED_MODULE_1___default","sortBy","sortAscending","patch","selectedRootIndex","info","reload","imgLazyLoad","LazyLoad","threshold","addEventListener","activate","each","percentage","classToAdd","progressbar","addClass","parent","tablesorter","sortList","textExtraction","0","node","1","3","prop","4","5","6","7","8","10","widgets","sorter","2","widgetOptions","filter_columnFilters","filter_hideFilters","filter_saveFilters","filter_functions","f","pct","floor","match","parseFloat","isFinite","columnSelector_mediaquery","sortStable","sortAppend","handleScroll","imagesLoaded","itemSelector","MEDUSA","posterSortby","posterSortdir","layoutMode","masonry","isFitWidth","getSortData","itemElem","date","POSITIVE_INFINITY","progress","NEGATIVE_INFINITY","posterHoverTimer","poster","setTimeout","popup","clone","origLeft","left","origTop","margin","zIndex","newTop","newLeft","scrollBottom","innerHeight","innerWidth","clearTimeout","popover","placement","html","columnSelector","attachTo","rootDir","rootDirs","rootDirIndex","backendDirs","rootDirOptions","sortable","axis","scroll","tolerance","helper","handle","cancel","draggedItem","originalPosition","prependTo","showListOrder","toArray","once","inheritAttrs","rawRootDirs","transformRaw","paths","rd","selectedDir","newRootDir","defaultRootDir","defaultDir","filters","markDefault","saveRootDirs","nFileBrowser","found","isFirst","wasDefault","accumlator","isNewRootDir","oldDirIndex","findIndex","oldDirPath","filteredRootDirs","newSelected","defaultIndex","splice","oldValue","JSON","stringify","PlotInfo","ShowHeader","_show_header_vue__WEBPACK_IMPORTED_MODULE_3__","metaInfo","titleTemplate","showIndexer","getShowById","indexername","seriesid","getShow","setEpisodeSceneNumbering","setAbsoluteSceneNumbering","setInputValidInvalid","getSeasonSceneExceptions","commit","detailed","reflowLayout","ajaxEpSearch","colorRow","startAjaxEpisodeSubtitles","ajaxEpSubtitlesSearch","ajaxEpRedownloadSubtitle","seasCheck","seasNo","collapse","seasonIdentifier","element","lastCheck","shiftKey","check","tableRow","forSeason","forEpisode","m","onlyEpisode","sceneSeason","sceneEpisode","isValid","forAbsolute","sceneAbsolute","columnSelector_saveColumns","columnSelector_layout","columnSelector_cssChecked","exec","moveSummaryBackground","movecheckboxControlsBackground","attachImdbTooltip","seriesId","getJSON","errorMessage","alert","valid","background-color","font-weight","_api__WEBPACK_IMPORTED_MODULE_1__","setSeasonSceneExceptions","seasonExceptions","nameExceptions","foundInXem","xemNumbering","indexerSeason","xemSeason","_helpers__WEBPACK_IMPORTED_MODULE_7__","Asset","QualityPill","StateSwitch","Truncate","vue_truncate_collapsed__WEBPACK_IMPORTED_MODULE_0__","showSeason","showEpisode","vuex__WEBPACK_IMPORTED_MODULE_4__","specials","search","indexerUrl","showUrl","activeShowQueueStatuses","showQueueStatus","showGenres","summary","Unaired","Snatched (Proper)","Snatched (Best)","Unset","Archived","episodes","changeStatusOptions","defaultOptions","changeQualityOptions","_utils__WEBPACK_IMPORTED_MODULE_6__","setQuality","patchData","_api__WEBPACK_IMPORTED_MODULE_5__","epArr","whichClass","numRows","seasonNo","is_visible__WEBPACK_IMPORTED_MODULE_2__","array","Set","country_language__WEBPACK_IMPORTED_MODULE_1__","iso639_2en","vue_scrollto__WEBPACK_IMPORTED_MODULE_3__","container","easing","_show_header_vue__WEBPACK_IMPORTED_MODULE_2__","updateSpinner","showSpinner","spinner","themeSpinner","empty","checkCacheUpdates","repeat","pollInterval","checkIsTrue","urlParams","isNumeric","contentType","removeAttr","complete","timeago","fn","loadContainer","loadingTxt","errorTxt","load","forceSearch","manual_search_type","perform_search","9","11","parser","hasClass","switchClass","ADD_CONFIG","ADD_SHOW","tokens","access","refresh","mutations","_defineProperty","_mutations","getters","actions","login","context","credentials","apiLogin","logout","clients","authType","dir","highBandwidth","labelAnime","rpcUrl","seedLocation","seedTime","password","verifySSL","testStatus","nzb","nzbget","category","categoryAnime","categoryAnimeBacklog","categoryBacklog","priority","useHttps","sabnzbd","forced","modules_config","wikiUrl","localUser","locale","cacheDir","databaseVersion","major","minor","programDir","dataDir","animeSplitHomeInTabs","rpcurl","allSeasons","history","schedule","dbPath","configFile","trimZero","gitUsername","branch","commitHash","main","externalMappings","statusMap","traktIndexers","validLanguages","langabbvToId","apiParams","useZip","baseUrl","identifier","mappedTo","scene_loc","xemOrigin","tmdb","tvmaze","sourceUrl","fanartBackgroundOpacity","appArgs","comingEpsDisplayPaused","timePreset","fuzzyDating","backlogOverview","period","lastRead","latest","deleteFailed","sslVersion","pythonVersion","comingEpsSort","githubUrl","datePreset","subtitlesMulti","pid","os","logDir","config_defineProperty","getConfig","sections","setConfig","_ref2","updateConfig","_ref3","setLayout","_ref4","defaults","akas","cache","classification","requiredWordsExclude","ignoredWordsExclude","countries","certificates","countryCodes","imdbId","imdbInfoId","lastUpdate","nextAirDate","showType","metadata_defineProperty","notifications","notifications_defineProperty","notifications_mutations","enable","disable","displayNotification","boxcar2","notifyOnSnatch","notifyOnDownload","notifyOnSubtitleDownload","accessToken","email","port","tls","addressList","subject","growl","alwaysOn","libraryCleanPending","cleanLibrary","library","full","onlyFirst","libnotify","nmj","database","mount","nmjv2","dbloc","client","updateLibrary","https","token","prowl","messageTitle","pushalot","authToken","pushbullet","device","pushover","userKey","sound","py_tivo","shareName","slack","webhook","synology","synology_index","telegram","pinUrl","defaultIndexer","syncRemove","syncWatchlist","methodAdd","removeWatchlist","removeSerieslist","removeShowFromApplication","startPaused","blacklistName","twitter","dmto","prefix","directMessage","notifiers_defineProperty","modules","pyTivo","synologyIndex","qualities_defineProperty","modules_shows","currentShow","shows_defineProperty","shows_mutations","existingShow","newShow","Vue","getShowByTitle","getSeason","getEpisode","_ref5","getCurrentShow","rootState","_ref6","fetch","reject","getShows","limit","totalPages","pageRequests","newPage","all","ignoreUnknownSubs","ignoredSubsList","general","minDailySearchFrequency","minBacklogFrequency","dailySearchFrequency","checkPropersInterval","usenetRetention","maxCacheAge","backlogDays","torrentCheckerFrequency","backlogFrequency","cacheTrimming","downloadPropers","useFailedDownloads","minTorrentCheckerFrequency","removeFromClient","randomizeProviders","propersSearchDays","allowHighPriority","trackersList","search_defineProperty","socket","isConnected","messages","reconnectError","socket_defineProperty","socket_mutations","existingMessage","count","statuses_defineProperty","Store","Vuex","use","_window$location","protocol","proto","store","websocketUrl","VueNativeSock","reconnection","reconnectionAttempts","reconnectionDelay","passToStoreHandler","eventName","eventData","parse","SOCKET_ONOPEN","SOCKET_ONCLOSE","SOCKET_ONERROR","SOCKET_ONMESSAGE","SOCKET_RECONNECT","SOCKET_RECONNECT_ERROR","components_ircvue_type_script_lang_js_","frameSrc","components_add_recommendedvue_type_script_lang_js_","components_loginvue_type_script_lang_js_","components_add_showsvue_type_script_lang_js_","components_configvue_type_script_lang_js_","prettyPrintJSON","cellspacing","border","cellpadding","runsInDocker","http_404vue_type_script_lang_js_","components_config_post_processingvue_type_script_lang_js_","submit","initial-dir","modifiers","number","_n","blur","$forceUpdate","csv-enabled","list-items","naming-pattern","naming-presets","multi-ep-style","multi-ep-styles","flag-loaded","enabled-naming-custom","anime-naming-type","fanart","banner","episodeThumbnails","seasonPosters","seasonBanners","seasonAllPoster","seasonAllBanner","innerHTML","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_app_link_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_config_textbox_number_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_config_textbox_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_config_toggle_slider_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_file_browser_vue_vue_type_style_index_0_id_5a327762_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_plot_info_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_quality_pill_vue_vue_type_style_index_0_id_b683ee7a_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_scroll_buttons_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_select_list_vue_vue_type_style_index_0_id_ac609192_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_show_selector_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_anidb_release_group_ui_vue_vue_type_style_index_0_id_10f4092b_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_app_header_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_config_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_irc_vue_vue_type_style_index_0_id_60f89f30_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_root_dirs_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_show_header_vue_vue_type_style_index_0_id_e712fe74_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__"],"mappings":"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","file":"js/medusa-runtime.js","sourcesContent":["import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./anidb-release-group-ui.vue?vue&type=template&id=10f4092b&scoped=true&\"\nimport script from \"./anidb-release-group-ui.vue?vue&type=script&lang=js&\"\nexport * from \"./anidb-release-group-ui.vue?vue&type=script&lang=js&\"\nimport style0 from \"./anidb-release-group-ui.vue?vue&type=style&index=0&id=10f4092b&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"10f4092b\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"anidb-release-group-ui-wrapper top-10 max-width\"},[_c('div',{staticClass:\"row\"},[_c('div',{staticClass:\"col-sm-4 left-whitelist\"},[_c('span',[_vm._v(\"Whitelist\")]),(_vm.showDeleteFromWhitelist)?_c('img',{staticClass:\"deleteFromWhitelist\",attrs:{\"src\":\"images/no16.png\"},on:{\"click\":function($event){return _vm.deleteFromList('whitelist')}}}):_vm._e(),_vm._v(\" \"),_c('ul',[_vm._l((_vm.itemsWhitelist),function(release){return _c('li',{key:release.id,class:{active: release.toggled},on:{\"click\":function($event){release.toggled = !release.toggled}}},[_vm._v(_vm._s(release.name))])}),_vm._v(\" \"),_c('div',{staticClass:\"arrow\",on:{\"click\":function($event){return _vm.moveToList('whitelist')}}},[_c('img',{attrs:{\"src\":\"images/curved-arrow-left.png\"}})])],2)]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-4 center-available\"},[_c('span',[_vm._v(\"Release groups\")]),_vm._v(\" \"),_c('ul',[_vm._l((_vm.itemsReleaseGroups),function(release){return _c('li',{key:release.id,staticClass:\"initial\",class:{active: release.toggled},on:{\"click\":function($event){release.toggled = !release.toggled}}},[_vm._v(_vm._s(release.name))])}),_vm._v(\" \"),_c('div',{staticClass:\"arrow\",on:{\"click\":function($event){return _vm.moveToList('releasegroups')}}},[_c('img',{attrs:{\"src\":\"images/curved-arrow-left.png\"}})])],2)]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-4 right-blacklist\"},[_c('span',[_vm._v(\"Blacklist\")]),(_vm.showDeleteFromBlacklist)?_c('img',{staticClass:\"deleteFromBlacklist\",attrs:{\"src\":\"images/no16.png\"},on:{\"click\":function($event){return _vm.deleteFromList('blacklist')}}}):_vm._e(),_vm._v(\" \"),_c('ul',[_vm._l((_vm.itemsBlacklist),function(release){return _c('li',{key:release.id,class:{active: release.toggled},on:{\"click\":function($event){release.toggled = !release.toggled}}},[_vm._v(_vm._s(release.name))])}),_vm._v(\" \"),_c('div',{staticClass:\"arrow\",on:{\"click\":function($event){return _vm.moveToList('blacklist')}}},[_c('img',{attrs:{\"src\":\"images/curved-arrow-left.png\"}})])],2)])]),_vm._v(\" \"),_c('div',{staticClass:\"row\",attrs:{\"id\":\"add-new-release-group\"}},[_c('div',{staticClass:\"col-md-4\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.newGroup),expression:\"newGroup\"}],staticClass:\"form-control input-sm\",attrs:{\"type\":\"text\",\"placeholder\":\"add custom group\"},domProps:{\"value\":(_vm.newGroup)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.newGroup=$event.target.value}}})]),_vm._v(\" \"),_vm._m(0)])])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"col-md-8\"},[_c('p',[_vm._v(\"Use the input to add custom whitelist / blacklist release groups. Click on the \"),_c('img',{attrs:{\"src\":\"images/curved-arrow-left.png\"}}),_vm._v(\" to add it to the correct list.\")])])}]\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-show-options.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-show-options.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./add-show-options.vue?vue&type=template&id=36c5afdc&\"\nimport script from \"./add-show-options.vue?vue&type=script&lang=js&\"\nexport * from \"./add-show-options.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"add-show-options-content\"}},[_c('fieldset',{staticClass:\"component-group-list\"},[_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_vm._m(0),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('quality-chooser',{attrs:{\"overall-quality\":_vm.defaultConfig.quality},on:{\"update:quality:allowed\":function($event){_vm.quality.allowed = $event},\"update:quality:preferred\":function($event){_vm.quality.preferred = $event}}})],1)])]),_vm._v(\" \"),(_vm.subtitlesEnabled)?_c('div',{attrs:{\"id\":\"use-subtitles\"}},[_c('config-toggle-slider',{attrs:{\"label\":\"Subtitles\",\"id\":\"subtitles\",\"value\":_vm.selectedSubtitleEnabled,\"explanations\":['Download subtitles for this show?']},on:{\"input\":function($event){_vm.selectedSubtitleEnabled = $event}}})],1):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_vm._m(1),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.selectedStatus),expression:\"selectedStatus\"}],staticClass:\"form-control form-control-inline input-sm\",attrs:{\"id\":\"defaultStatus\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.selectedStatus=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},_vm._l((_vm.defaultEpisodeStatusOptions),function(option){return _c('option',{key:option.value,domProps:{\"value\":option.value}},[_vm._v(_vm._s(option.text))])}),0)])])]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_vm._m(2),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.selectedStatusAfter),expression:\"selectedStatusAfter\"}],staticClass:\"form-control form-control-inline input-sm\",attrs:{\"id\":\"defaultStatusAfter\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.selectedStatusAfter=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},_vm._l((_vm.defaultEpisodeStatusOptions),function(option){return _c('option',{key:option.value,domProps:{\"value\":option.value}},[_vm._v(_vm._s(option.text))])}),0)])])]),_vm._v(\" \"),_c('config-toggle-slider',{attrs:{\"label\":\"Season Folders\",\"id\":\"season_folders\",\"value\":_vm.selectedSeasonFoldersEnabled,\"disabled\":_vm.namingForceFolders,\"explanations\":['Group episodes by season folders?']},on:{\"input\":function($event){_vm.selectedSeasonFoldersEnabled = $event}}}),_vm._v(\" \"),(_vm.enableAnimeOptions)?_c('config-toggle-slider',{attrs:{\"label\":\"Anime\",\"id\":\"anime\",\"explanations\":['Is this show an Anime?'],\"value\":_vm.selectedAnimeEnabled},on:{\"input\":function($event){_vm.selectedAnimeEnabled = $event}}}):_vm._e(),_vm._v(\" \"),(_vm.enableAnimeOptions && _vm.selectedAnimeEnabled)?_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_vm._m(3),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('anidb-release-group-ui',{staticClass:\"max-width\",attrs:{\"blacklist\":_vm.release.blacklist,\"whitelist\":_vm.release.whitelist,\"all-groups\":_vm.release.allgroups},on:{\"change\":_vm.onChangeReleaseGroupsAnime}})],1)])]):_vm._e(),_vm._v(\" \"),_c('config-toggle-slider',{attrs:{\"label\":\"Scene Numbering\",\"id\":\"scene\",\"value\":_vm.selectedSceneEnabled,\"explanations\":['Is this show scene numbered?']},on:{\"input\":function($event){_vm.selectedSceneEnabled = $event}}}),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_vm._m(4),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('button',{staticClass:\"btn-medusa btn-inline\",attrs:{\"type\":\"button\",\"disabled\":_vm.saving || _vm.saveDefaultsDisabled},on:{\"click\":function($event){$event.preventDefault();return _vm.saveDefaults($event)}}},[_vm._v(\"Save Defaults\")])])])])],1)])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"customQuality\"}},[_c('span',[_vm._v(\"Quality\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"defaultStatus\"}},[_c('span',[_vm._v(\"Status for previously aired episodes\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"defaultStatusAfter\"}},[_c('span',[_vm._v(\"Status for all future episodes\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"anidbReleaseGroup\"}},[_c('span',[_vm._v(\"Release Groups\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"saveDefaultsButton\"}},[_c('span',[_vm._v(\"Use current values as the defaults\")])])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./app-header.vue?vue&type=template&id=33b81de2&\"\nimport script from \"./app-header.vue?vue&type=script&lang=js&\"\nexport * from \"./app-header.vue?vue&type=script&lang=js&\"\nimport style0 from \"./app-header.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('nav',{staticClass:\"navbar navbar-default navbar-fixed-top hidden-print\",attrs:{\"role\":\"navigation\"}},[_c('div',{staticClass:\"container-fluid\"},[_c('div',{staticClass:\"navbar-header\"},[_c('button',{staticClass:\"navbar-toggle collapsed\",attrs:{\"type\":\"button\",\"data-toggle\":\"collapse\",\"data-target\":\"#main_nav\"}},[(_vm.toolsBadgeCount > 0)?_c('span',{class:(\"floating-badge\" + _vm.toolsBadgeClass)},[_vm._v(_vm._s(_vm.toolsBadgeCount))]):_vm._e(),_vm._v(\" \"),_c('span',{staticClass:\"sr-only\"},[_vm._v(\"Toggle navigation\")]),_vm._v(\" \"),_c('span',{staticClass:\"icon-bar\"}),_vm._v(\" \"),_c('span',{staticClass:\"icon-bar\"}),_vm._v(\" \"),_c('span',{staticClass:\"icon-bar\"})]),_vm._v(\" \"),_c('app-link',{staticClass:\"navbar-brand\",attrs:{\"href\":\"home/\",\"title\":\"Medusa\"}},[_c('img',{staticClass:\"img-responsive pull-left\",staticStyle:{\"height\":\"50px\"},attrs:{\"alt\":\"Medusa\",\"src\":\"images/medusa.png\"}})])],1),_vm._v(\" \"),(_vm.isAuthenticated)?_c('div',{staticClass:\"collapse navbar-collapse\",attrs:{\"id\":\"main_nav\"}},[_c('ul',{staticClass:\"nav navbar-nav navbar-right\"},[_c('li',{staticClass:\"navbar-split dropdown\",class:{ active: _vm.topMenu === 'home' },attrs:{\"id\":\"NAVhome\"}},[_c('app-link',{staticClass:\"dropdown-toggle\",attrs:{\"href\":\"home/\",\"aria-haspopup\":\"true\",\"data-toggle\":\"dropdown\",\"data-hover\":\"dropdown\"}},[_c('span',[_vm._v(\"Shows\")]),_vm._v(\" \"),_c('b',{staticClass:\"caret\"})]),_vm._v(\" \"),_c('ul',{staticClass:\"dropdown-menu\"},[_c('li',[_c('app-link',{attrs:{\"href\":\"home/\"}},[_c('i',{staticClass:\"menu-icon-home\"}),_vm._v(\" Show List\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"addShows/\"}},[_c('i',{staticClass:\"menu-icon-addshow\"}),_vm._v(\" Add Shows\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"addRecommended/\"}},[_c('i',{staticClass:\"menu-icon-addshow\"}),_vm._v(\" Add Recommended Shows\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"home/postprocess/\"}},[_c('i',{staticClass:\"menu-icon-postprocess\"}),_vm._v(\" Manual Post-Processing\")])],1),_vm._v(\" \"),(_vm.recentShows.length > 0)?[_c('li',{staticClass:\"divider\",attrs:{\"role\":\"separator\"}}),_vm._v(\" \"),_vm._l((_vm.recentShows),function(recentShow){return _c('li',{key:recentShow.link},[_c('app-link',{attrs:{\"href\":recentShow.link}},[_c('i',{staticClass:\"menu-icon-addshow\"}),_vm._v(\" \"+_vm._s(recentShow.name)+\"\\n \")])],1)})]:_vm._e()],2),_vm._v(\" \"),_c('div',{staticStyle:{\"clear\":\"both\"}})],1),_vm._v(\" \"),_c('li',{class:{ active: _vm.topMenu === 'schedule' },attrs:{\"id\":\"NAVschedule\"}},[_c('app-link',{attrs:{\"href\":\"schedule/\"}},[_vm._v(\"Schedule\")])],1),_vm._v(\" \"),_c('li',{class:{ active: _vm.topMenu === 'history' },attrs:{\"id\":\"NAVhistory\"}},[_c('app-link',{attrs:{\"href\":\"history/\"}},[_vm._v(\"History\")])],1),_vm._v(\" \"),_c('li',{staticClass:\"navbar-split dropdown\",class:{ active: _vm.topMenu === 'manage' },attrs:{\"id\":\"NAVmanage\"}},[_c('app-link',{staticClass:\"dropdown-toggle\",attrs:{\"href\":\"manage/episodeStatuses/\",\"aria-haspopup\":\"true\",\"data-toggle\":\"dropdown\",\"data-hover\":\"dropdown\"}},[_c('span',[_vm._v(\"Manage\")]),_vm._v(\" \"),_c('b',{staticClass:\"caret\"})]),_vm._v(\" \"),_c('ul',{staticClass:\"dropdown-menu\"},[_c('li',[_c('app-link',{attrs:{\"href\":\"manage/\"}},[_c('i',{staticClass:\"menu-icon-manage\"}),_vm._v(\" Mass Update\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"manage/backlogOverview/\"}},[_c('i',{staticClass:\"menu-icon-backlog-view\"}),_vm._v(\" Backlog Overview\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"manage/manageSearches/\"}},[_c('i',{staticClass:\"menu-icon-manage-searches\"}),_vm._v(\" Manage Searches\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"manage/episodeStatuses/\"}},[_c('i',{staticClass:\"menu-icon-manage2\"}),_vm._v(\" Episode Status Management\")])],1),_vm._v(\" \"),(_vm.linkVisible.plex)?_c('li',[_c('app-link',{attrs:{\"href\":\"home/updatePLEX/\"}},[_c('i',{staticClass:\"menu-icon-plex\"}),_vm._v(\" Update PLEX\")])],1):_vm._e(),_vm._v(\" \"),(_vm.linkVisible.kodi)?_c('li',[_c('app-link',{attrs:{\"href\":\"home/updateKODI/\"}},[_c('i',{staticClass:\"menu-icon-kodi\"}),_vm._v(\" Update KODI\")])],1):_vm._e(),_vm._v(\" \"),(_vm.linkVisible.emby)?_c('li',[_c('app-link',{attrs:{\"href\":\"home/updateEMBY/\"}},[_c('i',{staticClass:\"menu-icon-emby\"}),_vm._v(\" Update Emby\")])],1):_vm._e(),_vm._v(\" \"),(_vm.linkVisible.manageTorrents)?_c('li',[_c('app-link',{attrs:{\"href\":\"manage/manageTorrents/\",\"target\":\"_blank\"}},[_c('i',{staticClass:\"menu-icon-bittorrent\"}),_vm._v(\" Manage Torrents\")])],1):_vm._e(),_vm._v(\" \"),(_vm.linkVisible.failedDownloads)?_c('li',[_c('app-link',{attrs:{\"href\":\"manage/failedDownloads/\"}},[_c('i',{staticClass:\"menu-icon-failed-download\"}),_vm._v(\" Failed Downloads\")])],1):_vm._e(),_vm._v(\" \"),(_vm.linkVisible.subtitleMissed)?_c('li',[_c('app-link',{attrs:{\"href\":\"manage/subtitleMissed/\"}},[_c('i',{staticClass:\"menu-icon-backlog\"}),_vm._v(\" Missed Subtitle Management\")])],1):_vm._e(),_vm._v(\" \"),(_vm.linkVisible.subtitleMissedPP)?_c('li',[_c('app-link',{attrs:{\"href\":\"manage/subtitleMissedPP/\"}},[_c('i',{staticClass:\"menu-icon-backlog\"}),_vm._v(\" Missed Subtitle in Post-Process folder\")])],1):_vm._e()]),_vm._v(\" \"),_c('div',{staticStyle:{\"clear\":\"both\"}})],1),_vm._v(\" \"),_c('li',{staticClass:\"navbar-split dropdown\",class:{ active: _vm.topMenu === 'config' },attrs:{\"id\":\"NAVconfig\"}},[_c('app-link',{staticClass:\"dropdown-toggle\",attrs:{\"href\":\"config/\",\"aria-haspopup\":\"true\",\"data-toggle\":\"dropdown\",\"data-hover\":\"dropdown\"}},[_c('span',{staticClass:\"visible-xs-inline\"},[_vm._v(\"Config\")]),_c('img',{staticClass:\"navbaricon hidden-xs\",attrs:{\"src\":\"images/menu/system18.png\"}}),_vm._v(\" \"),_c('b',{staticClass:\"caret\"})]),_vm._v(\" \"),_c('ul',{staticClass:\"dropdown-menu\"},[_c('li',[_c('app-link',{attrs:{\"href\":\"config/\"}},[_c('i',{staticClass:\"menu-icon-help\"}),_vm._v(\" Help & Info\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/general/\"}},[_c('i',{staticClass:\"menu-icon-config\"}),_vm._v(\" General\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/backuprestore/\"}},[_c('i',{staticClass:\"menu-icon-backup\"}),_vm._v(\" Backup & Restore\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/search/\"}},[_c('i',{staticClass:\"menu-icon-manage-searches\"}),_vm._v(\" Search Settings\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/providers/\"}},[_c('i',{staticClass:\"menu-icon-provider\"}),_vm._v(\" Search Providers\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/subtitles/\"}},[_c('i',{staticClass:\"menu-icon-backlog\"}),_vm._v(\" Subtitles Settings\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/postProcessing/\"}},[_c('i',{staticClass:\"menu-icon-postprocess\"}),_vm._v(\" Post Processing\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/notifications/\"}},[_c('i',{staticClass:\"menu-icon-notification\"}),_vm._v(\" Notifications\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/anime/\"}},[_c('i',{staticClass:\"menu-icon-anime\"}),_vm._v(\" Anime\")])],1)]),_vm._v(\" \"),_c('div',{staticStyle:{\"clear\":\"both\"}})],1),_vm._v(\" \"),_c('li',{staticClass:\"navbar-split dropdown\",class:{ active: _vm.topMenu === 'system' },attrs:{\"id\":\"NAVsystem\"}},[_c('app-link',{staticClass:\"padding-right-15 dropdown-toggle\",attrs:{\"href\":\"home/status/\",\"aria-haspopup\":\"true\",\"data-toggle\":\"dropdown\",\"data-hover\":\"dropdown\"}},[_c('span',{staticClass:\"visible-xs-inline\"},[_vm._v(\"Tools\")]),_c('img',{staticClass:\"navbaricon hidden-xs\",attrs:{\"src\":\"images/menu/system18-2.png\"}}),_vm._v(\" \"),(_vm.toolsBadgeCount > 0)?_c('span',{class:(\"badge\" + _vm.toolsBadgeClass)},[_vm._v(_vm._s(_vm.toolsBadgeCount))]):_vm._e(),_vm._v(\" \"),_c('b',{staticClass:\"caret\"})]),_vm._v(\" \"),_c('ul',{staticClass:\"dropdown-menu\"},[_c('li',[_c('app-link',{attrs:{\"href\":\"news/\"}},[_c('i',{staticClass:\"menu-icon-news\"}),_vm._v(\" News \"),(_vm.config.news.unread > 0)?_c('span',{staticClass:\"badge\"},[_vm._v(_vm._s(_vm.config.news.unread))]):_vm._e()])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"IRC/\"}},[_c('i',{staticClass:\"menu-icon-irc\"}),_vm._v(\" IRC\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"changes/\"}},[_c('i',{staticClass:\"menu-icon-changelog\"}),_vm._v(\" Changelog\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":_vm.config.donationsUrl}},[_c('i',{staticClass:\"menu-icon-support\"}),_vm._v(\" Support Medusa\")])],1),_vm._v(\" \"),_c('li',{staticClass:\"divider\",attrs:{\"role\":\"separator\"}}),_vm._v(\" \"),(_vm.config.logs.numErrors > 0)?_c('li',[_c('app-link',{attrs:{\"href\":\"errorlogs/\"}},[_c('i',{staticClass:\"menu-icon-error\"}),_vm._v(\" View Errors \"),_c('span',{staticClass:\"badge btn-danger\"},[_vm._v(_vm._s(_vm.config.logs.numErrors))])])],1):_vm._e(),_vm._v(\" \"),(_vm.config.logs.numWarnings > 0)?_c('li',[_c('app-link',{attrs:{\"href\":(\"errorlogs/?level=\" + _vm.warningLevel)}},[_c('i',{staticClass:\"menu-icon-viewlog-errors\"}),_vm._v(\" View Warnings \"),_c('span',{staticClass:\"badge btn-warning\"},[_vm._v(_vm._s(_vm.config.logs.numWarnings))])])],1):_vm._e(),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"errorlogs/viewlog/\"}},[_c('i',{staticClass:\"menu-icon-viewlog\"}),_vm._v(\" View Log\")])],1),_vm._v(\" \"),_c('li',{staticClass:\"divider\",attrs:{\"role\":\"separator\"}}),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":(\"home/updateCheck?pid=\" + (_vm.config.pid))}},[_c('i',{staticClass:\"menu-icon-update\"}),_vm._v(\" Check For Updates\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":(\"home/restart/?pid=\" + (_vm.config.pid))},nativeOn:{\"click\":function($event){$event.preventDefault();return _vm.confirmDialog($event, 'restart')}}},[_c('i',{staticClass:\"menu-icon-restart\"}),_vm._v(\" Restart\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":(\"home/shutdown/?pid=\" + (_vm.config.pid))},nativeOn:{\"click\":function($event){$event.preventDefault();return _vm.confirmDialog($event, 'shutdown')}}},[_c('i',{staticClass:\"menu-icon-shutdown\"}),_vm._v(\" Shutdown\")])],1),_vm._v(\" \"),(_vm.username)?_c('li',[_c('app-link',{attrs:{\"href\":\"logout\"},nativeOn:{\"click\":function($event){$event.preventDefault();return _vm.confirmDialog($event, 'logout')}}},[_c('i',{staticClass:\"menu-icon-shutdown\"}),_vm._v(\" Logout\")])],1):_vm._e(),_vm._v(\" \"),_c('li',{staticClass:\"divider\",attrs:{\"role\":\"separator\"}}),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"home/status/\"}},[_c('i',{staticClass:\"menu-icon-info\"}),_vm._v(\" Server Status\")])],1)]),_vm._v(\" \"),_c('div',{staticStyle:{\"clear\":\"both\"}})],1)])]):_vm._e()])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./backstretch.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./backstretch.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./backstretch.vue?vue&type=template&id=27a98ad8&\"\nimport script from \"./backstretch.vue?vue&type=script&lang=js&\"\nexport * from \"./backstretch.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div')}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./home.vue?vue&type=script&lang=js&\"\nexport * from \"./home.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manual-post-process.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manual-post-process.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./manual-post-process.vue?vue&type=script&lang=js&\"\nexport * from \"./manual-post-process.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./root-dirs.vue?vue&type=template&id=76f972d6&\"\nimport script from \"./root-dirs.vue?vue&type=script&lang=js&\"\nexport * from \"./root-dirs.vue?vue&type=script&lang=js&\"\nimport style0 from \"./root-dirs.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"root-dirs-wrapper\"}},[_c('div',{staticClass:\"root-dirs-selectbox\"},[_c('select',_vm._g(_vm._b({directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.selectedRootDir),expression:\"selectedRootDir\"}],ref:\"rootDirs\",attrs:{\"name\":\"rootDir\",\"id\":\"rootDirs\",\"size\":\"6\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.selectedRootDir=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},'select',_vm.$attrs,false),_vm.$listeners),_vm._l((_vm.rootDirs),function(curDir){return _c('option',{key:curDir.path,domProps:{\"value\":curDir.path}},[_vm._v(\"\\n \"+_vm._s(_vm._f(\"markDefault\")(curDir))+\"\\n \")])}),0)]),_vm._v(\" \"),_c('div',{staticClass:\"root-dirs-controls\"},[_c('button',{staticClass:\"btn-medusa\",attrs:{\"type\":\"button\"},on:{\"click\":function($event){$event.preventDefault();return _vm.add($event)}}},[_vm._v(\"New\")]),_vm._v(\" \"),_c('button',{staticClass:\"btn-medusa\",attrs:{\"type\":\"button\",\"disabled\":!_vm.selectedRootDir},on:{\"click\":function($event){$event.preventDefault();return _vm.edit($event)}}},[_vm._v(\"Edit\")]),_vm._v(\" \"),_c('button',{staticClass:\"btn-medusa\",attrs:{\"type\":\"button\",\"disabled\":!_vm.selectedRootDir},on:{\"click\":function($event){$event.preventDefault();return _vm.remove($event)}}},[_vm._v(\"Delete\")]),_vm._v(\" \"),_c('button',{staticClass:\"btn-medusa\",attrs:{\"type\":\"button\",\"disabled\":!_vm.selectedRootDir},on:{\"click\":function($event){$event.preventDefault();return _vm.setDefault($event)}}},[_vm._v(\"Set as Default *\")])])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./show.vue?vue&type=script&lang=js&\"\nexport * from \"./show.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./snatch-selection.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./snatch-selection.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./snatch-selection.vue?vue&type=script&lang=js&\"\nexport * from \"./snatch-selection.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./status.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./status.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./status.vue?vue&type=script&lang=js&\"\nexport * from \"./status.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","export { default as AddRecommended } from './add-recommended.vue';\nexport { default as AddShowOptions } from './add-show-options.vue';\nexport { default as AddShows } from './add-shows.vue';\nexport { default as AnidbReleaseGroupUi } from './anidb-release-group-ui.vue';\nexport { default as AppHeader } from './app-header.vue';\nexport { default as Backstretch } from './backstretch.vue';\nexport { default as Config } from './config.vue';\nexport { default as ConfigPostProcessing } from './config-post-processing.vue';\nexport { default as Home } from './home.vue';\nexport { default as IRC } from './irc.vue';\nexport { default as Login } from './login.vue';\nexport { default as ManualPostProcess } from './manual-post-process.vue';\nexport { default as RootDirs } from './root-dirs.vue';\nexport { default as Show } from './show.vue';\nexport { default as ShowHeader } from './show-header.vue';\nexport { default as SnatchSelection } from './snatch-selection.vue';\nexport { default as Status } from './status.vue';\nexport * from './http';\nexport * from './helpers';\n","import axios from 'axios';\n\nconst webRoot = document.body.getAttribute('web-root');\nconst apiKey = document.body.getAttribute('api-key');\n\n/**\n * Api client based on the axios client, to communicate with medusa's web routes, which return json data.\n */\nconst apiRoute = axios.create({\n baseURL: webRoot + '/',\n timeout: 30000,\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json'\n }\n});\n\n/**\n * Api client based on the axios client, to communicate with medusa's api v1.\n */\nconst apiv1 = axios.create({\n baseURL: webRoot + '/api/v1/' + apiKey + '/',\n timeout: 30000,\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json'\n }\n});\n\n/**\n * Api client based on the axios client, to communicate with medusa's api v2.\n */\nconst api = axios.create({\n baseURL: webRoot + '/api/v2/',\n timeout: 30000,\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n 'X-Api-Key': apiKey\n }\n});\n\nexport {\n webRoot,\n apiKey,\n apiRoute,\n apiv1,\n api\n};\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c(_vm.linkProperties.is,{tag:\"component\",class:{ 'router-link': _vm.linkProperties.is === 'router-link' },attrs:{\"to\":_vm.linkProperties.to,\"href\":_vm.linkProperties.href,\"target\":_vm.linkProperties.target,\"rel\":_vm.linkProperties.rel,\"false-link\":_vm.linkProperties.falseLink}},[_vm._t(\"default\")],2)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./app-link.vue?vue&type=template&id=d2623cd8&\"\nimport script from \"./app-link.vue?vue&type=script&lang=js&\"\nexport * from \"./app-link.vue?vue&type=script&lang=js&\"\nimport style0 from \"./app-link.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./asset.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./asset.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./asset.vue?vue&type=template&id=8ae62598&\"\nimport script from \"./asset.vue?vue&type=script&lang=js&\"\nexport * from \"./asset.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (!_vm.link)?_c('img',{class:_vm.cls,attrs:{\"src\":_vm.src},on:{\"error\":function($event){_vm.error = true}}}):_c('app-link',{attrs:{\"href\":_vm.href}},[_c('img',{class:_vm.cls,attrs:{\"src\":_vm.src},on:{\"error\":function($event){_vm.error = true}}})])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-template.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-template.vue?vue&type=script&lang=js&\"","\n\n\n\n\n","import { render, staticRenderFns } from \"./config-template.vue?vue&type=template&id=1203ba68&\"\nimport script from \"./config-template.vue?vue&type=script&lang=js&\"\nexport * from \"./config-template.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"config-template-content\"}},[_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":_vm.labelFor}},[_c('span',[_vm._v(_vm._s(_vm.label))])]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_vm._t(\"default\")],2)])])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=script&lang=js&\"","\n\n\n\n\n","import { render, staticRenderFns } from \"./config-textbox-number.vue?vue&type=template&id=159c522c&\"\nimport script from \"./config-textbox-number.vue?vue&type=script&lang=js&\"\nexport * from \"./config-textbox-number.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-textbox-number.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"config-textbox-number-content\"}},[_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":_vm.id}},[_c('span',[_vm._v(_vm._s(_vm.label))])]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('input',_vm._b({directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.localValue),expression:\"localValue\"}],attrs:{\"type\":\"number\"},domProps:{\"value\":(_vm.localValue)},on:{\"input\":[function($event){if($event.target.composing){ return; }_vm.localValue=$event.target.value},function($event){return _vm.updateValue()}]}},'input',{min: _vm.min, max: _vm.max, step: _vm.step, id: _vm.id, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled},false)),_vm._v(\" \"),_vm._l((_vm.explanations),function(explanation,index){return _c('p',{key:index},[_vm._v(_vm._s(explanation))])}),_vm._v(\" \"),_vm._t(\"default\")],2)])])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=script&lang=js&\"","\n\n\n\n\n","import { render, staticRenderFns } from \"./config-textbox.vue?vue&type=template&id=788aa398&\"\nimport script from \"./config-textbox.vue?vue&type=script&lang=js&\"\nexport * from \"./config-textbox.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-textbox.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"config-textbox\"}},[_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":_vm.id}},[_c('span',[_vm._v(_vm._s(_vm.label))])]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[((({id: _vm.id, type: _vm.type, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled}).type)==='checkbox')?_c('input',_vm._b({directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.localValue),expression:\"localValue\"}],attrs:{\"type\":\"checkbox\"},domProps:{\"checked\":Array.isArray(_vm.localValue)?_vm._i(_vm.localValue,null)>-1:(_vm.localValue)},on:{\"input\":function($event){return _vm.updateValue()},\"change\":function($event){var $$a=_vm.localValue,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.localValue=$$a.concat([$$v]))}else{$$i>-1&&(_vm.localValue=$$a.slice(0,$$i).concat($$a.slice($$i+1)))}}else{_vm.localValue=$$c}}}},'input',{id: _vm.id, type: _vm.type, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled},false)):((({id: _vm.id, type: _vm.type, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled}).type)==='radio')?_c('input',_vm._b({directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.localValue),expression:\"localValue\"}],attrs:{\"type\":\"radio\"},domProps:{\"checked\":_vm._q(_vm.localValue,null)},on:{\"input\":function($event){return _vm.updateValue()},\"change\":function($event){_vm.localValue=null}}},'input',{id: _vm.id, type: _vm.type, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled},false)):_c('input',_vm._b({directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.localValue),expression:\"localValue\"}],attrs:{\"type\":({id: _vm.id, type: _vm.type, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled}).type},domProps:{\"value\":(_vm.localValue)},on:{\"input\":[function($event){if($event.target.composing){ return; }_vm.localValue=$event.target.value},function($event){return _vm.updateValue()}]}},'input',{id: _vm.id, type: _vm.type, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled},false)),_vm._v(\" \"),_vm._l((_vm.explanations),function(explanation,index){return _c('p',{key:index},[_vm._v(_vm._s(explanation))])}),_vm._v(\" \"),_vm._t(\"default\")],2)])])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=script&lang=js&\"","\n\n\n\n\n","import { render, staticRenderFns } from \"./config-toggle-slider.vue?vue&type=template&id=89c5b77c&\"\nimport script from \"./config-toggle-slider.vue?vue&type=script&lang=js&\"\nexport * from \"./config-toggle-slider.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-toggle-slider.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"config-toggle-slider-content\"}},[_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":_vm.id}},[_c('span',[_vm._v(_vm._s(_vm.label))])]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',_vm._b({attrs:{\"width\":45,\"height\":22,\"sync\":\"\"},on:{\"input\":function($event){return _vm.updateValue()}},model:{value:(_vm.localChecked),callback:function ($$v) {_vm.localChecked=$$v},expression:\"localChecked\"}},'toggle-button',{id: _vm.id, name: _vm.id, disabled: _vm.disabled},false)),_vm._v(\" \"),_vm._l((_vm.explanations),function(explanation,index){return _c('p',{key:index},[_vm._v(_vm._s(explanation))])}),_vm._v(\" \"),_vm._t(\"default\")],2)])])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./file-browser.vue?vue&type=template&id=5a327762&scoped=true&\"\nimport script from \"./file-browser.vue?vue&type=script&lang=js&\"\nexport * from \"./file-browser.vue?vue&type=script&lang=js&\"\nimport style0 from \"./file-browser.vue?vue&type=style&index=0&id=5a327762&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"5a327762\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"file-browser max-width\"},[_c('div',{class:(_vm.showBrowseButton ? 'input-group' : 'input-group-no-btn')},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.currentPath),expression:\"currentPath\"}],ref:\"locationInput\",staticClass:\"form-control input-sm fileBrowserField\",attrs:{\"name\":_vm.name,\"type\":\"text\"},domProps:{\"value\":(_vm.currentPath)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.currentPath=$event.target.value}}}),_vm._v(\" \"),(_vm.showBrowseButton)?_c('div',{staticClass:\"input-group-btn\",attrs:{\"title\":_vm.title,\"alt\":_vm.title},on:{\"click\":function($event){$event.preventDefault();return _vm.openDialog($event)}}},[_vm._m(0)]):_vm._e()]),_vm._v(\" \"),_c('div',{ref:\"fileBrowserDialog\",staticClass:\"fileBrowserDialog\",staticStyle:{\"display\":\"none\"}}),_vm._v(\" \"),_c('input',{ref:\"fileBrowserSearchBox\",staticClass:\"form-control\",staticStyle:{\"display\":\"none\"},attrs:{\"type\":\"text\"},domProps:{\"value\":_vm.currentPath},on:{\"keyup\":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,\"enter\",13,$event.key,\"Enter\")){ return null; }return _vm.browse($event.target.value)}}}),_vm._v(\" \"),_c('ul',{ref:\"fileBrowserFileList\",staticStyle:{\"display\":\"none\"}},_vm._l((_vm.files),function(file){return _c('li',{key:file.name,staticClass:\"ui-state-default ui-corner-all\"},[_c('a',{on:{\"mouseover\":function($event){return _vm.toggleFolder(file, $event)},\"mouseout\":function($event){return _vm.toggleFolder(file, $event)},\"click\":function($event){return _vm.fileClicked(file)}}},[_c('span',{class:'ui-icon ' + (file.isFile ? 'ui-icon-blank' : 'ui-icon-folder-collapsed')}),_vm._v(\" \"+_vm._s(file.name)+\"\\n \")])])}),0)])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"btn btn-default input-sm\",staticStyle:{\"font-size\":\"14px\"}},[_c('i',{staticClass:\"glyphicon glyphicon-open\"})])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./language-select.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./language-select.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./language-select.vue?vue&type=template&id=2e8dcbe5&\"\nimport script from \"./language-select.vue?vue&type=script&lang=js&\"\nexport * from \"./language-select.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('select')}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./name-pattern.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./name-pattern.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./name-pattern.vue?vue&type=template&id=b51e0a36&\"\nimport script from \"./name-pattern.vue?vue&type=script&lang=js&\"\nexport * from \"./name-pattern.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"name-pattern-wrapper\"}},[(_vm.type)?_c('div',{staticClass:\"form-group\"},[_c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"enable_naming_custom\"}},[_c('span',[_vm._v(\"Custom \"+_vm._s(_vm.type))])]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"enable_naming_custom\",\"name\":\"enable_naming_custom\",\"sync\":\"\"},on:{\"input\":function($event){return _vm.update()}},model:{value:(_vm.isEnabled),callback:function ($$v) {_vm.isEnabled=$$v},expression:\"isEnabled\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Name \"+_vm._s(_vm.type)+\" shows differently than regular shows?\")])],1)]):_vm._e(),_vm._v(\" \"),(!_vm.type || _vm.isEnabled)?_c('div',{staticClass:\"episode-naming\"},[_c('div',{staticClass:\"form-group\"},[_vm._m(0),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.selectedNamingPattern),expression:\"selectedNamingPattern\"}],staticClass:\"form-control input-sm\",attrs:{\"id\":\"name_presets\"},on:{\"change\":[function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.selectedNamingPattern=$event.target.multiple ? $$selectedVal : $$selectedVal[0]},_vm.updatePatternSamples],\"input\":function($event){return _vm.update()}}},_vm._l((_vm.presets),function(preset){return _c('option',{key:preset.pattern,attrs:{\"id\":preset.pattern}},[_vm._v(_vm._s(preset.example))])}),0)])]),_vm._v(\" \"),_c('div',{attrs:{\"id\":\"naming_custom\"}},[(_vm.isCustom)?_c('div',{staticClass:\"form-group\",staticStyle:{\"padding-top\":\"0\"}},[_vm._m(1),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.customName),expression:\"customName\"}],staticClass:\"form-control-inline-max input-sm max-input350\",attrs:{\"type\":\"text\",\"name\":\"naming_pattern\",\"id\":\"naming_pattern\"},domProps:{\"value\":(_vm.customName)},on:{\"change\":_vm.updatePatternSamples,\"input\":[function($event){if($event.target.composing){ return; }_vm.customName=$event.target.value},function($event){return _vm.update()}]}}),_vm._v(\" \"),_c('img',{staticClass:\"legend\",attrs:{\"src\":\"images/legend16.png\",\"width\":\"16\",\"height\":\"16\",\"alt\":\"[Toggle Key]\",\"id\":\"show_naming_key\",\"title\":\"Toggle Naming Legend\"},on:{\"click\":function($event){_vm.showLegend = !_vm.showLegend}}})])]):_vm._e(),_vm._v(\" \"),(_vm.showLegend && _vm.isCustom)?_c('div',{staticClass:\"nocheck\",attrs:{\"id\":\"naming_key\"}},[_c('table',{staticClass:\"Key\"},[_vm._m(2),_vm._v(\" \"),_vm._m(3),_vm._v(\" \"),_c('tbody',[_vm._m(4),_vm._v(\" \"),_vm._m(5),_vm._v(\" \"),_vm._m(6),_vm._v(\" \"),_vm._m(7),_vm._v(\" \"),_vm._m(8),_vm._v(\" \"),_vm._m(9),_vm._v(\" \"),_vm._m(10),_vm._v(\" \"),_vm._m(11),_vm._v(\" \"),_vm._m(12),_vm._v(\" \"),_vm._m(13),_vm._v(\" \"),_vm._m(14),_vm._v(\" \"),_vm._m(15),_vm._v(\" \"),_vm._m(16),_vm._v(\" \"),_vm._m(17),_vm._v(\" \"),_vm._m(18),_vm._v(\" \"),_vm._m(19),_vm._v(\" \"),_c('tr',[_vm._m(20),_vm._v(\" \"),_c('td',[_vm._v(\"%M\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.getDateFormat('M')))])]),_vm._v(\" \"),_c('tr',{staticClass:\"even\"},[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%D\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.getDateFormat('D')))])]),_vm._v(\" \"),_c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%Y\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.getDateFormat('YY')))])]),_vm._v(\" \"),_c('tr',[_vm._m(21),_vm._v(\" \"),_c('td',[_vm._v(\"%CM\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.getDateFormat('M')))])]),_vm._v(\" \"),_c('tr',{staticClass:\"even\"},[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%CD\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.getDateFormat('D')))])]),_vm._v(\" \"),_c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%CY\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.getDateFormat('YY')))])]),_vm._v(\" \"),_vm._m(22),_vm._v(\" \"),_vm._m(23),_vm._v(\" \"),_vm._m(24),_vm._v(\" \"),_vm._m(25),_vm._v(\" \"),_vm._m(26),_vm._v(\" \"),_vm._m(27),_vm._v(\" \"),_vm._m(28),_vm._v(\" \"),_vm._m(29),_vm._v(\" \"),_vm._m(30)])])]):_vm._e()]),_vm._v(\" \"),(_vm.selectedMultiEpStyle)?_c('div',{staticClass:\"form-group\"},[_vm._m(31),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.selectedMultiEpStyle),expression:\"selectedMultiEpStyle\"}],staticClass:\"form-control input-sm\",attrs:{\"id\":\"naming_multi_ep\",\"name\":\"naming_multi_ep\"},on:{\"change\":[function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.selectedMultiEpStyle=$event.target.multiple ? $$selectedVal : $$selectedVal[0]},_vm.updatePatternSamples],\"input\":function($event){return _vm.update($event)}}},_vm._l((_vm.availableMultiEpStyles),function(multiEpStyle){return _c('option',{key:multiEpStyle.value,attrs:{\"id\":\"multiEpStyle\"},domProps:{\"value\":multiEpStyle.value}},[_vm._v(_vm._s(multiEpStyle.text))])}),0)])]):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"form-group row\"},[_c('h3',{staticClass:\"col-sm-12\"},[_vm._v(\"Single-EP Sample:\")]),_vm._v(\" \"),_c('div',{staticClass:\"example col-sm-12\"},[_c('span',{staticClass:\"jumbo\",attrs:{\"id\":\"naming_example\"}},[_vm._v(_vm._s(_vm.namingExample))])])]),_vm._v(\" \"),(_vm.isMulti)?_c('div',{staticClass:\"form-group row\"},[_c('h3',{staticClass:\"col-sm-12\"},[_vm._v(\"Multi-EP sample:\")]),_vm._v(\" \"),_c('div',{staticClass:\"example col-sm-12\"},[_c('span',{staticClass:\"jumbo\",attrs:{\"id\":\"naming_example_multi\"}},[_vm._v(_vm._s(_vm.namingExampleMulti))])])]):_vm._e(),_vm._v(\" \"),(_vm.animeType > 0)?_c('div',{staticClass:\"form-group\"},[_vm._m(32),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.animeType),expression:\"animeType\"}],attrs:{\"type\":\"radio\",\"name\":\"naming_anime\",\"id\":\"naming_anime\",\"value\":\"1\"},domProps:{\"checked\":_vm._q(_vm.animeType,\"1\")},on:{\"change\":[function($event){_vm.animeType=\"1\"},_vm.updatePatternSamples],\"input\":function($event){return _vm.update()}}}),_vm._v(\" \"),_c('span',[_vm._v(\"Add the absolute number to the season/episode format?\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Only applies to animes. (e.g. S15E45 - 310 vs S15E45)\")])])]):_vm._e(),_vm._v(\" \"),(_vm.animeType > 0)?_c('div',{staticClass:\"form-group\"},[_vm._m(33),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.animeType),expression:\"animeType\"}],attrs:{\"type\":\"radio\",\"name\":\"naming_anime\",\"id\":\"naming_anime_only\",\"value\":\"2\"},domProps:{\"checked\":_vm._q(_vm.animeType,\"2\")},on:{\"change\":[function($event){_vm.animeType=\"2\"},_vm.updatePatternSamples],\"input\":function($event){return _vm.update()}}}),_vm._v(\" \"),_c('span',[_vm._v(\"Replace season/episode format with absolute number\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Only applies to animes.\")])])]):_vm._e(),_vm._v(\" \"),(_vm.animeType > 0)?_c('div',{staticClass:\"form-group\"},[_vm._m(34),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.animeType),expression:\"animeType\"}],attrs:{\"type\":\"radio\",\"name\":\"naming_anime\",\"id\":\"naming_anime_none\",\"value\":\"3\"},domProps:{\"checked\":_vm._q(_vm.animeType,\"3\")},on:{\"change\":[function($event){_vm.animeType=\"3\"},_vm.updatePatternSamples],\"input\":function($event){return _vm.update()}}}),_vm._v(\" \"),_c('span',[_vm._v(\"Don't include the absolute number\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Only applies to animes.\")])])]):_vm._e()]):_vm._e()])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"name_presets\"}},[_c('span',[_vm._v(\"Name Pattern:\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\"},[_c('span',[_vm._v(\" \")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('thead',[_c('tr',[_c('th',{staticClass:\"align-right\"},[_vm._v(\"Meaning\")]),_vm._v(\" \"),_c('th',[_vm._v(\"Pattern\")]),_vm._v(\" \"),_c('th',{attrs:{\"width\":\"60%\"}},[_vm._v(\"Result\")])])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tfoot',[_c('tr',[_c('th',{attrs:{\"colspan\":\"3\"}},[_vm._v(\"Use lower case if you want lower case names (eg. %sn, %e.n, %q_n etc)\")])])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Show Name:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%SN\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Show Name\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%S.N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Show.Name\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%S_N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Show_Name\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Season Number:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%S\")]),_vm._v(\" \"),_c('td',[_vm._v(\"2\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%0S\")]),_vm._v(\" \"),_c('td',[_vm._v(\"02\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"XEM Season Number:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%XS\")]),_vm._v(\" \"),_c('td',[_vm._v(\"2\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%0XS\")]),_vm._v(\" \"),_c('td',[_vm._v(\"02\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Episode Number:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%E\")]),_vm._v(\" \"),_c('td',[_vm._v(\"3\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%0E\")]),_vm._v(\" \"),_c('td',[_vm._v(\"03\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"XEM Episode Number:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%XE\")]),_vm._v(\" \"),_c('td',[_vm._v(\"3\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%0XE\")]),_vm._v(\" \"),_c('td',[_vm._v(\"03\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Absolute Episode Number:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%AB\")]),_vm._v(\" \"),_c('td',[_vm._v(\"003\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Xem Absolute Episode Number:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%XAB\")]),_vm._v(\" \"),_c('td',[_vm._v(\"003\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Episode Name:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%EN\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Episode Name\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%E.N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Episode.Name\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%E_N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Episode_Name\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Air Date:\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Post-Processing Date:\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Quality:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%QN\")]),_vm._v(\" \"),_c('td',[_vm._v(\"720p BluRay\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%Q.N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"720p.BluRay\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%Q_N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"720p_BluRay\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Scene Quality:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%SQN\")]),_vm._v(\" \"),_c('td',[_vm._v(\"720p HDTV x264\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%SQ.N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"720p.HDTV.x264\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%SQ_N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"720p_HDTV_x264\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('i',{staticClass:\"glyphicon glyphicon-info-sign\",attrs:{\"title\":\"Multi-EP style is ignored\"}}),_vm._v(\" \"),_c('b',[_vm._v(\"Release Name:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%RN\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Show.Name.S02E03.HDTV.x264-RLSGROUP\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',{staticClass:\"align-right\"},[_c('i',{staticClass:\"glyphicon glyphicon-info-sign\",attrs:{\"title\":\"UNKNOWN_RELEASE_GROUP is used in place of RLSGROUP if it could not be properly detected\"}}),_vm._v(\" \"),_c('b',[_vm._v(\"Release Group:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%RG\")]),_vm._v(\" \"),_c('td',[_vm._v(\"RLSGROUP\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('i',{staticClass:\"glyphicon glyphicon-info-sign\",attrs:{\"title\":\"If episode is proper/repack add 'proper' to name.\"}}),_vm._v(\" \"),_c('b',[_vm._v(\"Release Type:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%RT\")]),_vm._v(\" \"),_c('td',[_vm._v(\"PROPER\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"naming_multi_ep\"}},[_c('span',[_vm._v(\"Multi-Episode Style:\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"naming_anime\"}},[_c('span',[_vm._v(\"Add Absolute Number\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"naming_anime_only\"}},[_c('span',[_vm._v(\"Only Absolute Number\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"naming_anime_none\"}},[_c('span',[_vm._v(\"No Absolute Number\")])])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./plot-info.vue?vue&type=template&id=6b17b4d1&\"\nimport script from \"./plot-info.vue?vue&type=script&lang=js&\"\nexport * from \"./plot-info.vue?vue&type=script&lang=js&\"\nimport style0 from \"./plot-info.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('img',{class:_vm.plotInfoClass,attrs:{\"src\":\"images/info32.png\",\"width\":\"16\",\"height\":\"16\",\"alt\":\"\"}})}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./quality-pill.vue?vue&type=template&id=b683ee7a&scoped=true&\"\nimport script from \"./quality-pill.vue?vue&type=script&lang=js&\"\nexport * from \"./quality-pill.vue?vue&type=script&lang=js&\"\nimport style0 from \"./quality-pill.vue?vue&type=style&index=0&id=b683ee7a&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"b683ee7a\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',{class:_vm.override.class || ['quality', _vm.pill.class],attrs:{\"title\":_vm.title}},[_vm._v(_vm._s(_vm.override.text || _vm.pill.text))])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./scroll-buttons.vue?vue&type=template&id=96ee7e7e&\"\nimport script from \"./scroll-buttons.vue?vue&type=script&lang=js&\"\nexport * from \"./scroll-buttons.vue?vue&type=script&lang=js&\"\nimport style0 from \"./scroll-buttons.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"scroll-buttons-wrapper\"}},[_c('div',{staticClass:\"scroll-wrapper top\",class:{ show: _vm.showToTop },on:{\"click\":function($event){$event.preventDefault();return _vm.scrollTop($event)}}},[_vm._m(0)]),_vm._v(\" \"),_c('div',{staticClass:\"scroll-wrapper left\",class:{ show: _vm.showLeftRight }},[_c('span',{staticClass:\"scroll-left-inner\"},[_c('i',{staticClass:\"glyphicon glyphicon-circle-arrow-left\",on:{\"click\":function($event){$event.preventDefault();return _vm.scrollLeft($event)}}})])]),_vm._v(\" \"),_c('div',{staticClass:\"scroll-wrapper right\",class:{ show: _vm.showLeftRight }},[_c('span',{staticClass:\"scroll-right-inner\"},[_c('i',{staticClass:\"glyphicon glyphicon-circle-arrow-right\",on:{\"click\":function($event){$event.preventDefault();return _vm.scrollRight($event)}}})])])])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',{staticClass:\"scroll-top-inner\"},[_c('i',{staticClass:\"glyphicon glyphicon-circle-arrow-up\"})])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./select-list.vue?vue&type=template&id=ac609192&scoped=true&\"\nimport script from \"./select-list.vue?vue&type=script&lang=js&\"\nexport * from \"./select-list.vue?vue&type=script&lang=js&\"\nimport style0 from \"./select-list.vue?vue&type=style&index=0&id=ac609192&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"ac609192\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',_vm._b({staticClass:\"select-list max-width\"},'div',{disabled: _vm.disabled},false),[_c('i',{staticClass:\"switch-input glyphicon glyphicon-refresh\",attrs:{\"title\":\"Switch between a list and comma separated values\"},on:{\"click\":function($event){return _vm.switchFields()}}}),_vm._v(\" \"),(!_vm.csvMode)?_c('ul',[_vm._l((_vm.editItems),function(item){return _c('li',{key:item.id},[_c('div',{staticClass:\"input-group\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(item.value),expression:\"item.value\"}],staticClass:\"form-control input-sm\",attrs:{\"type\":\"text\"},domProps:{\"value\":(item.value)},on:{\"input\":[function($event){if($event.target.composing){ return; }_vm.$set(item, \"value\", $event.target.value)},function($event){return _vm.removeEmpty(item)}]}}),_vm._v(\" \"),_c('div',{staticClass:\"input-group-btn\",on:{\"click\":function($event){return _vm.deleteItem(item)}}},[_vm._m(0,true)])])])}),_vm._v(\" \"),_c('div',{staticClass:\"new-item\"},[_c('div',{staticClass:\"input-group\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.newItem),expression:\"newItem\"}],ref:\"newItemInput\",staticClass:\"form-control input-sm\",attrs:{\"type\":\"text\",\"placeholder\":\"add new values per line\"},domProps:{\"value\":(_vm.newItem)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.newItem=$event.target.value}}}),_vm._v(\" \"),_c('div',{staticClass:\"input-group-btn\",on:{\"click\":function($event){return _vm.addNewItem()}}},[_vm._m(1)])])]),_vm._v(\" \"),(_vm.newItem.length > 0)?_c('div',{staticClass:\"new-item-help\"},[_vm._v(\"\\n Click \"),_c('i',{staticClass:\"glyphicon glyphicon-plus\"}),_vm._v(\" to finish adding the value.\\n \")]):_vm._e()],2):_c('div',{staticClass:\"csv\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.csv),expression:\"csv\"}],staticClass:\"form-control input-sm\",attrs:{\"type\":\"text\",\"placeholder\":\"add values comma separated\"},domProps:{\"value\":(_vm.csv)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.csv=$event.target.value}}})])])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"btn btn-default input-sm\",staticStyle:{\"font-size\":\"14px\"}},[_c('i',{staticClass:\"glyphicon glyphicon-remove\",attrs:{\"title\":\"Remove\"}})])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"btn btn-default input-sm\",staticStyle:{\"font-size\":\"14px\"}},[_c('i',{staticClass:\"glyphicon glyphicon-plus\",attrs:{\"title\":\"Add\"}})])}]\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./show-selector.vue?vue&type=template&id=38a86ae6&\"\nimport script from \"./show-selector.vue?vue&type=script&lang=js&\"\nexport * from \"./show-selector.vue?vue&type=script&lang=js&\"\nimport style0 from \"./show-selector.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (_vm.shows.length === 0)?_c('span',[_vm._v(\"Loading...\")]):_c('div',{staticClass:\"show-selector form-inline hidden-print\"},[_c('div',{staticClass:\"select-show-group pull-left top-5 bottom-5\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.selectedShowSlug),expression:\"selectedShowSlug\"}],class:_vm.selectClass,on:{\"change\":[function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.selectedShowSlug=$event.target.multiple ? $$selectedVal : $$selectedVal[0]},function($event){return _vm.$emit('change', _vm.selectedShowSlug)}]}},[(_vm.placeholder)?_c('option',{attrs:{\"disabled\":\"\",\"hidden\":\"\"},domProps:{\"value\":_vm.placeholder,\"selected\":!_vm.selectedShowSlug}},[_vm._v(_vm._s(_vm.placeholder))]):_vm._e(),_vm._v(\" \"),(_vm.whichList === -1)?_vm._l((_vm.showLists),function(curShowList){return _c('optgroup',{key:curShowList.type,attrs:{\"label\":curShowList.type}},_vm._l((curShowList.shows),function(show){return _c('option',{key:show.id.slug,domProps:{\"value\":show.id.slug}},[_vm._v(_vm._s(show.title))])}),0)}):_vm._l((_vm.showLists[_vm.whichList].shows),function(show){return _c('option',{key:show.id.slug,domProps:{\"value\":show.id.slug}},[_vm._v(_vm._s(show.title))])})],2)])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./state-switch.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./state-switch.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./state-switch.vue?vue&type=template&id=4f286108&\"\nimport script from \"./state-switch.vue?vue&type=script&lang=js&\"\nexport * from \"./state-switch.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('img',_vm._b({attrs:{\"height\":\"16\",\"width\":\"16\"}},'img',{ src: _vm.src, alt: _vm.alt },false))}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","export { default as AppLink } from './app-link.vue';\nexport { default as Asset } from './asset.vue';\nexport { default as ConfigTemplate } from './config-template.vue';\nexport { default as ConfigTextboxNumber } from './config-textbox-number.vue';\nexport { default as ConfigTextbox } from './config-textbox.vue';\nexport { default as ConfigToggleSlider } from './config-toggle-slider.vue';\nexport { default as FileBrowser } from './file-browser.vue';\nexport { default as LanguageSelect } from './language-select.vue';\nexport { default as NamePattern } from './name-pattern.vue';\nexport { default as PlotInfo } from './plot-info.vue';\nexport { default as QualityPill } from './quality-pill.vue';\nexport { default as ScrollButtons } from './scroll-buttons.vue';\nexport { default as SelectList } from './select-list.vue';\nexport { default as ShowSelector } from './show-selector.vue';\nexport { default as StateSwitch } from './state-switch.vue';\n","const isDevelopment = process.env.NODE_ENV === 'development';\n\n/**\n * Calculate the combined value of the selected qualities.\n * @param {number[]} allowedQualities - Array of allowed qualities.\n * @param {number[]} preferredQualities - Array of preferred qualities.\n * @returns {number} - An unsigned integer.\n */\nconst combineQualities = (allowedQualities, preferredQualities) => {\n const reducer = (accumulator, currentValue) => accumulator | currentValue;\n const allowed = allowedQualities.reduce(reducer, 0);\n const preferred = preferredQualities.reduce(reducer, 0);\n\n return (allowed | (preferred << 16)) >>> 0; // Unsigned int\n};\n\n/**\n * Return a human readable representation of the provided size.\n * @param {number} bytes - The size in bytes to convert\n * @param {boolean} [useDecimal=false] - Use decimal instead of binary prefixes (e.g. kilo = 1000 instead of 1024)\n * @returns {string} The converted size.\n */\nconst humanFileSize = (bytes, useDecimal = false) => {\n if (bytes === undefined) {\n return;\n }\n\n const thresh = useDecimal ? 1000 : 1024;\n if (Math.abs(bytes) < thresh) {\n return bytes + ' B';\n }\n const units = ['KB', 'MB', 'GB', 'TB', 'PB'];\n let u = -1;\n do {\n bytes /= thresh;\n ++u;\n } while (Math.abs(bytes) >= thresh && u < units.length - 1);\n\n return `${bytes.toFixed(2)} ${units[u]}`;\n};\n\nexport {\n combineQualities,\n humanFileSize,\n isDevelopment\n};\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"show-header-container\"},[_c('div',{staticClass:\"row\"},[(_vm.show)?_c('div',{staticClass:\"col-lg-12\",attrs:{\"id\":\"showtitle\",\"data-showname\":_vm.show.title}},[_c('div',[_c('h1',{staticClass:\"title\",attrs:{\"data-indexer-name\":_vm.show.indexer,\"data-series-id\":_vm.show.id[_vm.show.indexer],\"id\":'scene_exception_' + _vm.show.id[_vm.show.indexer]}},[_c('app-link',{staticClass:\"snatchTitle\",attrs:{\"href\":'home/displayShow?indexername=' + _vm.show.indexer + '&seriesid=' + _vm.show.id[_vm.show.indexer]}},[_vm._v(_vm._s(_vm.show.title))])],1)]),_vm._v(\" \"),(_vm.type === 'snatch-selection')?_c('div',{staticClass:\"pull-right\",attrs:{\"id\":\"show-specials-and-seasons\"}},[_c('span',{staticClass:\"h2footer display-specials\"},[_vm._v(\"\\n Manual search for:\"),_c('br'),_vm._v(\" \"),_c('app-link',{staticClass:\"snatchTitle\",attrs:{\"href\":'home/displayShow?indexername=' + _vm.show.indexer + '&seriesid=' + _vm.show.id[_vm.show.indexer]}},[_vm._v(_vm._s(_vm.show.title))]),_vm._v(\" / Season \"+_vm._s(_vm.season)),(_vm.episode && _vm.manualSearchType !== 'season')?[_vm._v(\" Episode \"+_vm._s(_vm.episode))]:_vm._e()],2)]):_vm._e(),_vm._v(\" \"),(_vm.type !== 'snatch-selection' && _vm.show.seasons && _vm.show.seasons.length >= 1)?_c('div',{staticClass:\"pull-right\",attrs:{\"id\":\"show-specials-and-seasons\"}},[(_vm.show.seasons.find(function (season) { return function (ref) {\n\tvar season = ref.season;\n\n\treturn season === 0;\n; }\t}))?_c('span',{staticClass:\"h2footer display-specials\"},[_vm._v(\"\\n Display Specials: \"),_c('a',{staticClass:\"inner\",staticStyle:{\"cursor\":\"pointer\"},on:{\"click\":function($event){return _vm.toggleSpecials()}}},[_vm._v(_vm._s(_vm.displaySpecials ? 'Hide' : 'Show'))])]):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"h2footer display-seasons clear\"},[_c('span',[(_vm.show.seasons.length >= 15)?_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.jumpToSeason),expression:\"jumpToSeason\"}],staticClass:\"form-control input-sm\",staticStyle:{\"position\":\"relative\"},attrs:{\"id\":\"seasonJump\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.jumpToSeason=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},[_c('option',{attrs:{\"value\":\"jump\"}},[_vm._v(\"Jump to Season\")]),_vm._v(\" \"),_vm._l((_vm.show.seasons),function(season){return _c('option',{key:'jumpToSeason-' + season[0].season,attrs:{\"data-season\":season[0].season},domProps:{\"value\":'#season-' + season[0].season}},[_vm._v(\"\\n \"+_vm._s(season[0].season === 0 ? 'Specials' : 'Season ' + season[0].season)+\"\\n \")])})],2):(_vm.show.seasons.length >= 1)?[_vm._v(\"\\n Season:\\n \"),_vm._l((_vm.reverse(_vm.show.seasons)),function(season,$index){return [_c('app-link',{key:(\"jumpToSeason-\" + (season[0].season)),attrs:{\"href\":'#season-' + season[0].season}},[_vm._v(_vm._s(season[0].season === 0 ? 'Specials' : season[0].season))]),_vm._v(\" \"),_vm._t(\"default\"),_vm._v(\" \"),($index !== (_vm.show.seasons.length - 1))?_c('span',{key:(\"separator-\" + $index),staticClass:\"separator\"},[_vm._v(\"| \")]):_vm._e()]})]:_vm._e()],2)])]):_vm._e()]):_vm._e()]),_vm._v(\" \"),_vm._l((_vm.activeShowQueueStatuses),function(queueItem){return _c('div',{key:queueItem.action,staticClass:\"row\"},[_c('div',{staticClass:\"alert alert-info\"},[_vm._v(\"\\n \"+_vm._s(queueItem.message)+\"\\n \")])])}),_vm._v(\" \"),_c('div',{staticClass:\"row\",attrs:{\"id\":\"row-show-summary\"}},[_c('div',{staticClass:\"col-md-12\",attrs:{\"id\":\"col-show-summary\"}},[_c('div',{staticClass:\"show-poster-container\"},[_c('div',{staticClass:\"row\"},[_c('div',{staticClass:\"image-flex-container col-md-12\"},[_c('asset',{attrs:{\"default\":\"images/poster.png\",\"show-slug\":_vm.show.id.slug,\"type\":\"posterThumb\",\"cls\":\"show-image shadow\",\"link\":true}})],1)])]),_vm._v(\" \"),_c('div',{staticClass:\"ver-spacer\"}),_vm._v(\" \"),_c('div',{staticClass:\"show-info-container\"},[_c('div',{staticClass:\"row\"},[_c('div',{staticClass:\"pull-right col-lg-3 col-md-3 hidden-sm hidden-xs\"},[_c('asset',{attrs:{\"default\":\"images/banner.png\",\"show-slug\":_vm.show.id.slug,\"type\":\"banner\",\"cls\":\"show-banner pull-right shadow\",\"link\":true}})],1),_vm._v(\" \"),_c('div',{staticClass:\"pull-left col-lg-9 col-md-9 col-sm-12 col-xs-12\",attrs:{\"id\":\"show-rating\"}},[(_vm.show.rating.imdb && _vm.show.rating.imdb.rating)?_c('span',{staticClass:\"imdbstars\",attrs:{\"qtip-content\":_vm.show.rating.imdb.rating + ' / 10 Stars
' + _vm.show.rating.imdb.votes + ' Votes'}},[_c('span',{style:({ width: (Number(_vm.show.rating.imdb.rating) * 12) + '%' })})]):_vm._e(),_vm._v(\" \"),(!_vm.show.id.imdb)?[(_vm.show.year.start)?_c('span',[_vm._v(\"(\"+_vm._s(_vm.show.year.start)+\") - \"+_vm._s(_vm.show.runtime)+\" minutes - \")]):_vm._e()]:[_vm._l((_vm.show.countryCodes),function(country){return _c('img',{key:'flag-' + country,class:['country-flag', 'flag-' + country],staticStyle:{\"margin-left\":\"3px\",\"vertical-align\":\"middle\"},attrs:{\"src\":\"images/blank.png\",\"width\":\"16\",\"height\":\"11\"}})}),_vm._v(\" \"),(_vm.show.imdbInfo.year)?_c('span',[_vm._v(\"\\n (\"+_vm._s(_vm.show.imdbInfo.year)+\") -\\n \")]):_vm._e(),_vm._v(\" \"),_c('span',[_vm._v(\"\\n \"+_vm._s(_vm.show.imdbInfo.runtimes || _vm.show.runtime)+\" minutes\\n \")]),_vm._v(\" \"),_c('app-link',{attrs:{\"href\":'https://www.imdb.com/title/' + _vm.show.id.imdb,\"title\":'https://www.imdb.com/title/' + _vm.show.id.imdb}},[_c('img',{staticStyle:{\"margin-top\":\"-1px\",\"vertical-align\":\"middle\"},attrs:{\"alt\":\"[imdb]\",\"height\":\"16\",\"width\":\"16\",\"src\":\"images/imdb.png\"}})])],_vm._v(\" \"),(_vm.show.id.trakt)?_c('app-link',{attrs:{\"href\":'https://trakt.tv/shows/' + _vm.show.id.trakt,\"title\":'https://trakt.tv/shows/' + _vm.show.id.trakt}},[_c('img',{attrs:{\"alt\":\"[trakt]\",\"height\":\"16\",\"width\":\"16\",\"src\":\"images/trakt.png\"}})]):_vm._e(),_vm._v(\" \"),(_vm.showIndexerUrl && _vm.indexerConfig[_vm.show.indexer].icon)?_c('app-link',{attrs:{\"href\":_vm.showIndexerUrl,\"title\":_vm.showIndexerUrl}},[_c('img',{staticStyle:{\"margin-top\":\"-1px\",\"vertical-align\":\"middle\"},attrs:{\"alt\":_vm.indexerConfig[_vm.show.indexer].name,\"height\":\"16\",\"width\":\"16\",\"src\":'images/' + _vm.indexerConfig[_vm.show.indexer].icon}})]):_vm._e(),_vm._v(\" \"),(_vm.show.xemNumbering)?_c('app-link',{attrs:{\"href\":'http://thexem.de/search?q=' + _vm.show.title,\"title\":'http://thexem.de/search?q=' + _vm.show.title}},[_c('img',{staticStyle:{\"margin-top\":\"-1px\",\"vertical-align\":\"middle\"},attrs:{\"alt\":\"[xem]\",\"height\":\"16\",\"width\":\"16\",\"src\":\"images/xem.png\"}})]):_vm._e(),_vm._v(\" \"),(_vm.show.id.tvdb)?_c('app-link',{attrs:{\"href\":'https://fanart.tv/series/' + _vm.show.id.tvdb,\"title\":'https://fanart.tv/series/' + _vm.show.id[_vm.show.indexer]}},[_c('img',{staticClass:\"fanart\",attrs:{\"alt\":\"[fanart.tv]\",\"height\":\"16\",\"width\":\"16\",\"src\":\"images/fanart.tv.png\"}})]):_vm._e()],2),_vm._v(\" \"),_c('div',{staticClass:\"pull-left col-lg-9 col-md-9 col-sm-12 col-xs-12\",attrs:{\"id\":\"tags\"}},[(_vm.show.genres)?_c('ul',{staticClass:\"tags\"},_vm._l((_vm.dedupeGenres(_vm.show.genres)),function(genre){return _c('app-link',{key:genre.toString(),attrs:{\"href\":'https://trakt.tv/shows/popular/?genres=' + genre.toLowerCase().replace(' ', '-'),\"title\":'View other popular ' + genre + ' shows on trakt.tv'}},[_c('li',[_vm._v(_vm._s(genre))])])}),1):_c('ul',{staticClass:\"tags\"},_vm._l((_vm.showGenres),function(genre){return _c('app-link',{key:genre.toString(),attrs:{\"href\":'https://www.imdb.com/search/title?count=100&title_type=tv_series&genres=' + genre.toLowerCase().replace(' ', '-'),\"title\":'View other popular ' + genre + ' shows on IMDB'}},[_c('li',[_vm._v(_vm._s(genre))])])}),1)])]),_vm._v(\" \"),_c('div',{staticClass:\"row\"},[_c('div',{staticClass:\"col-md-12\",attrs:{\"id\":\"summary\"}},[_c('div',{class:[{ summaryFanArt: _vm.config.fanartBackground }, 'col-lg-9', 'col-md-8', 'col-sm-8', 'col-xs-12'],attrs:{\"id\":\"show-summary\"}},[_c('table',{staticClass:\"summaryTable pull-left\"},[(_vm.show.plot)?_c('tr',[_c('td',{staticStyle:{\"padding-bottom\":\"15px\"},attrs:{\"colspan\":\"2\"}},[_c('truncate',{attrs:{\"length\":250,\"clamp\":\"show more...\",\"less\":\"show less...\",\"text\":_vm.show.plot},on:{\"toggle\":function($event){return _vm.$emit('reflow')}}})],1)]):_vm._e(),_vm._v(\" \"),(_vm.getPreset(_vm.combineQualities(_vm.show.config.qualities.allowed)).length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Quality: \")]),_c('td',[_c('quality-pill',{attrs:{\"quality\":_vm.combineQualities(_vm.show.config.qualities.allowed)}})],1)]):_vm._e(),_vm._v(\" \"),(!_vm.getPreset(_vm.combineQualities(_vm.show.config.qualities.allowed)).length > 0 && _vm.show.config.qualities.allowed)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Quality allowed:\")]),_c('td',[_vm._l((_vm.show.config.qualities.allowed),function(curQuality,$index){return [($index > 0)?[_vm._v(\",\")]:_vm._e(),_vm._v(\" \"),_c('quality-pill',{key:'allowed-' + curQuality,attrs:{\"quality\":curQuality}})]})],2)]):_vm._e(),_vm._v(\" \"),(!_vm.getPreset(_vm.combineQualities(_vm.show.config.qualities.allowed)).length > 0 && _vm.combineQualities(_vm.show.config.qualities.preferred).length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Quality preferred:\")]),_c('td',[_vm._l((_vm.show.config.qualities.preferred),function(curQuality,$index){return [($index > 0)?[_vm._v(\",\")]:_vm._e(),_vm._v(\" \"),_c('quality-pill',{key:'preferred-' + curQuality,attrs:{\"quality\":curQuality}})]})],2)]):_vm._e(),_vm._v(\" \"),(_vm.show.network && _vm.show.airs)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Originally Airs: \")]),_c('td',[_vm._v(_vm._s(_vm.show.airs)+\" \"),(!_vm.show.airsFormatValid)?_c('font',{attrs:{\"color\":\"#FF0000\"}},[_c('b',[_vm._v(\"(invalid Timeformat)\")])]):_vm._e(),_vm._v(\" on \"+_vm._s(_vm.show.network))],1)]):(_vm.show.network)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Originally Airs: \")]),_c('td',[_vm._v(_vm._s(_vm.show.network))])]):(_vm.show.airs)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Originally Airs: \")]),_c('td',[_vm._v(_vm._s(_vm.show.airs)+\" \"),(!_vm.show.airsFormatValid)?_c('font',{attrs:{\"color\":\"#FF0000\"}},[_c('b',[_vm._v(\"(invalid Timeformat)\")])]):_vm._e()],1)]):_vm._e(),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Show Status: \")]),_c('td',[_vm._v(_vm._s(_vm.show.status))])]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Default EP Status: \")]),_c('td',[_vm._v(_vm._s(_vm.show.config.defaultEpisodeStatus))])]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_c('span',{class:{'location-invalid': !_vm.show.config.locationValid}},[_vm._v(\"Location: \")])]),_c('td',[_c('span',{class:{'location-invalid': !_vm.show.config.locationValid}},[_vm._v(_vm._s(_vm.show.config.location))]),_vm._v(_vm._s(_vm.show.config.locationValid ? '' : ' (Missing)'))])]),_vm._v(\" \"),(_vm.show.config.aliases.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\",staticStyle:{\"vertical-align\":\"top\"}},[_vm._v(\"Scene Name:\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.show.config.aliases.join(',')))])]):_vm._e(),_vm._v(\" \"),(_vm.show.config.release.requiredWords.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\",staticStyle:{\"vertical-align\":\"top\"}},[_vm._v(\"Required Words: \")]),_vm._v(\" \"),_c('td',[_c('span',{staticClass:\"break-word\",class:{required: _vm.type === 'snatch-selection'}},[_vm._v(_vm._s(_vm.show.config.release.requiredWords.join(',')))])])]):_vm._e(),_vm._v(\" \"),(_vm.show.config.release.ignoredWords.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\",staticStyle:{\"vertical-align\":\"top\"}},[_vm._v(\"Ignored Words: \")]),_vm._v(\" \"),_c('td',[_c('span',{staticClass:\"break-word\",class:{ignored: _vm.type === 'snatch-selection'}},[_vm._v(_vm._s(_vm.show.config.release.ignoredWords.join(',')))])])]):_vm._e(),_vm._v(\" \"),(_vm.preferredWords.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\",staticStyle:{\"vertical-align\":\"top\"}},[_vm._v(\"Preferred Words: \")]),_vm._v(\" \"),_c('td',[_c('span',{staticClass:\"break-word\",class:{preferred: _vm.type === 'snatch-selection'}},[_vm._v(_vm._s(_vm.preferredWords.join(',')))])])]):_vm._e(),_vm._v(\" \"),(_vm.undesiredWords.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\",staticStyle:{\"vertical-align\":\"top\"}},[_vm._v(\"Undesired Words: \")]),_vm._v(\" \"),_c('td',[_c('span',{staticClass:\"break-word\",class:{undesired: _vm.type === 'snatch-selection'}},[_vm._v(_vm._s(_vm.undesiredWords.join(',')))])])]):_vm._e(),_vm._v(\" \"),(_vm.show.config.release.whitelist && _vm.show.config.release.whitelist.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Wanted Groups:\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.show.config.release.whitelist.join(',')))])]):_vm._e(),_vm._v(\" \"),(_vm.show.config.release.blacklist && _vm.show.config.release.blacklist.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Unwanted Groups:\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.show.config.release.blacklist.join(',')))])]):_vm._e(),_vm._v(\" \"),(_vm.show.config.airdateOffset !== 0)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Daily search offset:\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.show.config.airdateOffset)+\" hours\")])]):_vm._e(),_vm._v(\" \"),(_vm.show.config.locationValid && _vm.show.size > -1)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Size:\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.humanFileSize(_vm.show.size)))])]):_vm._e()])]),_vm._v(\" \"),_c('div',{staticClass:\"col-lg-3 col-md-4 col-sm-4 col-xs-12 pull-xs-left\",attrs:{\"id\":\"show-status\"}},[_c('table',{staticClass:\"pull-xs-left pull-md-right pull-sm-right pull-lg-right\"},[(_vm.show.language)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Info Language:\")]),_c('td',[_c('img',{attrs:{\"src\":'images/subtitles/flags/' + _vm.getCountryISO2ToISO3(_vm.show.language) + '.png',\"width\":\"16\",\"height\":\"11\",\"alt\":_vm.show.language,\"title\":_vm.show.language,\"onError\":\"this.onerror=null;this.src='images/flags/unknown.png';\"}})])]):_vm._e(),_vm._v(\" \"),(_vm.config.subtitles.enabled)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Subtitles: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.subtitlesEnabled}})],1)]):_vm._e(),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Season Folders: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.seasonFolders || _vm.config.namingForceFolders}})],1)]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Paused: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.paused}})],1)]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Air-by-Date: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.airByDate}})],1)]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Sports: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.sports}})],1)]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Anime: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.anime}})],1)]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"DVD Order: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.dvdOrder}})],1)]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Scene Numbering: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.scene}})],1)])])])])])])])]),_vm._v(\" \"),(_vm.show)?_c('div',{staticClass:\"row\",attrs:{\"id\":\"row-show-episodes-controls\"}},[_c('div',{staticClass:\"col-md-12\",attrs:{\"id\":\"col-show-episodes-controls\"}},[(_vm.type === 'show')?_c('div',{staticClass:\"row key\"},[_c('div',{staticClass:\"col-lg-12\",attrs:{\"id\":\"checkboxControls\"}},[_c('div',{staticClass:\"pull-left top-5\",attrs:{\"id\":\"key-padding\"}},[(_vm.show.seasons)?_c('label',{attrs:{\"for\":\"wanted\"}},[_c('span',{staticClass:\"wanted\"},[_c('input',{attrs:{\"type\":\"checkbox\",\"id\":\"wanted\",\"checked\":\"checked\"},on:{\"input\":function($event){return _vm.showHideRows('wanted')}}}),_vm._v(\" Wanted: \"),_c('b',[_vm._v(_vm._s(_vm.episodeSummary.Wanted))])])]):_vm._e(),_vm._v(\" \"),(_vm.show.seasons)?_c('label',{attrs:{\"for\":\"qual\"}},[_c('span',{staticClass:\"qual\"},[_c('input',{attrs:{\"type\":\"checkbox\",\"id\":\"qual\",\"checked\":\"checked\"},on:{\"input\":function($event){return _vm.showHideRows('qual')}}}),_vm._v(\" Allowed: \"),_c('b',[_vm._v(_vm._s(_vm.episodeSummary.Allowed))])])]):_vm._e(),_vm._v(\" \"),(_vm.show.seasons)?_c('label',{attrs:{\"for\":\"good\"}},[_c('span',{staticClass:\"good\"},[_c('input',{attrs:{\"type\":\"checkbox\",\"id\":\"good\",\"checked\":\"checked\"},on:{\"input\":function($event){return _vm.showHideRows('good')}}}),_vm._v(\" Preferred: \"),_c('b',[_vm._v(_vm._s(_vm.episodeSummary.Preferred))])])]):_vm._e(),_vm._v(\" \"),(_vm.show.seasons)?_c('label',{attrs:{\"for\":\"skipped\"}},[_c('span',{staticClass:\"skipped\"},[_c('input',{attrs:{\"type\":\"checkbox\",\"id\":\"skipped\",\"checked\":\"checked\"},on:{\"input\":function($event){return _vm.showHideRows('skipped')}}}),_vm._v(\" Skipped: \"),_c('b',[_vm._v(_vm._s(_vm.episodeSummary.Skipped))])])]):_vm._e(),_vm._v(\" \"),(_vm.show.seasons)?_c('label',{attrs:{\"for\":\"snatched\"}},[_c('span',{staticClass:\"snatched\"},[_c('input',{attrs:{\"type\":\"checkbox\",\"id\":\"snatched\",\"checked\":\"checked\"},on:{\"input\":function($event){return _vm.showHideRows('snatched')}}}),_vm._v(\" Snatched: \"),_c('b',[_vm._v(_vm._s(_vm.episodeSummary.Snatched + _vm.episodeSummary['Snatched (Proper)'] + _vm.episodeSummary['Snatched (Best)']))])])]):_vm._e(),_vm._v(\" \"),_c('button',{staticClass:\"btn-medusa seriesCheck\",on:{\"click\":_vm.selectEpisodesClicked}},[_vm._v(\"Select Episodes\")]),_vm._v(\" \"),_c('button',{staticClass:\"btn-medusa clearAll\",on:{\"click\":_vm.clearEpisodeSelectionClicked}},[_vm._v(\"Clear\")])]),_vm._v(\" \"),_c('div',{staticClass:\"pull-lg-right top-5\"},[_c('select',{staticClass:\"form-control form-control-inline input-sm-custom input-sm-smallfont\",attrs:{\"id\":\"statusSelect\"}},_vm._l((_vm.changeStatusOptions),function(option){return _c('option',{key:option.value,domProps:{\"value\":option.value}},[_vm._v(\"\\n \"+_vm._s(option.text)+\"\\n \")])}),0),_vm._v(\" \"),_c('select',{staticClass:\"form-control form-control-inline input-sm-custom input-sm-smallfont\",attrs:{\"id\":\"qualitySelect\"}},_vm._l((_vm.changeQualityOptions),function(option){return _c('option',{key:option.value,domProps:{\"value\":option.value}},[_vm._v(\"\\n \"+_vm._s(option.text)+\"\\n \")])}),0),_vm._v(\" \"),_c('input',{attrs:{\"type\":\"hidden\",\"id\":\"series-slug\"},domProps:{\"value\":_vm.show.id.slug}}),_vm._v(\" \"),_c('input',{attrs:{\"type\":\"hidden\",\"id\":\"series-id\"},domProps:{\"value\":_vm.show.id[_vm.show.indexer]}}),_vm._v(\" \"),_c('input',{attrs:{\"type\":\"hidden\",\"id\":\"indexer\"},domProps:{\"value\":_vm.show.indexer}}),_vm._v(\" \"),_c('input',{staticClass:\"btn-medusa\",attrs:{\"type\":\"button\",\"id\":\"changeStatus\",\"value\":\"Go\"},on:{\"click\":_vm.changeStatusClicked}})])])]):_c('div')])]):_vm._e()],2)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-header.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-header.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./show-header.vue?vue&type=template&id=e712fe74&scoped=true&\"\nimport script from \"./show-header.vue?vue&type=script&lang=js&\"\nexport * from \"./show-header.vue?vue&type=script&lang=js&\"\nimport style0 from \"./show-header.vue?vue&type=style&index=0&id=e712fe74&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"e712fe74\",\n null\n \n)\n\nexport default component.exports","import VueRouter from 'vue-router';\n\nconst AddRecommended = () => import('./components/add-recommended.vue');\nconst AddShows = () => import('./components/add-shows.vue');\nconst Config = () => import('./components/config.vue');\nconst ConfigPostProcessing = () => import('./components/config-post-processing.vue');\nconst IRC = () => import('./components/irc.vue');\nconst Login = () => import('./components/login.vue');\nconst NotFound = () => import('./components/http/404.vue');\n\nconst homeRoutes = [{\n path: '/home',\n name: 'home',\n meta: {\n title: 'Home',\n header: 'Show List',\n topMenu: 'home'\n }\n}, {\n path: '/home/editShow',\n name: 'editShow',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/home/displayShow',\n name: 'show',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/home/snatchSelection',\n name: 'snatchSelection',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/home/testRename',\n name: 'testRename',\n meta: {\n title: 'Preview Rename',\n header: 'Preview Rename',\n topMenu: 'home'\n }\n}, {\n path: '/home/postprocess',\n name: 'postprocess',\n meta: {\n title: 'Manual Post-Processing',\n header: 'Manual Post-Processing',\n topMenu: 'home'\n }\n}, {\n path: '/home/status',\n name: 'status',\n meta: {\n title: 'Status',\n topMenu: 'system'\n }\n}, {\n path: '/home/restart',\n name: 'restart',\n meta: {\n title: 'Restarting...',\n header: 'Performing Restart',\n topMenu: 'system'\n }\n}, {\n path: '/home/shutdown',\n name: 'shutdown',\n meta: {\n header: 'Shutting down',\n topMenu: 'system'\n }\n}, {\n path: '/home/update',\n name: 'update',\n meta: {\n topMenu: 'system'\n }\n}];\n\nconst configRoutes = [{\n path: '/config',\n name: 'config',\n meta: {\n title: 'Help & Info',\n header: 'Medusa Configuration',\n topMenu: 'config',\n converted: true\n },\n component: Config\n}, {\n path: '/config/anime',\n name: 'configAnime',\n meta: {\n title: 'Config - Anime',\n header: 'Anime',\n topMenu: 'config'\n }\n}, {\n path: '/config/backuprestore',\n name: 'configBackupRestore',\n meta: {\n title: 'Config - Backup/Restore',\n header: 'Backup/Restore',\n topMenu: 'config'\n }\n}, {\n path: '/config/general',\n name: 'configGeneral',\n meta: {\n title: 'Config - General',\n header: 'General Configuration',\n topMenu: 'config'\n }\n}, {\n path: '/config/notifications',\n name: 'configNotifications',\n meta: {\n title: 'Config - Notifications',\n header: 'Notifications',\n topMenu: 'config'\n }\n}, {\n path: '/config/postProcessing',\n name: 'configPostProcessing',\n meta: {\n title: 'Config - Post Processing',\n header: 'Post Processing',\n topMenu: 'config'\n },\n component: ConfigPostProcessing\n}, {\n path: '/config/providers',\n name: 'configSearchProviders',\n meta: {\n title: 'Config - Providers',\n header: 'Search Providers',\n topMenu: 'config'\n }\n}, {\n path: '/config/search',\n name: 'configSearchSettings',\n meta: {\n title: 'Config - Episode Search',\n header: 'Search Settings',\n topMenu: 'config'\n }\n}, {\n path: '/config/subtitles',\n name: 'configSubtitles',\n meta: {\n title: 'Config - Subtitles',\n header: 'Subtitles',\n topMenu: 'config'\n }\n}];\n\nconst addShowRoutes = [{\n path: '/addShows',\n name: 'addShows',\n meta: {\n title: 'Add Shows',\n header: 'Add Shows',\n topMenu: 'home',\n converted: true\n },\n component: AddShows\n}, {\n path: '/addShows/addExistingShows',\n name: 'addExistingShows',\n meta: {\n title: 'Add Existing Shows',\n header: 'Add Existing Shows',\n topMenu: 'home'\n }\n}, {\n path: '/addShows/newShow',\n name: 'addNewShow',\n meta: {\n title: 'Add New Show',\n header: 'Add New Show',\n topMenu: 'home'\n }\n}, {\n path: '/addShows/trendingShows',\n name: 'addTrendingShows',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/addShows/popularShows',\n name: 'addPopularShows',\n meta: {\n title: 'Popular Shows',\n header: 'Popular Shows',\n topMenu: 'home'\n }\n}, {\n path: '/addShows/popularAnime',\n name: 'addPopularAnime',\n meta: {\n title: 'Popular Anime Shows',\n header: 'Popular Anime Shows',\n topMenu: 'home'\n }\n}];\n\nconst loginRoute = {\n path: '/login',\n name: 'login',\n meta: {\n title: 'Login'\n },\n component: Login\n};\n\nconst addRecommendedRoute = {\n path: '/addRecommended',\n name: 'addRecommended',\n meta: {\n title: 'Add Recommended Shows',\n header: 'Add Recommended Shows',\n topMenu: 'home'\n },\n component: AddRecommended\n};\n\nconst scheduleRoute = {\n path: '/schedule',\n name: 'schedule',\n meta: {\n title: 'Schedule',\n header: 'Schedule',\n topMenu: 'schedule'\n }\n};\n\nconst historyRoute = {\n path: '/history',\n name: 'history',\n meta: {\n title: 'History',\n header: 'History',\n topMenu: 'history'\n }\n};\n\nconst manageRoutes = [{\n path: '/manage',\n name: 'manage',\n meta: {\n title: 'Mass Update',\n header: 'Mass Update',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/backlogOverview',\n name: 'manageBacklogOverview',\n meta: {\n title: 'Backlog Overview',\n header: 'Backlog Overview',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/episodeStatuses',\n name: 'manageEpisodeOverview',\n meta: {\n title: 'Episode Overview',\n header: 'Episode Overview',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/failedDownloads',\n name: 'manageFailedDownloads',\n meta: {\n title: 'Failed Downloads',\n header: 'Failed Downlaods',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/manageSearches',\n name: 'manageManageSearches',\n meta: {\n title: 'Manage Searches',\n header: 'Manage Searches',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/massEdit',\n name: 'manageMassEdit',\n meta: {\n title: 'Mass Edit',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/subtitleMissed',\n name: 'manageSubtitleMissed',\n meta: {\n title: 'Missing Subtitles',\n header: 'Missing Subtitles',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/subtitleMissedPP',\n name: 'manageSubtitleMissedPP',\n meta: {\n title: 'Missing Subtitles in Post-Process folder',\n header: 'Missing Subtitles in Post-Process folder',\n topMenu: 'manage'\n }\n}];\n\nconst errorLogsRoutes = [{\n path: '/errorlogs',\n name: 'errorlogs',\n meta: {\n title: 'Logs & Errors',\n topMenu: 'system'\n }\n}, {\n path: '/errorlogs/viewlog',\n name: 'viewlog',\n meta: {\n title: 'Logs',\n header: 'Log File',\n topMenu: 'system'\n }\n}];\n\nconst newsRoute = {\n path: '/news',\n name: 'news',\n meta: {\n title: 'News',\n header: 'News',\n topMenu: 'system'\n }\n};\n\nconst changesRoute = {\n path: '/changes',\n name: 'changes',\n meta: {\n title: 'Changelog',\n header: 'Changelog',\n topMenu: 'system'\n }\n};\n\nconst ircRoute = {\n path: '/IRC',\n name: 'IRC',\n meta: {\n title: 'IRC',\n topMenu: 'system'\n },\n component: IRC\n};\n\nconst notFoundRoute = {\n path: '/not-found',\n name: 'not-found',\n meta: {\n title: '404',\n header: '404 - page not found'\n },\n component: NotFound\n};\n\n// @NOTE: Redirect can only be added once all routes are vue\n/*\nconst notFoundRedirect = {\n path: '*',\n redirect: '/not-found'\n};\n*/\n\nconst routes = [\n ...homeRoutes,\n ...configRoutes,\n ...addShowRoutes,\n loginRoute,\n addRecommendedRoute,\n scheduleRoute,\n historyRoute,\n ...manageRoutes,\n ...errorLogsRoutes,\n newsRoute,\n changesRoute,\n ircRoute,\n notFoundRoute\n];\n\nconst router = new VueRouter({\n base: document.body.getAttribute('web-root') + '/',\n mode: 'history',\n routes\n});\n\nrouter.beforeEach((to, from, next) => {\n const { meta } = to;\n const { title } = meta;\n\n // If there's no title then it's not a .vue route\n // or it's handling its own title\n if (title) {\n document.title = `${title} | Medusa`;\n }\n\n // Always call next otherwise the will be empty\n next();\n});\n\nexport default router;\n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","\n\n\n\n","\n\n\n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","\n\n\n","// style-loader: Adds some css to the DOM by adding a \n","\n\n\n","// style-loader: Adds some css to the DOM by adding a \n","\n \n
\n
= 1\" id=\"show-specials-and-seasons\" class=\"pull-right\">\n ({ season }) => season === 0)\">\n Display Specials: {{ displaySpecials ? 'Hide' : 'Show' }}\n \n\n
\n \n \n \n \n
\n
\n
\n \n\n
\n
\n {{ queueItem.message }}\n
\n
\n\n
\n
\n
\n
\n
\n \n
\n
\n
\n\n
\n\n
\n
\n
\n \n
\n
\n ' + show.rating.imdb.votes + ' Votes'\"\n >\n \n \n \n \n \n \"[trakt]\"\n \n \n \n \n\n \n \"[xem]\"\n \n\n \n \"[fanart.tv]\"\n \n
\n
\n
    \n
  • {{ genre }}
  • \n
\n
    \n
  • {{ genre }}
  • \n
\n
\n
\n\n
\n \n
\n
\n \n \n \n \n\n \n 0\">\n \n\n \n 0 && show.config.qualities.allowed\">\n \n\n 0 && combineQualities(show.config.qualities.preferred).length > 0\">\n \n\n \n \n \n \n \n \n\n 0\">\n \n \n \n\n 0\">\n \n \n \n 0\">\n \n \n \n\n 0\">\n \n \n \n 0\">\n \n \n \n\n 0\">\n \n \n \n\n 0\">\n \n \n \n\n \n \n \n \n -1\">\n \n \n \n
\n \n
Quality: \n \n
Quality allowed:\n \n
Quality preferred:\n \n
Originally Airs: {{ show.airs }} (invalid Timeformat) on {{ show.network }}
Originally Airs: {{ show.network }}
Originally Airs: {{ show.airs }} (invalid Timeformat)
Show Status: {{ show.status }}
Default EP Status: {{ show.config.defaultEpisodeStatus }}
Location: {{show.config.location}}{{show.config.locationValid ? '' : ' (Missing)'}}
Scene Name:{{show.config.aliases.join(',')}}
Required Words: {{show.config.release.requiredWords.join(',')}}
Ignored Words: {{show.config.release.ignoredWords.join(',')}}
Preferred Words: {{preferredWords.join(',')}}
Undesired Words: {{undesiredWords.join(',')}}
Wanted Groups:{{show.config.release.whitelist.join(',')}}
Unwanted Groups:{{show.config.release.blacklist.join(',')}}
Daily search offset:{{show.config.airdateOffset}} hours
Size:{{humanFileSize(show.size)}}
\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
Info Language:
Subtitles:
Season Folders:
Paused:
Air-by-Date:
Sports:
Anime:
DVD Order:
Scene Numbering:
\n
\n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n\n \n \n \n \n \n \n \n
\n
\n\n \n\n \n \n \n \n \n
\n
\n
\n
\n
\n
\n \n\n\n\n\n\n","// style-loader: Adds some css to the DOM by adding a \n","\n\n\n","const LOGIN_PENDING = '🔒 Logging in';\nconst LOGIN_SUCCESS = '🔒 ✅ Login Successful';\nconst LOGIN_FAILED = '🔒 ❌ Login Failed';\nconst LOGOUT = '🔒 Logout';\nconst REFRESH_TOKEN = '🔒 Refresh Token';\nconst REMOVE_AUTH_ERROR = '🔒 Remove Auth Error';\nconst SOCKET_ONOPEN = '🔗 ✅ WebSocket connected';\nconst SOCKET_ONCLOSE = '🔗 ❌ WebSocket disconnected';\nconst SOCKET_ONERROR = '🔗 ❌ WebSocket error';\nconst SOCKET_ONMESSAGE = '🔗 ✉️ 📥 WebSocket message received';\nconst SOCKET_RECONNECT = '🔗 🔃 WebSocket reconnecting';\nconst SOCKET_RECONNECT_ERROR = '🔗 🔃 ❌ WebSocket reconnection attempt failed';\nconst NOTIFICATIONS_ENABLED = '🔔 Notifications Enabled';\nconst NOTIFICATIONS_DISABLED = '🔔 Notifications Disabled';\nconst ADD_CONFIG = '⚙️ Config added to store';\nconst ADD_SHOW = '📺 Show added to store';\n\nexport {\n LOGIN_PENDING,\n LOGIN_SUCCESS,\n LOGIN_FAILED,\n LOGOUT,\n REFRESH_TOKEN,\n REMOVE_AUTH_ERROR,\n SOCKET_ONOPEN,\n SOCKET_ONCLOSE,\n SOCKET_ONERROR,\n SOCKET_ONMESSAGE,\n SOCKET_RECONNECT,\n SOCKET_RECONNECT_ERROR,\n NOTIFICATIONS_ENABLED,\n NOTIFICATIONS_DISABLED,\n ADD_CONFIG,\n ADD_SHOW\n};\n","import {\n LOGIN_PENDING,\n LOGIN_SUCCESS,\n LOGIN_FAILED,\n LOGOUT,\n REFRESH_TOKEN,\n REMOVE_AUTH_ERROR\n} from '../mutation-types';\n\nconst state = {\n isAuthenticated: false,\n user: {},\n tokens: {\n access: null,\n refresh: null\n },\n error: null\n};\n\nconst mutations = {\n [LOGIN_PENDING]() { },\n [LOGIN_SUCCESS](state, user) {\n state.user = user;\n state.isAuthenticated = true;\n state.error = null;\n },\n [LOGIN_FAILED](state, { error }) {\n state.user = {};\n state.isAuthenticated = false;\n state.error = error;\n },\n [LOGOUT](state) {\n state.user = {};\n state.isAuthenticated = false;\n state.error = null;\n },\n [REFRESH_TOKEN]() {},\n [REMOVE_AUTH_ERROR]() {}\n};\n\nconst getters = {};\n\nconst actions = {\n login(context, credentials) {\n const { commit } = context;\n commit(LOGIN_PENDING);\n\n // @TODO: Add real JWT login\n const apiLogin = credentials => Promise.resolve(credentials);\n\n apiLogin(credentials).then(user => {\n return commit(LOGIN_SUCCESS, user);\n }).catch(error => {\n commit(LOGIN_FAILED, { error, credentials });\n });\n },\n logout(context) {\n const { commit } = context;\n commit(LOGOUT);\n }\n};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { ADD_CONFIG } from '../mutation-types';\n\nconst state = {\n torrents: {\n authType: null,\n dir: null,\n enabled: null,\n highBandwidth: null,\n host: null,\n label: null,\n labelAnime: null,\n method: null,\n path: null,\n paused: null,\n rpcUrl: null,\n seedLocation: null,\n seedTime: null,\n username: null,\n password: null,\n verifySSL: null,\n testStatus: 'Click below to test'\n },\n nzb: {\n enabled: null,\n method: null,\n nzbget: {\n category: null,\n categoryAnime: null,\n categoryAnimeBacklog: null,\n categoryBacklog: null,\n host: null,\n priority: null,\n useHttps: null,\n username: null,\n password: null\n },\n sabnzbd: {\n category: null,\n forced: null,\n categoryAnime: null,\n categoryBacklog: null,\n categoryAnimeBacklog: null,\n host: null,\n username: null,\n password: null,\n apiKey: null\n }\n }\n};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'clients') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { api } from '../../api';\nimport { ADD_CONFIG } from '../mutation-types';\n\nconst state = {\n wikiUrl: null,\n donationsUrl: null,\n localUser: null,\n posterSortdir: null,\n locale: null,\n themeName: null,\n selectedRootIndex: null,\n webRoot: null,\n namingForceFolders: null,\n cacheDir: null,\n databaseVersion: {\n major: null,\n minor: null\n },\n programDir: null,\n dataDir: null,\n animeSplitHomeInTabs: null,\n torrents: {\n authType: null,\n dir: null,\n enabled: null,\n highBandwidth: null,\n host: null,\n label: null,\n labelAnime: null,\n method: null,\n path: null,\n paused: null,\n rpcurl: null,\n seedLocation: null,\n seedTime: null,\n username: null,\n verifySSL: null\n },\n layout: {\n show: {\n specials: null,\n showListOrder: [],\n allSeasons: null\n },\n home: null,\n history: null,\n schedule: null\n },\n dbPath: null,\n nzb: {\n enabled: null,\n method: null,\n nzbget: {\n category: null,\n categoryAnime: null,\n categoryAnimeBacklog: null,\n categoryBacklog: null,\n host: null,\n priority: null,\n useHttps: null,\n username: null\n },\n sabnzbd: {\n category: null,\n forced: null,\n categoryAnime: null,\n categoryBacklog: null,\n categoryAnimeBacklog: null,\n host: null,\n username: null,\n password: null,\n apiKey: null\n }\n },\n configFile: null,\n fanartBackground: null,\n trimZero: null,\n animeSplitHome: null,\n gitUsername: null,\n branch: null,\n commitHash: null,\n indexers: {\n config: {\n main: {\n externalMappings: {},\n statusMap: {},\n traktIndexers: {},\n validLanguages: [],\n langabbvToId: {}\n },\n indexers: {\n tvdb: {\n apiParams: {\n useZip: null,\n language: null\n },\n baseUrl: null,\n enabled: null,\n icon: null,\n id: null,\n identifier: null,\n mappedTo: null,\n name: null,\n scene_loc: null, // eslint-disable-line camelcase\n showUrl: null,\n xemOrigin: null\n },\n tmdb: {\n apiParams: {\n useZip: null,\n language: null\n },\n baseUrl: null,\n enabled: null,\n icon: null,\n id: null,\n identifier: null,\n mappedTo: null,\n name: null,\n scene_loc: null, // eslint-disable-line camelcase\n showUrl: null,\n xemOrigin: null\n },\n tvmaze: {\n apiParams: {\n useZip: null,\n language: null\n },\n baseUrl: null,\n enabled: null,\n icon: null,\n id: null,\n identifier: null,\n mappedTo: null,\n name: null,\n scene_loc: null, // eslint-disable-line camelcase\n showUrl: null,\n xemOrigin: null\n }\n }\n }\n },\n sourceUrl: null,\n rootDirs: [],\n fanartBackgroundOpacity: null,\n appArgs: [],\n comingEpsDisplayPaused: null,\n sortArticle: null,\n timePreset: null,\n subtitles: {\n enabled: null\n },\n fuzzyDating: null,\n backlogOverview: {\n status: null,\n period: null\n },\n posterSortby: null,\n news: {\n lastRead: null,\n latest: null,\n unread: null\n },\n logs: {\n loggingLevels: {},\n numErrors: null,\n numWarnings: null\n },\n failedDownloads: {\n enabled: null,\n deleteFailed: null\n },\n postProcessing: {\n naming: {\n pattern: null,\n multiEp: null,\n enableCustomNamingSports: null,\n enableCustomNamingAirByDate: null,\n patternSports: null,\n patternAirByDate: null,\n enableCustomNamingAnime: null,\n patternAnime: null,\n animeMultiEp: null,\n animeNamingType: null,\n stripYear: null\n },\n showDownloadDir: null,\n processAutomatically: null,\n processMethod: null,\n deleteRarContent: null,\n unpack: null,\n noDelete: null,\n reflinkAvailable: null,\n postponeIfSyncFiles: null,\n autoPostprocessorFrequency: 10,\n airdateEpisodes: null,\n moveAssociatedFiles: null,\n allowedExtensions: [],\n addShowsWithoutDir: null,\n createMissingShowDirs: null,\n renameEpisodes: null,\n postponeIfNoSubs: null,\n nfoRename: null,\n syncFiles: [],\n fileTimestampTimezone: 'local',\n extraScripts: [],\n extraScriptsUrl: null,\n multiEpStrings: {}\n },\n sslVersion: null,\n pythonVersion: null,\n comingEpsSort: null,\n githubUrl: null,\n datePreset: null,\n subtitlesMulti: null,\n pid: null,\n os: null,\n anonRedirect: null,\n logDir: null,\n recentShows: [],\n showDefaults: {\n status: null,\n statusAfter: null,\n quality: null,\n subtitles: null,\n seasonFolders: null,\n anime: null,\n scene: null\n }\n};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'main') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {\n layout: state => layout => {\n return state.layout[layout];\n }\n};\n\nconst actions = {\n getConfig(context, section) {\n const { commit } = context;\n return api.get('/config/' + (section || '')).then(res => {\n if (section) {\n const config = res.data;\n commit(ADD_CONFIG, { section, config });\n return config;\n }\n\n const sections = res.data;\n Object.keys(sections).forEach(section => {\n const config = sections[section];\n commit(ADD_CONFIG, { section, config });\n });\n return sections;\n });\n },\n setConfig(context, { section, config }) {\n if (section !== 'main') {\n return;\n }\n\n // If an empty config object was passed, use the current state config\n config = Object.keys(config).length === 0 ? context.state : config;\n\n return api.patch('config/' + section, config);\n },\n updateConfig(context, { section, config }) {\n const { commit } = context;\n return commit(ADD_CONFIG, { section, config });\n },\n setLayout(context, { page, layout }) {\n return api.patch('config/main', {\n layout: {\n [page]: layout\n }\n }).then(() => {\n setTimeout(() => {\n // For now we reload the page since the layouts use python still\n location.reload();\n }, 500);\n });\n }\n};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","const state = {\n show: {\n airs: null,\n airsFormatValid: null,\n akas: null,\n cache: null,\n classification: null,\n config: {\n airByDate: null,\n aliases: [],\n anime: null,\n defaultEpisodeStatus: null,\n dvdOrder: null,\n location: null,\n locationValid: null,\n paused: null,\n qualities: {\n allowed: [],\n preferred: []\n },\n release: {\n requiredWords: [],\n ignoredWords: [],\n blacklist: [],\n whitelist: [],\n allgroups: [],\n requiredWordsExclude: null,\n ignoredWordsExclude: null\n },\n scene: null,\n seasonFolders: null,\n sports: null,\n subtitlesEnabled: null,\n airdateOffset: null\n },\n countries: null,\n genres: [],\n id: {\n tvdb: null,\n slug: null\n },\n indexer: null,\n imdbInfo: {\n akas: null,\n certificates: null,\n countries: null,\n countryCodes: null,\n genres: null,\n imdbId: null,\n imdbInfoId: null,\n indexer: null,\n indexerId: null,\n lastUpdate: null,\n plot: null,\n rating: null,\n runtimes: null,\n title: null,\n votes: null\n },\n language: null,\n network: null,\n nextAirDate: null,\n plot: null,\n rating: {\n imdb: {\n rating: null,\n votes: null\n }\n },\n runtime: null,\n showType: null,\n status: null,\n title: null,\n type: null,\n year: {},\n size: null,\n showQueueStatus: [],\n xemNumbering: []\n }\n};\n\nconst mutations = {};\n\nconst getters = {};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { ADD_CONFIG } from '../mutation-types';\n\nconst state = {\n metadataProviders: {}\n};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'metadata') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { NOTIFICATIONS_ENABLED, NOTIFICATIONS_DISABLED } from '../mutation-types';\n\nconst state = {\n enabled: true\n};\n\nconst mutations = {\n [NOTIFICATIONS_ENABLED](state) {\n state.enabled = true;\n },\n [NOTIFICATIONS_DISABLED](state) {\n state.enabled = false;\n }\n};\n\nconst getters = {};\n\nconst actions = {\n enable(context) {\n const { commit } = context;\n commit(NOTIFICATIONS_ENABLED);\n },\n disable(context) {\n const { commit } = context;\n commit(NOTIFICATIONS_DISABLED);\n },\n test() {\n return window.displayNotification('error', 'test', 'test
hello world
  • item 1
  • item 2
', 'notification-test');\n }\n};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n accessToken: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n host: null,\n port: null,\n from: null,\n tls: null,\n username: null,\n password: null,\n addressList: [],\n subject: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n host: null,\n apiKey: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n host: null,\n password: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n alwaysOn: null,\n libraryCleanPending: null,\n cleanLibrary: null,\n host: [],\n username: null,\n password: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n update: {\n library: null,\n full: null,\n onlyFirst: null\n }\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n host: null,\n database: null,\n mount: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n host: null,\n dbloc: null,\n database: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n client: {\n host: [],\n username: null,\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null\n },\n server: {\n updateLibrary: null,\n host: [],\n enabled: null,\n https: null,\n username: null,\n password: null,\n token: null\n }\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n api: [],\n messageTitle: null,\n priority: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n authToken: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n authToken: null,\n device: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n api: null,\n device: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n apiKey: null,\n userKey: null,\n device: [],\n sound: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n host: null,\n name: null,\n shareName: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n webhook: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n api: null,\n id: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n pinUrl: null,\n username: null,\n accessToken: null,\n timeout: null,\n defaultIndexer: null,\n sync: null,\n syncRemove: null,\n syncWatchlist: null,\n methodAdd: null,\n removeWatchlist: null,\n removeSerieslist: null,\n removeShowFromApplication: null,\n startPaused: null,\n blacklistName: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n dmto: null,\n username: null,\n password: null,\n prefix: null,\n directMessage: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { ADD_CONFIG } from '../../mutation-types';\nimport boxcar2 from './boxcar2';\nimport email from './email';\nimport emby from './emby';\nimport growl from './growl';\nimport kodi from './kodi';\nimport libnotify from './libnotify';\nimport nmj from './nmj';\nimport nmjv2 from './nmjv2';\nimport plex from './plex';\nimport prowl from './prowl';\nimport pushalot from './pushalot';\nimport pushbullet from './pushbullet';\nimport join from './join';\nimport pushover from './pushover';\nimport pyTivo from './py-tivo';\nimport slack from './slack';\nimport synology from './synology';\nimport synologyIndex from './synology-index';\nimport telegram from './telegram';\nimport trakt from './trakt';\nimport twitter from './twitter';\n\nconst state = {};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'notifiers') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {};\n\nconst actions = {};\n\nconst modules = {\n boxcar2,\n email,\n emby,\n growl,\n kodi,\n libnotify,\n nmj,\n nmjv2,\n plex,\n prowl,\n pushalot,\n pushbullet,\n join,\n pushover,\n pyTivo,\n slack,\n synology,\n synologyIndex,\n telegram,\n trakt,\n twitter\n};\n\nexport default {\n state,\n mutations,\n getters,\n actions,\n modules\n};\n","import { ADD_CONFIG } from '../mutation-types';\n\nconst state = {\n values: {},\n anySets: {},\n presets: {},\n strings: {\n values: {},\n anySets: {},\n presets: {},\n cssClass: {}\n }\n};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'qualities') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {\n getPreset: state => value => {\n return Object.keys(state.presets)\n .filter(key => {\n return state.presets[key] === value;\n })\n .map(key => {\n return {\n [key]: state.presets[key]\n };\n });\n },\n combineQualities: () => qualities => {\n const reducer = (accumulator, currentValue) => accumulator | currentValue;\n return qualities.reduce(reducer, 0);\n }\n};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import Vue from 'vue';\nimport { api } from '../../api';\nimport { ADD_SHOW } from '../mutation-types';\n\nconst state = {\n shows: [],\n currentShow: {\n indexer: null,\n id: null\n }\n};\n\nconst mutations = {\n [ADD_SHOW](state, show) {\n const existingShow = state.shows.find(({ id, indexer }) => Number(show.id[show.indexer]) === Number(id[indexer]));\n\n if (!existingShow) {\n console.debug(`Adding ${show.title || show.indexer + String(show.id)} as it wasn't found in the shows array`, show);\n state.shows.push(show);\n return;\n }\n\n // Merge new show object over old one\n // this allows detailed queries to update the record\n // without the non-detailed removing the extra data\n console.debug(`Found ${show.title || show.indexer + String(show.id)} in shows array attempting merge`);\n const newShow = {\n ...existingShow,\n ...show\n };\n\n // Update state\n Vue.set(state.shows, state.shows.indexOf(existingShow), newShow);\n console.debug(`Merged ${newShow.title || newShow.indexer + String(newShow.id)}`, newShow);\n },\n currentShow(state, { indexer, id }) {\n state.currentShow.indexer = indexer;\n state.currentShow.id = id;\n }\n};\n\nconst getters = {\n getShowById: state => ({ id, indexer }) => state.shows.find(show => Number(show.id[indexer]) === Number(id)),\n getShowByTitle: state => title => state.shows.find(show => show.title === title),\n getSeason: state => ({ id, indexer, season }) => {\n const show = state.shows.find(show => Number(show.id[indexer]) === Number(id));\n return show && show.seasons ? show.seasons[season] : undefined;\n },\n getEpisode: state => ({ id, indexer, season, episode }) => {\n const show = state.shows.find(show => Number(show.id[indexer]) === Number(id));\n return show && show.seasons && show.seasons[season] ? show.seasons[season][episode] : undefined;\n },\n getCurrentShow: (state, getters, rootState) => {\n return state.shows.find(show => Number(show.id[state.currentShow.indexer]) === Number(state.currentShow.id)) || rootState.defaults.show;\n }\n};\n\n/**\n * An object representing request parameters for getting a show from the API.\n *\n * @typedef {Object} ShowParameteres\n * @property {string} indexer - The indexer name (e.g. `tvdb`)\n * @property {string} id - The show ID on the indexer (e.g. `12345`)\n * @property {boolean} detailed - Whether to fetch detailed information (seasons & episodes)\n * @property {boolean} fetch - Whether to fetch external information (for example AniDB release groups)\n */\nconst actions = {\n /**\n * Get show from API and commit it to the store.\n *\n * @param {*} context - The store context.\n * @param {ShowParameteres} parameters - Request parameters.\n * @returns {Promise} The API response.\n */\n getShow(context, { indexer, id, detailed, fetch }) {\n return new Promise((resolve, reject) => {\n const { commit } = context;\n const params = {};\n\n if (detailed !== undefined) {\n params.detailed = Boolean(detailed);\n }\n\n if (fetch !== undefined) {\n params.fetch = Boolean(fetch);\n }\n\n api.get('/series/' + indexer + id, { params })\n .then(res => {\n commit(ADD_SHOW, res.data);\n resolve(res.data);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n /**\n * Get shows from API and commit them to the store.\n *\n * @param {*} context - The store context.\n * @param {ShowParameteres[]} shows - Shows to get. If not provided, gets the first 10k shows.\n * @returns {(undefined|Promise)} undefined if `shows` was provided or the API response if not.\n */\n getShows(context, shows) {\n const { commit, dispatch } = context;\n\n // If no shows are provided get the first 1000\n if (!shows) {\n return (() => {\n const limit = 1000;\n const page = 1;\n const params = {\n limit,\n page\n };\n\n // Get first page\n api.get('/series', { params })\n .then(response => {\n const totalPages = Number(response.headers['x-pagination-total']);\n response.data.forEach(show => {\n commit(ADD_SHOW, show);\n });\n\n // Optionally get additional pages\n const pageRequests = [];\n for (let page = 2; page <= totalPages; page++) {\n const newPage = { page };\n newPage.limit = params.limit;\n pageRequests.push(api.get('/series', { params: newPage }).then(response => {\n response.data.forEach(show => {\n commit(ADD_SHOW, show);\n });\n }));\n }\n\n return Promise.all(pageRequests);\n })\n .catch(() => {\n console.log('Could not retrieve a list of shows');\n });\n })();\n }\n\n return shows.forEach(show => dispatch('getShow', show));\n }\n};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { ADD_CONFIG } from '../mutation-types';\n\nconst state = {\n filters: {\n ignoreUnknownSubs: false,\n ignored: [\n 'german',\n 'french',\n 'core2hd',\n 'dutch',\n 'swedish',\n 'reenc',\n 'MrLss',\n 'dubbed'\n ],\n undesired: [\n 'internal',\n 'xvid'\n ],\n ignoredSubsList: [\n 'dk',\n 'fin',\n 'heb',\n 'kor',\n 'nor',\n 'nordic',\n 'pl',\n 'swe'\n ],\n required: [],\n preferred: []\n },\n general: {\n minDailySearchFrequency: 10,\n minBacklogFrequency: 720,\n dailySearchFrequency: 40,\n checkPropersInterval: '4h',\n usenetRetention: 500,\n maxCacheAge: 30,\n backlogDays: 7,\n torrentCheckerFrequency: 60,\n backlogFrequency: 720,\n cacheTrimming: false,\n deleteFailed: false,\n downloadPropers: true,\n useFailedDownloads: false,\n minTorrentCheckerFrequency: 30,\n removeFromClient: false,\n randomizeProviders: false,\n propersSearchDays: 2,\n allowHighPriority: true,\n trackersList: [\n 'udp://tracker.coppersurfer.tk:6969/announce',\n 'udp://tracker.leechers-paradise.org:6969/announce',\n 'udp://tracker.zer0day.to:1337/announce',\n 'udp://tracker.opentrackr.org:1337/announce',\n 'http://tracker.opentrackr.org:1337/announce',\n 'udp://p4p.arenabg.com:1337/announce',\n 'http://p4p.arenabg.com:1337/announce',\n 'udp://explodie.org:6969/announce',\n 'udp://9.rarbg.com:2710/announce',\n 'http://explodie.org:6969/announce',\n 'http://tracker.dler.org:6969/announce',\n 'udp://public.popcorn-tracker.org:6969/announce',\n 'udp://tracker.internetwarriors.net:1337/announce',\n 'udp://ipv4.tracker.harry.lu:80/announce',\n 'http://ipv4.tracker.harry.lu:80/announce',\n 'udp://mgtracker.org:2710/announce',\n 'http://mgtracker.org:6969/announce',\n 'udp://tracker.mg64.net:6969/announce',\n 'http://tracker.mg64.net:6881/announce',\n 'http://torrentsmd.com:8080/announce'\n ]\n }\n};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'search') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import {\n SOCKET_ONOPEN,\n SOCKET_ONCLOSE,\n SOCKET_ONERROR,\n SOCKET_ONMESSAGE,\n SOCKET_RECONNECT,\n SOCKET_RECONNECT_ERROR\n} from '../mutation-types';\n\nconst state = {\n isConnected: false,\n // Current message\n message: {},\n // Delivered messages for this session\n messages: [],\n reconnectError: false\n};\n\nconst mutations = {\n [SOCKET_ONOPEN](state) {\n state.isConnected = true;\n },\n [SOCKET_ONCLOSE](state) {\n state.isConnected = false;\n },\n [SOCKET_ONERROR](state, event) {\n console.error(state, event);\n },\n // Default handler called for all websocket methods\n [SOCKET_ONMESSAGE](state, message) {\n const { data, event } = message;\n\n // Set the current message\n state.message = message;\n\n if (event === 'notification') {\n // Save it so we can look it up later\n const existingMessage = state.messages.filter(message => message.hash === data.hash);\n if (existingMessage.length === 1) {\n state.messages[state.messages.indexOf(existingMessage)] = message;\n } else {\n state.messages.push(message);\n }\n }\n },\n // Mutations for websocket reconnect methods\n [SOCKET_RECONNECT](state, count) {\n console.info(state, count);\n },\n [SOCKET_RECONNECT_ERROR](state) {\n state.reconnectError = true;\n\n const title = 'Error connecting to websocket';\n let error = '';\n error += 'Please check your network connection. ';\n error += 'If you are using a reverse proxy, please take a look at our wiki for config examples.';\n\n window.displayNotification('notice', title, error);\n }\n};\n\nconst getters = {};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { ADD_CONFIG } from '../mutation-types';\n\nconst state = {\n values: {},\n strings: {}\n};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'statuses') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import Vue from 'vue';\nimport Vuex from 'vuex';\nimport VueNativeSock from 'vue-native-websocket';\nimport {\n auth,\n clients,\n config,\n defaults,\n metadata,\n notifications,\n notifiers,\n qualities,\n search,\n shows,\n socket,\n statuses\n} from './modules';\nimport {\n SOCKET_ONOPEN,\n SOCKET_ONCLOSE,\n SOCKET_ONERROR,\n SOCKET_ONMESSAGE,\n SOCKET_RECONNECT,\n SOCKET_RECONNECT_ERROR\n} from './mutation-types';\n\nconst { Store } = Vuex;\n\nVue.use(Vuex);\n\nconst store = new Store({\n modules: {\n auth,\n clients,\n config,\n defaults,\n metadata,\n notifications,\n notifiers,\n qualities,\n search,\n shows,\n socket,\n statuses\n },\n state: {},\n mutations: {},\n getters: {},\n actions: {}\n});\n\n// Keep as a non-arrow function for `this` context.\nconst passToStoreHandler = function(eventName, event, next) {\n const target = eventName.toUpperCase();\n const eventData = event.data;\n\n if (target === 'SOCKET_ONMESSAGE') {\n const message = JSON.parse(eventData);\n const { data, event } = message;\n\n // Show the notification to the user\n if (event === 'notification') {\n const { body, hash, type, title } = data;\n window.displayNotification(type, title, body, hash);\n } else if (event === 'configUpdated') {\n const { section, config } = data;\n this.store.dispatch('updateConfig', { section, config });\n } else {\n window.displayNotification('info', event, data);\n }\n }\n\n // Resume normal 'passToStore' handling\n next(eventName, event);\n};\n\nconst websocketUrl = (() => {\n const { protocol, host } = window.location;\n const proto = protocol === 'https:' ? 'wss:' : 'ws:';\n const WSMessageUrl = '/ui';\n const webRoot = document.body.getAttribute('web-root');\n return `${proto}//${host}${webRoot}/ws${WSMessageUrl}`;\n})();\n\nVue.use(VueNativeSock, websocketUrl, {\n store,\n format: 'json',\n reconnection: true, // (Boolean) whether to reconnect automatically (false)\n reconnectionAttempts: 2, // (Number) number of reconnection attempts before giving up (Infinity),\n reconnectionDelay: 1000, // (Number) how long to initially wait before attempting a new (1000)\n passToStoreHandler, // (Function|) Handler for events triggered by the WebSocket (false)\n mutations: {\n SOCKET_ONOPEN,\n SOCKET_ONCLOSE,\n SOCKET_ONERROR,\n SOCKET_ONMESSAGE,\n SOCKET_RECONNECT,\n SOCKET_RECONNECT_ERROR\n }\n});\n\nexport default store;\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('iframe',{staticClass:\"irc-frame loading-spinner\",attrs:{\"src\":_vm.frameSrc}})}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./irc.vue?vue&type=template&id=60f89f30&scoped=true&\"\nimport script from \"./irc.vue?vue&type=script&lang=js&\"\nexport * from \"./irc.vue?vue&type=script&lang=js&\"\nimport style0 from \"./irc.vue?vue&type=style&index=0&id=60f89f30&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"60f89f30\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"addShowPortal\"}},[_c('app-link',{staticClass:\"btn-medusa btn-large\",attrs:{\"href\":\"addShows/trendingShows/?traktList=anticipated\",\"id\":\"btnNewShow\"}},[_c('div',{staticClass:\"button\"},[_c('div',{staticClass:\"add-list-icon-addtrakt\"})]),_vm._v(\" \"),_c('div',{staticClass:\"buttontext\"},[_c('h3',[_vm._v(\"Add From Trakt Lists\")]),_vm._v(\" \"),_c('p',[_vm._v(\"For shows that you haven't downloaded yet, this option lets you choose from a show from one of the Trakt lists to add to Medusa .\")])])]),_vm._v(\" \"),_c('app-link',{staticClass:\"btn-medusa btn-large\",attrs:{\"href\":\"addShows/popularShows/\",\"id\":\"btnNewShow\"}},[_c('div',{staticClass:\"button\"},[_c('div',{staticClass:\"add-list-icon-addimdb\"})]),_vm._v(\" \"),_c('div',{staticClass:\"buttontext\"},[_c('h3',[_vm._v(\"Add From IMDB's Popular Shows\")]),_vm._v(\" \"),_c('p',[_vm._v(\"View IMDB's list of the most popular shows. This feature uses IMDB's MOVIEMeter algorithm to identify popular TV Shows.\")])])]),_vm._v(\" \"),_c('app-link',{staticClass:\"btn-medusa btn-large\",attrs:{\"href\":\"addShows/popularAnime/\",\"id\":\"btnNewShow\"}},[_c('div',{staticClass:\"button\"},[_c('div',{staticClass:\"add-list-icon-addanime\"})]),_vm._v(\" \"),_c('div',{staticClass:\"buttontext\"},[_c('h3',[_vm._v(\"Add From Anidb's Hot Anime list\")]),_vm._v(\" \"),_c('p',[_vm._v(\"View Anidb's list of the most popular anime shows. Anidb provides lists for Popular Anime, using the \\\"Hot Anime\\\" list.\")])])])],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-recommended.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-recommended.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./add-recommended.vue?vue&type=template&id=b4192aae&\"\nimport script from \"./add-recommended.vue?vue&type=script&lang=js&\"\nexport * from \"./add-recommended.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _vm._m(0)}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"login\"},[_c('form',{attrs:{\"action\":\"\",\"method\":\"post\"}},[_c('h1',[_vm._v(\"Medusa\")]),_vm._v(\" \"),_c('div',{staticClass:\"ctrlHolder\"},[_c('input',{staticClass:\"inlay\",attrs:{\"name\":\"username\",\"type\":\"text\",\"placeholder\":\"Username\",\"autocomplete\":\"off\"}})]),_vm._v(\" \"),_c('div',{staticClass:\"ctrlHolder\"},[_c('input',{staticClass:\"inlay\",attrs:{\"name\":\"password\",\"type\":\"password\",\"placeholder\":\"Password\",\"autocomplete\":\"off\"}})]),_vm._v(\" \"),_c('div',{staticClass:\"ctrlHolder\"},[_c('label',{staticClass:\"remember_me\",attrs:{\"title\":\"for 30 days\"}},[_c('input',{staticClass:\"inlay\",attrs:{\"id\":\"remember_me\",\"name\":\"remember_me\",\"type\":\"checkbox\",\"value\":\"1\",\"checked\":\"checked\"}}),_vm._v(\" Remember me\")]),_vm._v(\" \"),_c('input',{staticClass:\"button\",attrs:{\"name\":\"submit\",\"type\":\"submit\",\"value\":\"Login\"}})])])])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./login.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./login.vue?vue&type=script&lang=js&\"","\n\n\n\n\n","import { render, staticRenderFns } from \"./login.vue?vue&type=template&id=1f239a7a&\"\nimport script from \"./login.vue?vue&type=script&lang=js&\"\nexport * from \"./login.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"addShowPortal\"}},[_c('app-link',{staticClass:\"btn-medusa btn-large\",attrs:{\"href\":\"addShows/newShow/\",\"id\":\"btnNewShow\"}},[_c('div',{staticClass:\"button\"},[_c('div',{staticClass:\"add-list-icon-addnewshow\"})]),_vm._v(\" \"),_c('div',{staticClass:\"buttontext\"},[_c('h3',[_vm._v(\"Add New Show\")]),_vm._v(\" \"),_c('p',[_vm._v(\"For shows that you haven't downloaded yet, this option finds a show on your preferred indexer, creates a directory for it's episodes, and adds it to Medusa.\")])])]),_vm._v(\" \"),_c('app-link',{staticClass:\"btn-medusa btn-large\",attrs:{\"href\":\"addShows/existingShows/\",\"id\":\"btnExistingShow\"}},[_c('div',{staticClass:\"button\"},[_c('div',{staticClass:\"add-list-icon-addexistingshow\"})]),_vm._v(\" \"),_c('div',{staticClass:\"buttontext\"},[_c('h3',[_vm._v(\"Add Existing Shows\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Use this option to add shows that already have a folder created on your hard drive. Medusa will scan your existing metadata/episodes and add the show accordingly.\")])])])],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-shows.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-shows.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./add-shows.vue?vue&type=template&id=3f2dd7ac&\"\nimport script from \"./add-shows.vue?vue&type=script&lang=js&\"\nexport * from \"./add-shows.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"config-content\"}},[_c('table',{staticClass:\"infoTable\",attrs:{\"cellspacing\":\"1\",\"border\":\"0\",\"cellpadding\":\"0\",\"width\":\"100%\"}},[_c('tr',[_vm._m(0),_vm._v(\" \"),_c('td',[_vm._v(\"\\n Branch:\\n \"),(_vm.config.branch)?_c('span',[_c('app-link',{attrs:{\"href\":_vm.config.sourceUrl + '/tree/' + _vm.config.branch}},[_vm._v(_vm._s(_vm.config.branch))])],1):_c('span',[_vm._v(\"Unknown\")]),_vm._v(\" \"),_c('br'),_vm._v(\"\\n Commit:\\n \"),(_vm.config.commitHash)?_c('span',[_c('app-link',{attrs:{\"href\":_vm.config.sourceUrl + '/commit/' + _vm.config.commitHash}},[_vm._v(_vm._s(_vm.config.commitHash))])],1):_c('span',[_vm._v(\"Unknown\")]),_vm._v(\" \"),_c('br'),_vm._v(\"\\n Version:\\n \"),(_vm.config.release)?_c('span',[_c('app-link',{attrs:{\"href\":_vm.config.sourceUrl + '/releases/tag/' + _vm.config.release}},[_vm._v(_vm._s(_vm.config.release))])],1):_c('span',[_vm._v(\"Unknown\")]),_vm._v(\" \"),_c('br'),_vm._v(\"\\n Database:\\n \"),(_vm.config.databaseVersion)?_c('span',[_vm._v(_vm._s(_vm.config.databaseVersion.major)+\".\"+_vm._s(_vm.config.databaseVersion.minor))]):_c('span',[_vm._v(\"Unknown\")])])]),_vm._v(\" \"),_c('tr',[_vm._m(1),_c('td',[_vm._v(_vm._s(_vm.config.pythonVersion))])]),_vm._v(\" \"),_c('tr',[_vm._m(2),_c('td',[_vm._v(_vm._s(_vm.config.sslVersion))])]),_vm._v(\" \"),_c('tr',[_vm._m(3),_c('td',[_vm._v(_vm._s(_vm.config.os))])]),_vm._v(\" \"),_c('tr',[_vm._m(4),_c('td',[_vm._v(_vm._s(_vm.config.locale))])]),_vm._v(\" \"),_vm._m(5),_vm._v(\" \"),_vm._m(6),_vm._v(\" \"),_c('tr',[_vm._m(7),_c('td',[_vm._v(_vm._s(_vm.config.localUser))])]),_vm._v(\" \"),_c('tr',[_vm._m(8),_c('td',[_vm._v(_vm._s(_vm.config.programDir))])]),_vm._v(\" \"),_c('tr',[_vm._m(9),_c('td',[_vm._v(_vm._s(_vm.config.configFile))])]),_vm._v(\" \"),_c('tr',[_vm._m(10),_c('td',[_vm._v(_vm._s(_vm.config.dbPath))])]),_vm._v(\" \"),_c('tr',[_vm._m(11),_c('td',[_vm._v(_vm._s(_vm.config.cacheDir))])]),_vm._v(\" \"),_c('tr',[_vm._m(12),_c('td',[_vm._v(_vm._s(_vm.config.logDir))])]),_vm._v(\" \"),(_vm.config.appArgs)?_c('tr',[_vm._m(13),_c('td',[_c('pre',[_vm._v(_vm._s(_vm._f(\"prettyPrintJSON\")(_vm.config.appArgs)))])])]):_vm._e(),_vm._v(\" \"),(_vm.config.webRoot)?_c('tr',[_vm._m(14),_c('td',[_vm._v(_vm._s(_vm.config.webRoot))])]):_vm._e(),_vm._v(\" \"),(_vm.config.runsInDocker)?_c('tr',[_vm._m(15),_c('td',[_vm._v(_vm._s(_vm.config.runsInDocker ? 'yes' : 'no'))])]):_vm._e(),_vm._v(\" \"),_vm._m(16),_vm._v(\" \"),_vm._m(17),_vm._v(\" \"),_c('tr',[_vm._m(18),_c('td',[_c('app-link',{attrs:{\"href\":_vm.config.githubUrl}},[_vm._v(_vm._s(_vm.config.githubUrl))])],1)]),_vm._v(\" \"),_c('tr',[_vm._m(19),_c('td',[_c('app-link',{attrs:{\"href\":_vm.config.wikiUrl}},[_vm._v(_vm._s(_vm.config.wikiUrl))])],1)]),_vm._v(\" \"),_c('tr',[_vm._m(20),_c('td',[_c('app-link',{attrs:{\"href\":_vm.config.sourceUrl}},[_vm._v(_vm._s(_vm.config.sourceUrl))])],1)]),_vm._v(\" \"),_c('tr',[_vm._m(21),_c('td',[_c('app-link',{attrs:{\"href\":\"irc://irc.freenode.net/#pymedusa\"}},[_c('i',[_vm._v(\"#pymedusa\")]),_vm._v(\" on \"),_c('i',[_vm._v(\"irc.freenode.net\")])])],1)])])])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-application\"}),_vm._v(\" Medusa Info:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-python\"}),_vm._v(\" Python Version:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-ssl\"}),_vm._v(\" SSL Version:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-os\"}),_vm._v(\" OS:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-locale\"}),_vm._v(\" Locale:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_c('td',[_vm._v(\" \")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"infoTableSeperator\"},[_c('td',[_vm._v(\" \")]),_c('td',[_vm._v(\" \")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-user\"}),_vm._v(\" User:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-dir\"}),_vm._v(\" Program Folder:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-config\"}),_vm._v(\" Config File:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-db\"}),_vm._v(\" Database File:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-cache\"}),_vm._v(\" Cache Folder:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-log\"}),_vm._v(\" Log Folder:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-arguments\"}),_vm._v(\" Arguments:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-dir\"}),_vm._v(\" Web Root:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-docker\"}),_vm._v(\" Runs in docker:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_c('td',[_vm._v(\" \")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"infoTableSeperator\"},[_c('td',[_vm._v(\" \")]),_c('td',[_vm._v(\" \")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-web\"}),_vm._v(\" Website:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-wiki\"}),_vm._v(\" Wiki:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-github\"}),_vm._v(\" Source:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-mirc\"}),_vm._v(\" IRC Chat:\")])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./config.vue?vue&type=template&id=2ad9ae57&\"\nimport script from \"./config.vue?vue&type=script&lang=js&\"\nexport * from \"./config.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"align-center\"},[_vm._v(\"You have reached this page by accident, please check the url.\")])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./404.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./404.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./404.vue?vue&type=template&id=3cfbf450&\"\nimport script from \"./404.vue?vue&type=script&lang=js&\"\nexport * from \"./404.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"config\"}},[_c('div',{attrs:{\"id\":\"config-content\"}},[_c('form',{staticClass:\"form-horizontal\",attrs:{\"id\":\"configForm\"},on:{\"submit\":function($event){$event.preventDefault();return _vm.save()}}},[_c('div',{attrs:{\"id\":\"config-components\"}},[_c('ul',[_c('li',[_c('app-link',{attrs:{\"href\":\"#post-processing\"}},[_vm._v(\"Post Processing\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"#episode-naming\"}},[_vm._v(\"Episode Naming\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"#metadata\"}},[_vm._v(\"Metadata\")])],1)]),_vm._v(\" \"),_c('div',{attrs:{\"id\":\"post-processing\"}},[_c('div',{staticClass:\"row component-group\"},[_vm._m(0),_vm._v(\" \"),_c('div',{staticClass:\"col-xs-12 col-md-10\"},[_c('fieldset',{staticClass:\"component-group-list\"},[_c('div',{staticClass:\"form-group\"},[_vm._m(1),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"process_automatically\",\"name\":\"process_automatically\",\"sync\":\"\"},model:{value:(_vm.postProcessing.processAutomatically),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"processAutomatically\", $$v)},expression:\"postProcessing.processAutomatically\"}}),_vm._v(\" \"),_vm._m(2),_vm._v(\" \"),_vm._m(3)],1)]),_vm._v(\" \"),_c('div',{directives:[{name:\"show\",rawName:\"v-show\",value:(_vm.postProcessing.processAutomatically),expression:\"postProcessing.processAutomatically\"}],attrs:{\"id\":\"post-process-toggle-wrapper\"}},[_c('div',{staticClass:\"form-group\"},[_vm._m(4),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('file-browser',{attrs:{\"id\":\"tv_download_dir\",\"name\":\"tv_download_dir\",\"title\":\"Select series download location\",\"initial-dir\":_vm.postProcessing.showDownloadDir},on:{\"update\":function($event){_vm.postProcessing.showDownloadDir = $event}}}),_vm._v(\" \"),_c('span',{staticClass:\"clear-left\"},[_vm._v(\"The folder where your download client puts the completed TV downloads.\")]),_vm._v(\" \"),_vm._m(5)],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(6),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.postProcessing.processMethod),expression:\"postProcessing.processMethod\"}],staticClass:\"form-control input-sm\",attrs:{\"id\":\"naming_multi_ep\",\"name\":\"naming_multi_ep\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.$set(_vm.postProcessing, \"processMethod\", $event.target.multiple ? $$selectedVal : $$selectedVal[0])}}},_vm._l((_vm.processMethods),function(option){return _c('option',{key:option.value,domProps:{\"value\":option.value}},[_vm._v(_vm._s(option.text))])}),0),_vm._v(\" \"),_c('span',[_vm._v(\"What method should be used to put files into the library?\")]),_vm._v(\" \"),_vm._m(7),_vm._v(\" \"),(_vm.postProcessing.processMethod == 'reflink')?_c('p',[_vm._v(\"To use reference linking, the \"),_c('app-link',{attrs:{\"href\":\"http://www.dereferer.org/?https://pypi.python.org/pypi/reflink/0.1.4\"}},[_vm._v(\"reflink package\")]),_vm._v(\" needs to be installed.\")],1):_vm._e()])]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(8),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model.number\",value:(_vm.postProcessing.autoPostprocessorFrequency),expression:\"postProcessing.autoPostprocessorFrequency\",modifiers:{\"number\":true}}],staticClass:\"form-control input-sm input75\",attrs:{\"type\":\"number\",\"min\":\"10\",\"step\":\"1\",\"name\":\"autopostprocessor_frequency\",\"id\":\"autopostprocessor_frequency\"},domProps:{\"value\":(_vm.postProcessing.autoPostprocessorFrequency)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.$set(_vm.postProcessing, \"autoPostprocessorFrequency\", _vm._n($event.target.value))},\"blur\":function($event){return _vm.$forceUpdate()}}}),_vm._v(\" \"),_c('span',[_vm._v(\"Time in minutes to check for new files to auto post-process (min 10)\")])])])])])])]),_vm._v(\" \"),_c('div',{staticClass:\"row component-group\"},[_vm._m(9),_vm._v(\" \"),_c('div',{staticClass:\"col-xs-12 col-md-10\"},[_c('fieldset',{staticClass:\"component-group-list\"},[_c('div',{staticClass:\"form-group\"},[_vm._m(10),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"postpone_if_sync_files\",\"name\":\"postpone_if_sync_files\",\"sync\":\"\"},model:{value:(_vm.postProcessing.postponeIfSyncFiles),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"postponeIfSyncFiles\", $$v)},expression:\"postProcessing.postponeIfSyncFiles\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Wait to process a folder if sync files are present.\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(11),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select-list',{attrs:{\"name\":\"sync_files\",\"id\":\"sync_files\",\"csv-enabled\":\"\",\"list-items\":_vm.postProcessing.syncFiles},on:{\"change\":_vm.onChangeSyncFiles}}),_vm._v(\" \"),_c('span',[_vm._v(\"comma seperated list of extensions or filename globs Medusa ignores when Post Processing\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(12),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"postpone_if_no_subs\",\"name\":\"postpone_if_no_subs\",\"sync\":\"\"},model:{value:(_vm.postProcessing.postponeIfNoSubs),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"postponeIfNoSubs\", $$v)},expression:\"postProcessing.postponeIfNoSubs\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Wait to process a file until subtitles are present\")]),_c('br'),_vm._v(\" \"),_c('span',[_vm._v(\"Language names are allowed in subtitle filename (en.srt, pt-br.srt, ita.srt, etc.)\")]),_c('br'),_vm._v(\" \"),_vm._m(13),_c('br'),_vm._v(\" \"),_c('span',[_vm._v(\"If you have any active show with subtitle search disabled, you must enable Automatic post processor.\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(14),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"rename_episodes\",\"name\":\"rename_episodes\",\"sync\":\"\"},model:{value:(_vm.postProcessing.renameEpisodes),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"renameEpisodes\", $$v)},expression:\"postProcessing.renameEpisodes\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Rename episode using the Episode Naming settings?\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(15),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"create_missing_show_dirs\",\"name\":\"create_missing_show_dirs\",\"sync\":\"\"},model:{value:(_vm.postProcessing.createMissingShowDirs),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"createMissingShowDirs\", $$v)},expression:\"postProcessing.createMissingShowDirs\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Create missing show directories when they get deleted\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(16),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"add_shows_wo_dir\",\"name\":\"add_shows_wo_dir\",\"sync\":\"\"},model:{value:(_vm.postProcessing.addShowsWithoutDir),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"addShowsWithoutDir\", $$v)},expression:\"postProcessing.addShowsWithoutDir\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Add shows without creating a directory (not recommended)\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(17),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"move_associated_files\",\"name\":\"move_associated_files\",\"sync\":\"\"},model:{value:(_vm.postProcessing.moveAssociatedFiles),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"moveAssociatedFiles\", $$v)},expression:\"postProcessing.moveAssociatedFiles\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Delete srt/srr/sfv/etc files while post processing?\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(18),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select-list',{attrs:{\"name\":\"allowed_extensions\",\"id\":\"allowed_extensions\",\"csv-enabled\":\"\",\"list-items\":_vm.postProcessing.allowedExtensions},on:{\"change\":_vm.onChangeAllowedExtensions}}),_vm._v(\" \"),_c('span',[_vm._v(\"Comma seperated list of associated file extensions Medusa should keep while post processing.\")]),_c('br'),_vm._v(\" \"),_c('span',[_vm._v(\"Leaving it empty means all associated files will be deleted\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(19),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"nfo_rename\",\"name\":\"nfo_rename\",\"sync\":\"\"},model:{value:(_vm.postProcessing.nfoRename),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"nfoRename\", $$v)},expression:\"postProcessing.nfoRename\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Rename the original .nfo file to .nfo-orig to avoid conflicts?\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(20),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"airdate_episodes\",\"name\":\"airdate_episodes\",\"sync\":\"\"},model:{value:(_vm.postProcessing.airdateEpisodes),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"airdateEpisodes\", $$v)},expression:\"postProcessing.airdateEpisodes\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Set last modified filedate to the date that the episode aired?\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(21),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.postProcessing.fileTimestampTimezone),expression:\"postProcessing.fileTimestampTimezone\"}],staticClass:\"form-control input-sm\",attrs:{\"id\":\"file_timestamp_timezone\",\"name\":\"file_timestamp_timezone\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.$set(_vm.postProcessing, \"fileTimestampTimezone\", $event.target.multiple ? $$selectedVal : $$selectedVal[0])}}},_vm._l((_vm.timezoneOptions),function(option){return _c('option',{key:option.value,domProps:{\"value\":option.value}},[_vm._v(_vm._s(option.text))])}),0),_vm._v(\" \"),_c('span',[_vm._v(\"What timezone should be used to change File Date?\")])])]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(22),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"unpack\",\"name\":\"unpack\",\"sync\":\"\"},model:{value:(_vm.postProcessing.unpack),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"unpack\", $$v)},expression:\"postProcessing.unpack\"}}),_vm._v(\" \"),_vm._m(23),_c('br'),_vm._v(\" \"),_vm._m(24)],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(25),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"del_rar_contents\",\"name\":\"del_rar_contents\",\"sync\":\"\"},model:{value:(_vm.postProcessing.deleteRarContent),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"deleteRarContent\", $$v)},expression:\"postProcessing.deleteRarContent\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Delete content of RAR files, even if Process Method not set to move?\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(26),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"no_delete\",\"name\":\"no_delete\",\"sync\":\"\"},model:{value:(_vm.postProcessing.noDelete),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"noDelete\", $$v)},expression:\"postProcessing.noDelete\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Leave empty folders when Post Processing?\")]),_c('br'),_vm._v(\" \"),_vm._m(27)],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(28),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select-list',{attrs:{\"name\":\"extra_scripts\",\"id\":\"extra_scripts\",\"csv-enabled\":\"\",\"list-items\":_vm.postProcessing.extraScripts},on:{\"change\":_vm.onChangeExtraScripts}}),_vm._v(\" \"),_c('span',[_vm._v(\"See \"),_c('app-link',{staticClass:\"wikie\",attrs:{\"href\":_vm.postProcessing.extraScriptsUrl}},[_c('strong',[_vm._v(\"Wiki\")])]),_vm._v(\" for script arguments description and usage.\")],1)],1)])]),_vm._v(\" \"),_c('input',{staticClass:\"btn-medusa config_submitter\",attrs:{\"type\":\"submit\",\"value\":\"Save Changes\"}})])])]),_vm._v(\" \"),_c('div',{attrs:{\"id\":\"episode-naming\"}},[_c('div',{staticClass:\"row component-group\"},[_vm._m(29),_vm._v(\" \"),_c('div',{staticClass:\"col-xs-12 col-md-10\"},[_c('fieldset',{staticClass:\"component-group-list\"},[_c('name-pattern',{staticClass:\"component-item\",attrs:{\"naming-pattern\":_vm.postProcessing.naming.pattern,\"naming-presets\":_vm.presets,\"multi-ep-style\":_vm.postProcessing.naming.multiEp,\"multi-ep-styles\":_vm.multiEpStringsSelect,\"flag-loaded\":_vm.configLoaded},on:{\"change\":_vm.saveNaming}}),_vm._v(\" \"),_c('name-pattern',{staticClass:\"component-item\",attrs:{\"enabled\":_vm.postProcessing.naming.enableCustomNamingSports,\"naming-pattern\":_vm.postProcessing.naming.patternSports,\"naming-presets\":_vm.presets,\"type\":\"sports\",\"enabled-naming-custom\":_vm.postProcessing.naming.enableCustomNamingSports,\"flag-loaded\":_vm.configLoaded},on:{\"change\":_vm.saveNamingSports}}),_vm._v(\" \"),_c('name-pattern',{staticClass:\"component-item\",attrs:{\"enabled\":_vm.postProcessing.naming.enableCustomNamingAirByDate,\"naming-pattern\":_vm.postProcessing.naming.patternAirByDate,\"naming-presets\":_vm.presets,\"type\":\"airs by date\",\"enabled-naming-custom\":_vm.postProcessing.naming.enableCustomNamingAirByDate,\"flag-loaded\":_vm.configLoaded},on:{\"change\":_vm.saveNamingAbd}}),_vm._v(\" \"),_c('name-pattern',{staticClass:\"component-item\",attrs:{\"enabled\":_vm.postProcessing.naming.enableCustomNamingAnime,\"naming-pattern\":_vm.postProcessing.naming.patternAnime,\"naming-presets\":_vm.presets,\"type\":\"anime\",\"multi-ep-style\":_vm.postProcessing.naming.animeMultiEp,\"multi-ep-styles\":_vm.multiEpStringsSelect,\"anime-naming-type\":_vm.postProcessing.naming.animeNamingType,\"enabled-naming-custom\":_vm.postProcessing.naming.enableCustomNamingAnime,\"flag-loaded\":_vm.configLoaded},on:{\"change\":_vm.saveNamingAnime}}),_vm._v(\" \"),_c('div',{staticClass:\"form-group component-item\"},[_vm._m(30),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"naming_strip_year\",\"name\":\"naming_strip_year\",\"sync\":\"\"},model:{value:(_vm.postProcessing.naming.stripYear),callback:function ($$v) {_vm.$set(_vm.postProcessing.naming, \"stripYear\", $$v)},expression:\"postProcessing.naming.stripYear\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Remove the TV show's year when renaming the file?\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Only applies to shows that have year inside parentheses\")])],1)])],1)])])]),_vm._v(\" \"),_c('div',{attrs:{\"id\":\"metadata\"}},[_c('div',{staticClass:\"row component-group\"},[_vm._m(31),_vm._v(\" \"),_c('div',{staticClass:\"col-xs-12 col-md-10\"},[_c('fieldset',{staticClass:\"component-group-list\"},[_c('div',{staticClass:\"form-group\"},[_vm._m(32),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.metadataProviderSelected),expression:\"metadataProviderSelected\"}],staticClass:\"form-control input-sm\",attrs:{\"id\":\"metadataType\",\"name\":\"metadataType\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.metadataProviderSelected=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},_vm._l((_vm.metadataProviders),function(option){return _c('option',{key:option.id,domProps:{\"value\":option.id}},[_vm._v(_vm._s(option.name))])}),0),_vm._v(\" \"),_vm._m(33)])]),_vm._v(\" \"),_vm._l((_vm.metadataProviders),function(provider){return _c('div',{directives:[{name:\"show\",rawName:\"v-show\",value:(provider.id === _vm.metadataProviderSelected),expression:\"provider.id === metadataProviderSelected\"}],key:provider.id,staticClass:\"metadataDiv\",attrs:{\"id\":\"provider.id\"}},[_c('div',{staticClass:\"metadata_options_wrapper\"},[_c('h4',[_vm._v(\"Create:\")]),_vm._v(\" \"),_c('div',{staticClass:\"metadata_options\"},[_c('label',{attrs:{\"for\":provider.id + '_show_metadata'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.showMetadata),expression:\"provider.showMetadata\"}],staticClass:\"metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_show_metadata'},domProps:{\"checked\":Array.isArray(provider.showMetadata)?_vm._i(provider.showMetadata,null)>-1:(provider.showMetadata)},on:{\"change\":function($event){var $$a=provider.showMetadata,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"showMetadata\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"showMetadata\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"showMetadata\", $$c)}}}}),_vm._v(\" Show Metadata\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_episode_metadata'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.episodeMetadata),expression:\"provider.episodeMetadata\"}],staticClass:\"metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_episode_metadata',\"disabled\":provider.example.episodeMetadata.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.episodeMetadata)?_vm._i(provider.episodeMetadata,null)>-1:(provider.episodeMetadata)},on:{\"change\":function($event){var $$a=provider.episodeMetadata,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"episodeMetadata\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"episodeMetadata\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"episodeMetadata\", $$c)}}}}),_vm._v(\" Episode Metadata\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_fanart'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.fanart),expression:\"provider.fanart\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_fanart',\"disabled\":provider.example.fanart.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.fanart)?_vm._i(provider.fanart,null)>-1:(provider.fanart)},on:{\"change\":function($event){var $$a=provider.fanart,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"fanart\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"fanart\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"fanart\", $$c)}}}}),_vm._v(\" Show Fanart\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_poster'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.poster),expression:\"provider.poster\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_poster',\"disabled\":provider.example.poster.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.poster)?_vm._i(provider.poster,null)>-1:(provider.poster)},on:{\"change\":function($event){var $$a=provider.poster,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"poster\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"poster\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"poster\", $$c)}}}}),_vm._v(\" Show Poster\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_banner'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.banner),expression:\"provider.banner\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_banner',\"disabled\":provider.example.banner.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.banner)?_vm._i(provider.banner,null)>-1:(provider.banner)},on:{\"change\":function($event){var $$a=provider.banner,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"banner\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"banner\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"banner\", $$c)}}}}),_vm._v(\" Show Banner\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_episode_thumbnails'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.episodeThumbnails),expression:\"provider.episodeThumbnails\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_episode_thumbnails',\"disabled\":provider.example.episodeThumbnails.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.episodeThumbnails)?_vm._i(provider.episodeThumbnails,null)>-1:(provider.episodeThumbnails)},on:{\"change\":function($event){var $$a=provider.episodeThumbnails,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"episodeThumbnails\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"episodeThumbnails\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"episodeThumbnails\", $$c)}}}}),_vm._v(\" Episode Thumbnails\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_posters'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.seasonPosters),expression:\"provider.seasonPosters\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_season_posters',\"disabled\":provider.example.seasonPosters.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.seasonPosters)?_vm._i(provider.seasonPosters,null)>-1:(provider.seasonPosters)},on:{\"change\":function($event){var $$a=provider.seasonPosters,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"seasonPosters\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"seasonPosters\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"seasonPosters\", $$c)}}}}),_vm._v(\" Season Posters\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_banners'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.seasonBanners),expression:\"provider.seasonBanners\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_season_banners',\"disabled\":provider.example.seasonBanners.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.seasonBanners)?_vm._i(provider.seasonBanners,null)>-1:(provider.seasonBanners)},on:{\"change\":function($event){var $$a=provider.seasonBanners,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"seasonBanners\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"seasonBanners\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"seasonBanners\", $$c)}}}}),_vm._v(\" Season Banners\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_all_poster'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.seasonAllPoster),expression:\"provider.seasonAllPoster\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_season_all_poster',\"disabled\":provider.example.seasonAllPoster.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.seasonAllPoster)?_vm._i(provider.seasonAllPoster,null)>-1:(provider.seasonAllPoster)},on:{\"change\":function($event){var $$a=provider.seasonAllPoster,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"seasonAllPoster\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"seasonAllPoster\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"seasonAllPoster\", $$c)}}}}),_vm._v(\" Season All Poster\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_all_banner'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.seasonAllBanner),expression:\"provider.seasonAllBanner\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_season_all_banner',\"disabled\":provider.example.seasonAllBanner.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.seasonAllBanner)?_vm._i(provider.seasonAllBanner,null)>-1:(provider.seasonAllBanner)},on:{\"change\":function($event){var $$a=provider.seasonAllBanner,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"seasonAllBanner\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"seasonAllBanner\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"seasonAllBanner\", $$c)}}}}),_vm._v(\" Season All Banner\")])])]),_vm._v(\" \"),_c('div',{staticClass:\"metadata_example_wrapper\"},[_c('h4',[_vm._v(\"Results:\")]),_vm._v(\" \"),_c('div',{staticClass:\"metadata_example\"},[_c('label',{attrs:{\"for\":provider.id + '_show_metadata'}},[_c('span',{class:{disabled: !provider.showMetadata},attrs:{\"id\":provider.id + '_eg_show_metadata'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.showMetadata + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_episode_metadata'}},[_c('span',{class:{disabled: !provider.episodeMetadata},attrs:{\"id\":provider.id + '_eg_episode_metadata'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.episodeMetadata + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_fanart'}},[_c('span',{class:{disabled: !provider.fanart},attrs:{\"id\":provider.id + '_eg_fanart'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.fanart + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_poster'}},[_c('span',{class:{disabled: !provider.poster},attrs:{\"id\":provider.id + '_eg_poster'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.poster + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_banner'}},[_c('span',{class:{disabled: !provider.banner},attrs:{\"id\":provider.id + '_eg_banner'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.banner + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_episode_thumbnails'}},[_c('span',{class:{disabled: !provider.episodeThumbnails},attrs:{\"id\":provider.id + '_eg_episode_thumbnails'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.episodeThumbnails + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_posters'}},[_c('span',{class:{disabled: !provider.seasonPosters},attrs:{\"id\":provider.id + '_eg_season_posters'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.seasonPosters + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_banners'}},[_c('span',{class:{disabled: !provider.seasonBanners},attrs:{\"id\":provider.id + '_eg_season_banners'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.seasonBanners + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_all_poster'}},[_c('span',{class:{disabled: !provider.seasonAllPoster},attrs:{\"id\":provider.id + '_eg_season_all_poster'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.seasonAllPoster + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_all_banner'}},[_c('span',{class:{disabled: !provider.seasonAllBanner},attrs:{\"id\":provider.id + '_eg_season_all_banner'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.seasonAllBanner + '')}})])])])])])})],2),_vm._v(\" \"),_c('input',{staticClass:\"btn-medusa config_submitter\",attrs:{\"type\":\"submit\",\"value\":\"Save Changes\"}}),_c('br')])])]),_vm._v(\" \"),_c('h6',{staticClass:\"pull-right\"},[_c('b',[_vm._v(\"All non-absolute folder locations are relative to \"),_c('span',{staticClass:\"path\"},[_vm._v(_vm._s(_vm.config.dataDir))])])]),_vm._v(\" \"),_c('input',{staticClass:\"btn-medusa pull-left config_submitter button\",attrs:{\"type\":\"submit\",\"value\":\"Save Changes\"}})])])])])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"component-group-desc col-xs-12 col-md-2\"},[_c('h3',[_vm._v(\"Scheduled Post-Processing\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Settings that dictate how Medusa should process completed downloads.\")]),_vm._v(\" \"),_c('p',[_vm._v(\"The scheduled postprocessor will periodically scan a folder for media to process.\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"process_automatically\"}},[_c('span',[_vm._v(\"Scheduled Postprocessor\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('p',[_vm._v(\"Enable the scheduled post processor to scan and process any files in your \"),_c('i',[_vm._v(\"Post Processing Dir\")]),_vm._v(\"?\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"clear-left\"},[_c('p',[_c('b',[_vm._v(\"NOTE:\")]),_vm._v(\" Do not use if you use an external Post Processing script\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"tv_download_dir\"}},[_c('span',[_vm._v(\"Post Processing Dir\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"clear-left\"},[_c('p',[_c('b',[_vm._v(\"NOTE:\")]),_vm._v(\" Please use seperate downloading and completed folders in your download client if possible.\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"process_method\"}},[_c('span',[_vm._v(\"Processing Method\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('p',[_c('b',[_vm._v(\"NOTE:\")]),_vm._v(\" If you keep seeding torrents after they finish, please avoid the 'move' processing method to prevent errors.\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"autopostprocessor_frequency\"}},[_c('span',[_vm._v(\"Auto Post-Processing Frequency\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"component-group-desc col-xs-12 col-md-2\"},[_c('h3',[_vm._v(\"General Post-Processing\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Generic postprocessing settings that apply both to the scheduled postprocessor as external scripts\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"postpone_if_sync_files\"}},[_c('span',[_vm._v(\"Postpone post processing\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"sync_files\"}},[_c('span',[_vm._v(\"Sync File Extensions\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"postpone_if_no_subs\"}},[_c('span',[_vm._v(\"Postpone if no subtitle\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',[_c('b',[_vm._v(\"NOTE:\")]),_vm._v(\" Automatic post processor should be disabled to avoid files with pending subtitles being processed over and over.\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"rename_episodes\"}},[_c('span',[_vm._v(\"Rename Episodes\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"create_missing_show_dirs\"}},[_c('span',[_vm._v(\"Create missing show directories\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"add_shows_wo_dir\"}},[_c('span',[_vm._v(\"Add shows without directory\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"move_associated_files\"}},[_c('span',[_vm._v(\"Delete associated files\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\"},[_c('span',[_vm._v(\"Keep associated file extensions\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"nfo_rename\"}},[_c('span',[_vm._v(\"Rename .nfo file\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"airdate_episodes\"}},[_c('span',[_vm._v(\"Change File Date\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"file_timestamp_timezone\"}},[_c('span',[_vm._v(\"Timezone for File Date:\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"unpack\"}},[_c('span',[_vm._v(\"Unpack\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',[_vm._v(\"Unpack any TV releases in your \"),_c('i',[_vm._v(\"TV Download Dir\")]),_vm._v(\"?\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',[_c('b',[_vm._v(\"NOTE:\")]),_vm._v(\" Only working with RAR archive\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"del_rar_contents\"}},[_c('span',[_vm._v(\"Delete RAR contents\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"no_delete\"}},[_c('span',[_vm._v(\"Don't delete empty folders\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',[_c('b',[_vm._v(\"NOTE:\")]),_vm._v(\" Can be overridden using manual Post Processing\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\"},[_c('span',[_vm._v(\"Extra Scripts\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"component-group-desc col-xs-12 col-md-2\"},[_c('h3',[_vm._v(\"Episode Naming\")]),_vm._v(\" \"),_c('p',[_vm._v(\"How Medusa will name and sort your episodes.\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"naming_strip_year\"}},[_c('span',[_vm._v(\"Strip Show Year\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"component-group-desc col-xs-12 col-md-2\"},[_c('h3',[_vm._v(\"Metadata\")]),_vm._v(\" \"),_c('p',[_vm._v(\"The data associated to the data. These are files associated to a TV show in the form of images and text that, when supported, will enhance the viewing experience.\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"metadataType\"}},[_c('span',[_vm._v(\"Metadata Type\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',{staticClass:\"d-block\"},[_vm._v(\"Toggle the metadata options that you wish to be created. \"),_c('b',[_vm._v(\"Multiple targets may be used.\")])])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-post-processing.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-post-processing.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./config-post-processing.vue?vue&type=template&id=0b3bbb62&\"\nimport script from \"./config-post-processing.vue?vue&type=script&lang=js&\"\nexport * from \"./config-post-processing.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/*\\n@NOTE: This fixes the header blocking elements when using a hash link\\ne.g. displayShow?indexername=tvdb&seriesid=83462#season-5\\n*/\\n[false-link]::before {\\n content: '';\\n display: block;\\n position: absolute;\\n height: 100px;\\n margin-top: -100px;\\n z-index: -100;\\n}\\n.router-link,\\n.router-link-active {\\n cursor: pointer;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.form-control {\\n color: rgb(0, 0, 0);\\n}\\n.input75 {\\n width: 75px;\\n margin-top: -4px;\\n}\\n.input250 {\\n width: 250px;\\n margin-top: -4px;\\n}\\n.input350 {\\n width: 350px;\\n margin-top: -4px;\\n}\\n.input450 {\\n width: 450px;\\n margin-top: -4px;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.input75 {\\n width: 75px;\\n margin-top: -4px;\\n}\\n.input250 {\\n width: 250px;\\n margin-top: -4px;\\n}\\n.input350 {\\n width: 350px;\\n margin-top: -4px;\\n}\\n.input450 {\\n width: 450px;\\n margin-top: -4px;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.input75 {\\n width: 75px;\\n margin-top: -4px;\\n}\\n.input250 {\\n width: 250px;\\n margin-top: -4px;\\n}\\n.input350 {\\n width: 350px;\\n margin-top: -4px;\\n}\\n.input450 {\\n width: 450px;\\n margin-top: -4px;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=style&index=0&id=5a327762&scoped=true&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=style&index=0&id=5a327762&scoped=true&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\ndiv.file-browser.max-width[data-v-5a327762] {\\n max-width: 450px;\\n}\\ndiv.file-browser .input-group-no-btn[data-v-5a327762] {\\n display: flex;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.plotInfo {\\n cursor: help;\\n float: right;\\n position: relative;\\n top: 2px;\\n}\\n.plotInfoNone {\\n cursor: help;\\n float: right;\\n position: relative;\\n top: 2px;\\n opacity: 0.4;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=style&index=0&id=b683ee7a&scoped=true&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=style&index=0&id=b683ee7a&scoped=true&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.quality[data-v-b683ee7a] {\\n font: 12px/13px \\\"Open Sans\\\", verdana, sans-serif;\\n background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n background-image: -o-linear-gradient(top, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), inset 0 -1px 3px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 2px rgba(0, 0, 0, 0.15);\\n text-shadow: 0 1px rgba(0, 0, 0, 0.8);\\n color: rgb(255, 255, 255);\\n display: inline-block;\\n padding: 2px 4px;\\n text-align: center;\\n vertical-align: baseline;\\n border-radius: 4px;\\n white-space: nowrap;\\n}\\n.any-hd[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n /* stylelint-disable declaration-block-no-shorthand-property-overrides */\\n background:\\n repeating-linear-gradient(\\n -45deg,\\n rgb(38, 114, 182),\\n rgb(38, 114, 182) 10px,\\n rgb(91, 153, 13) 10px,\\n rgb(91, 153, 13) 20px\\n );\\n /* stylelint-enable */\\n}\\n.Custom[data-v-b683ee7a] {\\n background-color: rgb(98, 25, 147);\\n}\\n.HD[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n}\\n.HDTV[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n}\\n.HD720p[data-v-b683ee7a] {\\n background-color: rgb(91, 153, 13);\\n}\\n.HD1080p[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n}\\n.UHD-4K[data-v-b683ee7a] {\\n background-color: rgb(117, 0, 255);\\n}\\n.UHD-8K[data-v-b683ee7a] {\\n background-color: rgb(65, 0, 119);\\n}\\n.RawHD[data-v-b683ee7a] {\\n background-color: rgb(205, 115, 0);\\n}\\n.RawHDTV[data-v-b683ee7a] {\\n background-color: rgb(205, 115, 0);\\n}\\n.SD[data-v-b683ee7a] {\\n background-color: rgb(190, 38, 37);\\n}\\n.SDTV[data-v-b683ee7a] {\\n background-color: rgb(190, 38, 37);\\n}\\n.SDDVD[data-v-b683ee7a] {\\n background-color: rgb(190, 38, 37);\\n}\\n.Any[data-v-b683ee7a] {\\n background-color: rgb(102, 102, 102);\\n}\\n.Unknown[data-v-b683ee7a] {\\n background-color: rgb(153, 153, 153);\\n}\\n.Proper[data-v-b683ee7a] {\\n background-color: rgb(63, 127, 0);\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.scroll-wrapper {\\n position: fixed;\\n opacity: 0;\\n visibility: hidden;\\n overflow: hidden;\\n text-align: center;\\n font-size: 20px;\\n z-index: 999;\\n background-color: #777;\\n color: #eee;\\n width: 50px;\\n height: 48px;\\n line-height: 48px;\\n right: 30px;\\n bottom: 30px;\\n padding-top: 2px;\\n border-radius: 10px;\\n -webkit-transition: all 0.5s ease-in-out;\\n -moz-transition: all 0.5s ease-in-out;\\n -ms-transition: all 0.5s ease-in-out;\\n -o-transition: all 0.5s ease-in-out;\\n transition: all 0.5s ease-in-out;\\n}\\n.scroll-wrapper.show {\\n visibility: visible;\\n cursor: pointer;\\n opacity: 1;\\n}\\n.scroll-wrapper.left {\\n position: fixed;\\n right: 150px;\\n}\\n.scroll-wrapper.right {\\n position: fixed;\\n right: 90px;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=style&index=0&id=ac609192&scoped=true&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=style&index=0&id=ac609192&scoped=true&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\ndiv.select-list ul[data-v-ac609192] {\\n padding-left: 0;\\n}\\ndiv.select-list li[data-v-ac609192] {\\n list-style-type: none;\\n display: flex;\\n}\\ndiv.select-list .new-item[data-v-ac609192] {\\n display: flex;\\n}\\ndiv.select-list .new-item-help[data-v-ac609192] {\\n font-weight: bold;\\n padding-top: 5px;\\n}\\ndiv.select-list input[data-v-ac609192],\\ndiv.select-list img[data-v-ac609192] {\\n display: inline-block;\\n box-sizing: border-box;\\n}\\ndiv.select-list.max-width[data-v-ac609192] {\\n max-width: 450px;\\n}\\ndiv.select-list .switch-input[data-v-ac609192] {\\n left: -8px;\\n top: 4px;\\n position: absolute;\\n z-index: 10;\\n opacity: 0.6;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\nselect.select-show {\\n display: inline-block;\\n height: 25px;\\n padding: 1px;\\n}\\n.show-selector {\\n height: 31px;\\n display: table-cell;\\n left: 20px;\\n margin-bottom: 5px;\\n}\\n@media (max-width: 767px) and (min-width: 341px) {\\n.select-show-group,\\n .select-show {\\n width: 100%;\\n}\\n}\\n@media (max-width: 340px) {\\n.select-show-group {\\n width: 100%;\\n}\\n}\\n@media (max-width: 767px) {\\n.show-selector {\\n float: left;\\n width: 100%;\\n}\\n.select-show {\\n width: 100%;\\n}\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=style&index=0&id=10f4092b&scoped=true&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=style&index=0&id=10f4092b&scoped=true&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\ndiv.anidb-release-group-ui-wrapper[data-v-10f4092b] {\\n clear: both;\\n margin-bottom: 20px;\\n}\\ndiv.anidb-release-group-ui-wrapper ul[data-v-10f4092b] {\\n border-style: solid;\\n border-width: thin;\\n padding: 5px 2px 2px 5px;\\n list-style: none;\\n}\\ndiv.anidb-release-group-ui-wrapper li.active[data-v-10f4092b] {\\n background-color: cornflowerblue;\\n}\\ndiv.anidb-release-group-ui-wrapper div.arrow img[data-v-10f4092b] {\\n cursor: pointer;\\n height: 32px;\\n width: 32px;\\n}\\ndiv.anidb-release-group-ui-wrapper img.deleteFromWhitelist[data-v-10f4092b],\\ndiv.anidb-release-group-ui-wrapper img.deleteFromBlacklist[data-v-10f4092b] {\\n float: right;\\n}\\ndiv.anidb-release-group-ui-wrapper #add-new-release-group p > img[data-v-10f4092b] {\\n height: 16px;\\n width: 16px;\\n background-color: rgb(204, 204, 204);\\n}\\ndiv.anidb-release-group-ui-wrapper.placeholder[data-v-10f4092b] {\\n height: 32px;\\n}\\ndiv.anidb-release-group-ui-wrapper.max-width[data-v-10f4092b] {\\n max-width: 960px;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.floating-badge {\\n position: absolute;\\n top: -5px;\\n right: -8px;\\n padding: 0 4px;\\n background-color: #777;\\n border: 2px solid #959595;\\n border-radius: 100px;\\n font-size: 12px;\\n font-weight: bold;\\n text-decoration: none;\\n color: white;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.infoTable tr td:first-child {\\n vertical-align: top;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=style&index=0&id=60f89f30&scoped=true&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=style&index=0&id=60f89f30&scoped=true&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.irc-frame[data-v-60f89f30] {\\n width: 100%;\\n height: 500px;\\n border: 1px #000 solid;\\n}\\n.loading-spinner[data-v-60f89f30] {\\n background-position: center center;\\n background-repeat: no-repeat;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.root-dirs-selectbox,\\n.root-dirs-selectbox select,\\n.root-dirs-controls {\\n width: 100%;\\n max-width: 430px;\\n}\\n.root-dirs-selectbox {\\n padding: 0 0 5px;\\n}\\n.root-dirs-controls {\\n text-align: center;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-header.vue?vue&type=style&index=0&id=e712fe74&scoped=true&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-header.vue?vue&type=style&index=0&id=e712fe74&scoped=true&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.summaryTable[data-v-e712fe74] {\\n overflow: hidden;\\n}\\n.summaryTable tr td[data-v-e712fe74] {\\n word-break: break-all;\\n}\\n.ver-spacer[data-v-e712fe74] {\\n width: 15px;\\n}\\n#show-specials-and-seasons[data-v-e712fe74] {\\n margin-bottom: 15px;\\n}\\nspan.required[data-v-e712fe74] {\\n color: green;\\n}\\nspan.preferred[data-v-e712fe74] {\\n color: blue;\\n}\\nspan.undesired[data-v-e712fe74] {\\n color: orange;\\n}\\nspan.ignored[data-v-e712fe74] {\\n color: red;\\n}\\ndiv#col-show-summary[data-v-e712fe74] {\\n display: table;\\n}\\n#col-show-summary img.show-image[data-v-e712fe74] {\\n max-width: 180px;\\n}\\n.show-poster-container[data-v-e712fe74] {\\n margin-right: 10px;\\n display: table-cell;\\n width: 180px;\\n}\\n.show-info-container[data-v-e712fe74] {\\n overflow: hidden;\\n display: table-cell;\\n}\\n@media (min-width: 768px) {\\n.display-specials[data-v-e712fe74],\\n .display-seasons[data-v-e712fe74] {\\n top: -60px;\\n}\\n#show-specials-and-seasons[data-v-e712fe74] {\\n bottom: 5px;\\n right: 15px;\\n position: absolute;\\n}\\n}\\n@media (max-width: 767px) {\\n.show-poster-container[data-v-e712fe74] {\\n display: inline-block;\\n width: 100%;\\n margin: 0 auto;\\n border-style: none;\\n}\\n.show-poster-container img[data-v-e712fe74] {\\n display: block;\\n margin: 0 auto;\\n max-width: 280px !important;\\n}\\n.show-info-container[data-v-e712fe74] {\\n display: block;\\n padding-top: 5px;\\n width: 100%;\\n}\\n}\\n@media (max-width: 991px) and (min-width: 768px) {\\n.show-poster-container[data-v-e712fe74] {\\n float: left;\\n display: inline-block;\\n width: 100%;\\n border-style: none;\\n}\\n.show-info-container[data-v-e712fe74] {\\n display: block;\\n width: 100%;\\n}\\n#col-show-summary img.show-image[data-v-e712fe74] {\\n max-width: 280px;\\n}\\n}\\n\", \"\"]);\n\n"],"sourceRoot":""} \ No newline at end of file diff --git a/themes/dark/assets/js/notifications.js b/themes/dark/assets/js/notifications.js index 4cfbe7a356..4fd70fe910 100644 --- a/themes/dark/assets/js/notifications.js +++ b/themes/dark/assets/js/notifications.js @@ -19,9 +19,9 @@ window.displayNotification = (type, title, message, id) => { desktop: { tag: id }, - text: String(message).replace(/]*)?>/ig, '\n') // eslint-disable-line unicorn/no-unsafe-regex - .replace(/<[/]?b(?:\s[^>]*)?>/ig, '*') // eslint-disable-line unicorn/no-unsafe-regex - .replace(/]*)?>/ig, '[').replace(/<[/]i>/ig, ']') // eslint-disable-line unicorn/no-unsafe-regex - .replace(/<(?:[/]?ul|\/li)(?:\s[^>]*)?>/ig, '').replace(/]*)?>/ig, '\n* ') // eslint-disable-line unicorn/no-unsafe-regex + text: String(message).replace(/]*)?>/ig, '\n') + .replace(/<[/]?b(?:\s[^>]*)?>/ig, '*') + .replace(/]*)?>/ig, '[').replace(/<[/]i>/ig, ']') + .replace(/<(?:[/]?ul|\/li)(?:\s[^>]*)?>/ig, '').replace(/]*)?>/ig, '\n* ') }); }; diff --git a/themes/dark/assets/js/parsers.js b/themes/dark/assets/js/parsers.js index 62d90ecfbe..c261159244 100644 --- a/themes/dark/assets/js/parsers.js +++ b/themes/dark/assets/js/parsers.js @@ -7,7 +7,7 @@ $.tablesorter.addParser({ if (s.indexOf('Loading...') === 0) { return s.replace('Loading...', '000'); } - return (MEDUSA.config.sortArticle ? (s || '') : (s || '').replace(/^(The|A|An)\s/i, '')); // eslint-disable-line no-undef + return (MEDUSA.config.sortArticle ? (s || '') : (s || '').replace(/^(The|A|An)\s/i, '')); }, type: 'text' }); diff --git a/themes/dark/assets/js/trending-shows.js b/themes/dark/assets/js/trending-shows.js index 21d4cdae8a..bf40428607 100644 --- a/themes/dark/assets/js/trending-shows.js +++ b/themes/dark/assets/js/trending-shows.js @@ -12,7 +12,7 @@ $(document).ready(() => { getSortData: { name(itemElem) { const name = $(itemElem).attr('data-name') || ''; - return (MEDUSA.config.sortArticle ? name : name.replace(/^(The|A|An)\s/i, '')).toLowerCase(); // eslint-disable-line no-undef + return (MEDUSA.config.sortArticle ? name : name.replace(/^(The|A|An)\s/i, '')).toLowerCase(); }, rating: '[data-rating] parseInt', votes: '[data-votes] parseInt' diff --git a/themes/dark/assets/js/vendors.js b/themes/dark/assets/js/vendors.js index 58006ece9a..19d090ed5a 100644 --- a/themes/dark/assets/js/vendors.js +++ b/themes/dark/assets/js/vendors.js @@ -1,4 +1,10 @@ -!function(t){function e(e){for(var r,a,s=e[0],c=e[1],l=e[2],f=0,d=[];f-1&&t.splice(n,1)}}function f(e,t){e._actions=Object.create(null),e._mutations=Object.create(null),e._wrappedGetters=Object.create(null),e._modulesNamespaceMap=Object.create(null);var n=e.state;m(e,n,[],e._modules.root,!0),p(e,n,t)}function p(e,t,n){var i=e._vm;e.getters={};var o=e._wrappedGetters,a={};r(o,function(t,n){a[n]=function(){return t(e)},Object.defineProperty(e.getters,n,{get:function(){return e._vm[n]},enumerable:!0})});var s=l.config.silent;l.config.silent=!0,e._vm=new l({data:{$$state:t},computed:a}),l.config.silent=s,e.strict&&function(e){e._vm.$watch(function(){return this._data.$$state},function(){0},{deep:!0,sync:!0})}(e),i&&(n&&e._withCommit(function(){i._data.$$state=null}),l.nextTick(function(){return i.$destroy()}))}function m(e,t,n,i,r){var o=!n.length,a=e._modules.getNamespace(n);if(i.namespaced&&(e._modulesNamespaceMap[a]=i),!o&&!r){var s=h(t,n.slice(0,-1)),u=n[n.length-1];e._withCommit(function(){l.set(s,u,i.state)})}var c=i.context=function(e,t,n){var i=""===t,r={dispatch:i?e.dispatch:function(n,i,r){var o=g(n,i,r),a=o.payload,s=o.options,l=o.type;return s&&s.root||(l=t+l),e.dispatch(l,a)},commit:i?e.commit:function(n,i,r){var o=g(n,i,r),a=o.payload,s=o.options,l=o.type;s&&s.root||(l=t+l),e.commit(l,a,s)}};return Object.defineProperties(r,{getters:{get:i?function(){return e.getters}:function(){return function(e,t){var n={},i=t.length;return Object.keys(e.getters).forEach(function(r){if(r.slice(0,i)===t){var o=r.slice(i);Object.defineProperty(n,o,{get:function(){return e.getters[r]},enumerable:!0})}}),n}(e,t)}},state:{get:function(){return h(e.state,n)}}}),r}(e,a,n);i.forEachMutation(function(t,n){!function(e,t,n,i){(e._mutations[t]||(e._mutations[t]=[])).push(function(t){n.call(e,i.state,t)})}(e,a+n,t,c)}),i.forEachAction(function(t,n){var i=t.root?n:a+n,r=t.handler||t;!function(e,t,n,i){(e._actions[t]||(e._actions[t]=[])).push(function(t,r){var o,a=n.call(e,{dispatch:i.dispatch,commit:i.commit,getters:i.getters,state:i.state,rootGetters:e.getters,rootState:e.state},t,r);return(o=a)&&"function"==typeof o.then||(a=Promise.resolve(a)),e._devtoolHook?a.catch(function(t){throw e._devtoolHook.emit("vuex:error",t),t}):a})}(e,i,r,c)}),i.forEachGetter(function(t,n){!function(e,t,n,i){if(e._wrappedGetters[t])return void 0;e._wrappedGetters[t]=function(e){return n(i.state,i.getters,e.state,e.getters)}}(e,a+n,t,c)}),i.forEachChild(function(i,o){m(e,t,n.concat(o),i,r)})}function h(e,t){return t.length?t.reduce(function(e,t){return e[t]},e):e}function g(e,t,n){var i;return null!==(i=e)&&"object"==typeof i&&e.type&&(n=t,t=e,e=e.type),{type:e,payload:t,options:n}}function v(e){l&&e===l|| +/** + * vuex v3.1.0 + * (c) 2019 Evan You + * @license MIT + */ +function(e){if(Number(e.version.split(".")[0])>=2)e.mixin({beforeCreate:n});else{var t=e.prototype._init;e.prototype._init=function(e){void 0===e&&(e={}),e.init=e.init?[n].concat(e.init):n,t.call(this,e)}}function n(){var e=this.$options;e.store?this.$store="function"==typeof e.store?e.store():e.store:e.parent&&e.parent.$store&&(this.$store=e.parent.$store)}}(l=e)}c.state.get=function(){return this._vm._data.$$state},c.state.set=function(e){0},u.prototype.commit=function(e,t,n){var i=this,r=g(e,t,n),o=r.type,a=r.payload,s=(r.options,{type:o,payload:a}),l=this._mutations[o];l&&(this._withCommit(function(){l.forEach(function(e){e(a)})}),this._subscribers.forEach(function(e){return e(s,i.state)}))},u.prototype.dispatch=function(e,t){var n=this,i=g(e,t),r=i.type,o=i.payload,a={type:r,payload:o},s=this._actions[r];if(s){try{this._actionSubscribers.filter(function(e){return e.before}).forEach(function(e){return e.before(a,n.state)})}catch(e){0}return(s.length>1?Promise.all(s.map(function(e){return e(o)})):s[0](o)).then(function(e){try{n._actionSubscribers.filter(function(e){return e.after}).forEach(function(e){return e.after(a,n.state)})}catch(e){0}return e})}},u.prototype.subscribe=function(e){return d(e,this._subscribers)},u.prototype.subscribeAction=function(e){return d("function"==typeof e?{before:e}:e,this._actionSubscribers)},u.prototype.watch=function(e,t,n){var i=this;return this._watcherVM.$watch(function(){return e(i.state,i.getters)},t,n)},u.prototype.replaceState=function(e){var t=this;this._withCommit(function(){t._vm._data.$$state=e})},u.prototype.registerModule=function(e,t,n){void 0===n&&(n={}),"string"==typeof e&&(e=[e]),this._modules.register(e,t),m(this,this.state,e,this._modules.get(e),n.preserveState),p(this,this.state)},u.prototype.unregisterModule=function(e){var t=this;"string"==typeof e&&(e=[e]),this._modules.unregister(e),this._withCommit(function(){var n=h(t.state,e.slice(0,-1));l.delete(n,e[e.length-1])}),f(this)},u.prototype.hotUpdate=function(e){this._modules.update(e),f(this,!0)},u.prototype._withCommit=function(e){var t=this._committing;this._committing=!0,e(),this._committing=t},Object.defineProperties(u.prototype,c);var y=N(function(e,t){var n={};return w(t).forEach(function(t){var i=t.key,r=t.val;n[i]=function(){var t=this.$store.state,n=this.$store.getters;if(e){var i=x(this.$store,"mapState",e);if(!i)return;t=i.context.state,n=i.context.getters}return"function"==typeof r?r.call(this,t,n):t[r]},n[i].vuex=!0}),n}),_=N(function(e,t){var n={};return w(t).forEach(function(t){var i=t.key,r=t.val;n[i]=function(){for(var t=[],n=arguments.length;n--;)t[n]=arguments[n];var i=this.$store.commit;if(e){var o=x(this.$store,"mapMutations",e);if(!o)return;i=o.context.commit}return"function"==typeof r?r.apply(this,[i].concat(t)):i.apply(this.$store,[r].concat(t))}}),n}),b=N(function(e,t){var n={};return w(t).forEach(function(t){var i=t.key,r=t.val;r=e+r,n[i]=function(){if(!e||x(this.$store,"mapGetters",e))return this.$store.getters[r]},n[i].vuex=!0}),n}),C=N(function(e,t){var n={};return w(t).forEach(function(t){var i=t.key,r=t.val;n[i]=function(){for(var t=[],n=arguments.length;n--;)t[n]=arguments[n];var i=this.$store.dispatch;if(e){var o=x(this.$store,"mapActions",e);if(!o)return;i=o.context.dispatch}return"function"==typeof r?r.apply(this,[i].concat(t)):i.apply(this.$store,[r].concat(t))}}),n});function w(e){return Array.isArray(e)?e.map(function(e){return{key:e,val:e}}):Object.keys(e).map(function(t){return{key:t,val:e[t]}})}function N(e){return function(t,n){return"string"!=typeof t?(n=t,t=""):"/"!==t.charAt(t.length-1)&&(t+="/"),e(t,n)}}function x(e,t,n){return e._modulesNamespaceMap[n]}var T={Store:u,install:v,version:"3.1.0",mapState:y,mapMutations:_,mapGetters:b,mapActions:C,createNamespacedHelpers:function(e){return{mapState:y.bind(null,e),mapGetters:b.bind(null,e),mapMutations:_.bind(null,e),mapActions:C.bind(null,e)}}};t.a=T},function(e,t,n){var i; /*! * jQuery JavaScript Library v3.3.1 * https://jquery.com/ @@ -25,7 +31,7 @@ * * Date: 2018-01-20T17:24Z */ -!function(e,n){"use strict";"object"==typeof t.exports?t.exports=e.document?n(e,!0):function(t){if(!t.document)throw new Error("jQuery requires a window with a document");return n(t)}:n(e)}("undefined"!=typeof window?window:this,function(n,o){"use strict";var i=[],a=n.document,s=Object.getPrototypeOf,c=i.slice,l=i.concat,u=i.push,f=i.indexOf,d={},p=d.toString,h=d.hasOwnProperty,g=h.toString,m=g.call(Object),v={},y=function(t){return"function"==typeof t&&"number"!=typeof t.nodeType},b=function(t){return null!=t&&t===t.window},w={type:!0,src:!0,noModule:!0};function x(t,e,n){var r,o=(e=e||a).createElement("script");if(o.text=t,n)for(r in w)n[r]&&(o[r]=n[r]);e.head.appendChild(o).parentNode.removeChild(o)}function C(t){return null==t?t+"":"object"==typeof t||"function"==typeof t?d[p.call(t)]||"object":typeof t}var _=function(t,e){return new _.fn.init(t,e)},$=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function T(t){var e=!!t&&"length"in t&&t.length,n=C(t);return!y(t)&&!b(t)&&("array"===n||0===e||"number"==typeof e&&e>0&&e-1 in t)}_.fn=_.prototype={jquery:"3.3.1",constructor:_,length:0,toArray:function(){return c.call(this)},get:function(t){return null==t?c.call(this):t<0?this[t+this.length]:this[t]},pushStack:function(t){var e=_.merge(this.constructor(),t);return e.prevObject=this,e},each:function(t){return _.each(this,t)},map:function(t){return this.pushStack(_.map(this,function(e,n){return t.call(e,n,e)}))},slice:function(){return this.pushStack(c.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(t){var e=this.length,n=+t+(t<0?e:0);return this.pushStack(n>=0&&n0&&t-1 in e)}N.fn=N.prototype={jquery:"3.3.1",constructor:N,length:0,toArray:function(){return l.call(this)},get:function(e){return null==e?l.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=N.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return N.each(this,e)},map:function(e){return this.pushStack(N.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(l.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n+~]|"+F+")"+F+"*"),U=new RegExp("="+F+"*([^\\]'\"]*?)"+F+"*\\]","g"),W=new RegExp(P),V=new RegExp("^"+L+"$"),K={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+F+"*(even|odd|(([+-]|)(\\d*)n|)"+F+"*(?:([+-]|)"+F+"*(\\d+)|))"+F+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+F+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+F+"*((?:-\\d)?\\d*)"+F+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,G=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,Q=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+F+"?|("+F+")|.)","ig"),tt=function(t,e,n){var r="0x"+e-65536;return r!=r||n?e:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},et=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,nt=function(t,e){return e?"\0"===t?"�":t.slice(0,-1)+"\\"+t.charCodeAt(t.length-1).toString(16)+" ":"\\"+t},rt=function(){d()},ot=yt(function(t){return!0===t.disabled&&("form"in t||"label"in t)},{dir:"parentNode",next:"legend"});try{j.apply(A=N.call(x.childNodes),x.childNodes),A[x.childNodes.length].nodeType}catch(t){j={apply:A.length?function(t,e){D.apply(t,N.call(e))}:function(t,e){for(var n=t.length,r=0;t[n++]=e[r++];);t.length=n-1}}}function it(t,e,r,o){var i,s,l,u,f,h,v,y=e&&e.ownerDocument,C=e?e.nodeType:9;if(r=r||[],"string"!=typeof t||!t||1!==C&&9!==C&&11!==C)return r;if(!o&&((e?e.ownerDocument||e:x)!==p&&d(e),e=e||p,g)){if(11!==C&&(f=J.exec(t)))if(i=f[1]){if(9===C){if(!(l=e.getElementById(i)))return r;if(l.id===i)return r.push(l),r}else if(y&&(l=y.getElementById(i))&&b(e,l)&&l.id===i)return r.push(l),r}else{if(f[2])return j.apply(r,e.getElementsByTagName(t)),r;if((i=f[3])&&n.getElementsByClassName&&e.getElementsByClassName)return j.apply(r,e.getElementsByClassName(i)),r}if(n.qsa&&!S[t+" "]&&(!m||!m.test(t))){if(1!==C)y=e,v=t;else if("object"!==e.nodeName.toLowerCase()){for((u=e.getAttribute("id"))?u=u.replace(et,nt):e.setAttribute("id",u=w),s=(h=a(t)).length;s--;)h[s]="#"+u+" "+vt(h[s]);v=h.join(","),y=Q.test(t)&>(e.parentNode)||e}if(v)try{return j.apply(r,y.querySelectorAll(v)),r}catch(t){}finally{u===w&&e.removeAttribute("id")}}}return c(t.replace(q,"$1"),e,r,o)}function at(){var t=[];return function e(n,o){return t.push(n+" ")>r.cacheLength&&delete e[t.shift()],e[n+" "]=o}}function st(t){return t[w]=!0,t}function ct(t){var e=p.createElement("fieldset");try{return!!t(e)}catch(t){return!1}finally{e.parentNode&&e.parentNode.removeChild(e),e=null}}function lt(t,e){for(var n=t.split("|"),o=n.length;o--;)r.attrHandle[n[o]]=e}function ut(t,e){var n=e&&t,r=n&&1===t.nodeType&&1===e.nodeType&&t.sourceIndex-e.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===e)return-1;return t?1:-1}function ft(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function dt(t){return function(e){var n=e.nodeName.toLowerCase();return("input"===n||"button"===n)&&e.type===t}}function pt(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ot(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ht(t){return st(function(e){return e=+e,st(function(n,r){for(var o,i=t([],n.length,e),a=i.length;a--;)n[o=i[a]]&&(n[o]=!(r[o]=n[o]))})})}function gt(t){return t&&void 0!==t.getElementsByTagName&&t}for(e in n=it.support={},i=it.isXML=function(t){var e=t&&(t.ownerDocument||t).documentElement;return!!e&&"HTML"!==e.nodeName},d=it.setDocument=function(t){var e,o,a=t?t.ownerDocument||t:x;return a!==p&&9===a.nodeType&&a.documentElement?(h=(p=a).documentElement,g=!i(p),x!==p&&(o=p.defaultView)&&o.top!==o&&(o.addEventListener?o.addEventListener("unload",rt,!1):o.attachEvent&&o.attachEvent("onunload",rt)),n.attributes=ct(function(t){return t.className="i",!t.getAttribute("className")}),n.getElementsByTagName=ct(function(t){return t.appendChild(p.createComment("")),!t.getElementsByTagName("*").length}),n.getElementsByClassName=G.test(p.getElementsByClassName),n.getById=ct(function(t){return h.appendChild(t).id=w,!p.getElementsByName||!p.getElementsByName(w).length}),n.getById?(r.filter.ID=function(t){var e=t.replace(Z,tt);return function(t){return t.getAttribute("id")===e}},r.find.ID=function(t,e){if(void 0!==e.getElementById&&g){var n=e.getElementById(t);return n?[n]:[]}}):(r.filter.ID=function(t){var e=t.replace(Z,tt);return function(t){var n=void 0!==t.getAttributeNode&&t.getAttributeNode("id");return n&&n.value===e}},r.find.ID=function(t,e){if(void 0!==e.getElementById&&g){var n,r,o,i=e.getElementById(t);if(i){if((n=i.getAttributeNode("id"))&&n.value===t)return[i];for(o=e.getElementsByName(t),r=0;i=o[r++];)if((n=i.getAttributeNode("id"))&&n.value===t)return[i]}return[]}}),r.find.TAG=n.getElementsByTagName?function(t,e){return void 0!==e.getElementsByTagName?e.getElementsByTagName(t):n.qsa?e.querySelectorAll(t):void 0}:function(t,e){var n,r=[],o=0,i=e.getElementsByTagName(t);if("*"===t){for(;n=i[o++];)1===n.nodeType&&r.push(n);return r}return i},r.find.CLASS=n.getElementsByClassName&&function(t,e){if(void 0!==e.getElementsByClassName&&g)return e.getElementsByClassName(t)},v=[],m=[],(n.qsa=G.test(p.querySelectorAll))&&(ct(function(t){h.appendChild(t).innerHTML="",t.querySelectorAll("[msallowcapture^='']").length&&m.push("[*^$]="+F+"*(?:''|\"\")"),t.querySelectorAll("[selected]").length||m.push("\\["+F+"*(?:value|"+R+")"),t.querySelectorAll("[id~="+w+"-]").length||m.push("~="),t.querySelectorAll(":checked").length||m.push(":checked"),t.querySelectorAll("a#"+w+"+*").length||m.push(".#.+[+~]")}),ct(function(t){t.innerHTML="";var e=p.createElement("input");e.setAttribute("type","hidden"),t.appendChild(e).setAttribute("name","D"),t.querySelectorAll("[name=d]").length&&m.push("name"+F+"*[*^$|!~]?="),2!==t.querySelectorAll(":enabled").length&&m.push(":enabled",":disabled"),h.appendChild(t).disabled=!0,2!==t.querySelectorAll(":disabled").length&&m.push(":enabled",":disabled"),t.querySelectorAll("*,:x"),m.push(",.*:")})),(n.matchesSelector=G.test(y=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ct(function(t){n.disconnectedMatch=y.call(t,"*"),y.call(t,"[s!='']:x"),v.push("!=",P)}),m=m.length&&new RegExp(m.join("|")),v=v.length&&new RegExp(v.join("|")),e=G.test(h.compareDocumentPosition),b=e||G.test(h.contains)?function(t,e){var n=9===t.nodeType?t.documentElement:t,r=e&&e.parentNode;return t===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):t.compareDocumentPosition&&16&t.compareDocumentPosition(r)))}:function(t,e){if(e)for(;e=e.parentNode;)if(e===t)return!0;return!1},k=e?function(t,e){if(t===e)return f=!0,0;var r=!t.compareDocumentPosition-!e.compareDocumentPosition;return r||(1&(r=(t.ownerDocument||t)===(e.ownerDocument||e)?t.compareDocumentPosition(e):1)||!n.sortDetached&&e.compareDocumentPosition(t)===r?t===p||t.ownerDocument===x&&b(x,t)?-1:e===p||e.ownerDocument===x&&b(x,e)?1:u?I(u,t)-I(u,e):0:4&r?-1:1)}:function(t,e){if(t===e)return f=!0,0;var n,r=0,o=t.parentNode,i=e.parentNode,a=[t],s=[e];if(!o||!i)return t===p?-1:e===p?1:o?-1:i?1:u?I(u,t)-I(u,e):0;if(o===i)return ut(t,e);for(n=t;n=n.parentNode;)a.unshift(n);for(n=e;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?ut(a[r],s[r]):a[r]===x?-1:s[r]===x?1:0},p):p},it.matches=function(t,e){return it(t,null,null,e)},it.matchesSelector=function(t,e){if((t.ownerDocument||t)!==p&&d(t),e=e.replace(U,"='$1']"),n.matchesSelector&&g&&!S[e+" "]&&(!v||!v.test(e))&&(!m||!m.test(e)))try{var r=y.call(t,e);if(r||n.disconnectedMatch||t.document&&11!==t.document.nodeType)return r}catch(t){}return it(e,p,null,[t]).length>0},it.contains=function(t,e){return(t.ownerDocument||t)!==p&&d(t),b(t,e)},it.attr=function(t,e){(t.ownerDocument||t)!==p&&d(t);var o=r.attrHandle[e.toLowerCase()],i=o&&E.call(r.attrHandle,e.toLowerCase())?o(t,e,!g):void 0;return void 0!==i?i:n.attributes||!g?t.getAttribute(e):(i=t.getAttributeNode(e))&&i.specified?i.value:null},it.escape=function(t){return(t+"").replace(et,nt)},it.error=function(t){throw new Error("Syntax error, unrecognized expression: "+t)},it.uniqueSort=function(t){var e,r=[],o=0,i=0;if(f=!n.detectDuplicates,u=!n.sortStable&&t.slice(0),t.sort(k),f){for(;e=t[i++];)e===t[i]&&(o=r.push(i));for(;o--;)t.splice(r[o],1)}return u=null,t},o=it.getText=function(t){var e,n="",r=0,i=t.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof t.textContent)return t.textContent;for(t=t.firstChild;t;t=t.nextSibling)n+=o(t)}else if(3===i||4===i)return t.nodeValue}else for(;e=t[r++];)n+=o(e);return n},(r=it.selectors={cacheLength:50,createPseudo:st,match:K,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(t){return t[1]=t[1].replace(Z,tt),t[3]=(t[3]||t[4]||t[5]||"").replace(Z,tt),"~="===t[2]&&(t[3]=" "+t[3]+" "),t.slice(0,4)},CHILD:function(t){return t[1]=t[1].toLowerCase(),"nth"===t[1].slice(0,3)?(t[3]||it.error(t[0]),t[4]=+(t[4]?t[5]+(t[6]||1):2*("even"===t[3]||"odd"===t[3])),t[5]=+(t[7]+t[8]||"odd"===t[3])):t[3]&&it.error(t[0]),t},PSEUDO:function(t){var e,n=!t[6]&&t[2];return K.CHILD.test(t[0])?null:(t[3]?t[2]=t[4]||t[5]||"":n&&W.test(n)&&(e=a(n,!0))&&(e=n.indexOf(")",n.length-e)-n.length)&&(t[0]=t[0].slice(0,e),t[2]=n.slice(0,e)),t.slice(0,3))}},filter:{TAG:function(t){var e=t.replace(Z,tt).toLowerCase();return"*"===t?function(){return!0}:function(t){return t.nodeName&&t.nodeName.toLowerCase()===e}},CLASS:function(t){var e=$[t+" "];return e||(e=new RegExp("(^|"+F+")"+t+"("+F+"|$)"))&&$(t,function(t){return e.test("string"==typeof t.className&&t.className||void 0!==t.getAttribute&&t.getAttribute("class")||"")})},ATTR:function(t,e,n){return function(r){var o=it.attr(r,t);return null==o?"!="===e:!e||(o+="","="===e?o===n:"!="===e?o!==n:"^="===e?n&&0===o.indexOf(n):"*="===e?n&&o.indexOf(n)>-1:"$="===e?n&&o.slice(-n.length)===n:"~="===e?(" "+o.replace(H," ")+" ").indexOf(n)>-1:"|="===e&&(o===n||o.slice(0,n.length+1)===n+"-"))}},CHILD:function(t,e,n,r,o){var i="nth"!==t.slice(0,3),a="last"!==t.slice(-4),s="of-type"===e;return 1===r&&0===o?function(t){return!!t.parentNode}:function(e,n,c){var l,u,f,d,p,h,g=i!==a?"nextSibling":"previousSibling",m=e.parentNode,v=s&&e.nodeName.toLowerCase(),y=!c&&!s,b=!1;if(m){if(i){for(;g;){for(d=e;d=d[g];)if(s?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;h=g="only"===t&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&y){for(b=(p=(l=(u=(f=(d=m)[w]||(d[w]={}))[d.uniqueID]||(f[d.uniqueID]={}))[t]||[])[0]===C&&l[1])&&l[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(b=p=0)||h.pop();)if(1===d.nodeType&&++b&&d===e){u[t]=[C,p,b];break}}else if(y&&(b=p=(l=(u=(f=(d=e)[w]||(d[w]={}))[d.uniqueID]||(f[d.uniqueID]={}))[t]||[])[0]===C&&l[1]),!1===b)for(;(d=++p&&d&&d[g]||(b=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++b||(y&&((u=(f=d[w]||(d[w]={}))[d.uniqueID]||(f[d.uniqueID]={}))[t]=[C,b]),d!==e)););return(b-=o)===r||b%r==0&&b/r>=0}}},PSEUDO:function(t,e){var n,o=r.pseudos[t]||r.setFilters[t.toLowerCase()]||it.error("unsupported pseudo: "+t);return o[w]?o(e):o.length>1?(n=[t,t,"",e],r.setFilters.hasOwnProperty(t.toLowerCase())?st(function(t,n){for(var r,i=o(t,e),a=i.length;a--;)t[r=I(t,i[a])]=!(n[r]=i[a])}):function(t){return o(t,0,n)}):o}},pseudos:{not:st(function(t){var e=[],n=[],r=s(t.replace(q,"$1"));return r[w]?st(function(t,e,n,o){for(var i,a=r(t,null,o,[]),s=t.length;s--;)(i=a[s])&&(t[s]=!(e[s]=i))}):function(t,o,i){return e[0]=t,r(e,null,i,n),e[0]=null,!n.pop()}}),has:st(function(t){return function(e){return it(t,e).length>0}}),contains:st(function(t){return t=t.replace(Z,tt),function(e){return(e.textContent||e.innerText||o(e)).indexOf(t)>-1}}),lang:st(function(t){return V.test(t||"")||it.error("unsupported lang: "+t),t=t.replace(Z,tt).toLowerCase(),function(e){var n;do{if(n=g?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(n=n.toLowerCase())===t||0===n.indexOf(t+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var n=t.location&&t.location.hash;return n&&n.slice(1)===e.id},root:function(t){return t===h},focus:function(t){return t===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(t.type||t.href||~t.tabIndex)},enabled:pt(!1),disabled:pt(!0),checked:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&!!t.checked||"option"===e&&!!t.selected},selected:function(t){return t.parentNode&&t.parentNode.selectedIndex,!0===t.selected},empty:function(t){for(t=t.firstChild;t;t=t.nextSibling)if(t.nodeType<6)return!1;return!0},parent:function(t){return!r.pseudos.empty(t)},header:function(t){return Y.test(t.nodeName)},input:function(t){return X.test(t.nodeName)},button:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&"button"===t.type||"button"===e},text:function(t){var e;return"input"===t.nodeName.toLowerCase()&&"text"===t.type&&(null==(e=t.getAttribute("type"))||"text"===e.toLowerCase())},first:ht(function(){return[0]}),last:ht(function(t,e){return[e-1]}),eq:ht(function(t,e,n){return[n<0?n+e:n]}),even:ht(function(t,e){for(var n=0;n=0;)t.push(r);return t}),gt:ht(function(t,e,n){for(var r=n<0?n+e:n;++r1?function(e,n,r){for(var o=t.length;o--;)if(!t[o](e,n,r))return!1;return!0}:t[0]}function wt(t,e,n,r,o){for(var i,a=[],s=0,c=t.length,l=null!=e;s-1&&(i[l]=!(a[l]=f))}}else v=wt(v===a?v.splice(h,v.length):v),o?o(null,a,v,c):j.apply(a,v)})}function Ct(t){for(var e,n,o,i=t.length,a=r.relative[t[0].type],s=a||r.relative[" "],c=a?1:0,u=yt(function(t){return t===e},s,!0),f=yt(function(t){return I(e,t)>-1},s,!0),d=[function(t,n,r){var o=!a&&(r||n!==l)||((e=n).nodeType?u(t,n,r):f(t,n,r));return e=null,o}];c1&&bt(d),c>1&&vt(t.slice(0,c-1).concat({value:" "===t[c-2].type?"*":""})).replace(q,"$1"),n,c0,o=t.length>0,i=function(i,a,s,c,u){var f,h,m,v=0,y="0",b=i&&[],w=[],x=l,_=i||o&&r.find.TAG("*",u),$=C+=null==x?1:Math.random()||.1,T=_.length;for(u&&(l=a===p||a||u);y!==T&&null!=(f=_[y]);y++){if(o&&f){for(h=0,a||f.ownerDocument===p||(d(f),s=!g);m=t[h++];)if(m(f,a||p,s)){c.push(f);break}u&&(C=$)}n&&((f=!m&&f)&&v--,i&&b.push(f))}if(v+=y,n&&y!==v){for(h=0;m=e[h++];)m(b,w,a,s);if(i){if(v>0)for(;y--;)b[y]||w[y]||(w[y]=O.call(c));w=wt(w)}j.apply(c,w),u&&!i&&w.length>0&&v+e.length>1&&it.uniqueSort(c)}return u&&(C=$,l=x),b};return n?st(i):i}(i,o))).selector=t}return s},c=it.select=function(t,e,n,o){var i,c,l,u,f,d="function"==typeof t&&t,p=!o&&a(t=d.selector||t);if(n=n||[],1===p.length){if((c=p[0]=p[0].slice(0)).length>2&&"ID"===(l=c[0]).type&&9===e.nodeType&&g&&r.relative[c[1].type]){if(!(e=(r.find.ID(l.matches[0].replace(Z,tt),e)||[])[0]))return n;d&&(e=e.parentNode),t=t.slice(c.shift().value.length)}for(i=K.needsContext.test(t)?0:c.length;i--&&(l=c[i],!r.relative[u=l.type]);)if((f=r.find[u])&&(o=f(l.matches[0].replace(Z,tt),Q.test(c[0].type)&>(e.parentNode)||e))){if(c.splice(i,1),!(t=o.length&&vt(c)))return j.apply(n,o),n;break}}return(d||s(t,p))(o,e,!g,n,!e||Q.test(t)&>(e.parentNode)||e),n},n.sortStable=w.split("").sort(k).join("")===w,n.detectDuplicates=!!f,d(),n.sortDetached=ct(function(t){return 1&t.compareDocumentPosition(p.createElement("fieldset"))}),ct(function(t){return t.innerHTML="","#"===t.firstChild.getAttribute("href")})||lt("type|href|height|width",function(t,e,n){if(!n)return t.getAttribute(e,"type"===e.toLowerCase()?1:2)}),n.attributes&&ct(function(t){return t.innerHTML="",t.firstChild.setAttribute("value",""),""===t.firstChild.getAttribute("value")})||lt("value",function(t,e,n){if(!n&&"input"===t.nodeName.toLowerCase())return t.defaultValue}),ct(function(t){return null==t.getAttribute("disabled")})||lt(R,function(t,e,n){var r;if(!n)return!0===t[e]?e.toLowerCase():(r=t.getAttributeNode(e))&&r.specified?r.value:null}),it}(n);_.find=S,_.expr=S.selectors,_.expr[":"]=_.expr.pseudos,_.uniqueSort=_.unique=S.uniqueSort,_.text=S.getText,_.isXMLDoc=S.isXML,_.contains=S.contains,_.escapeSelector=S.escape;var k=function(t,e,n){for(var r=[],o=void 0!==n;(t=t[e])&&9!==t.nodeType;)if(1===t.nodeType){if(o&&_(t).is(n))break;r.push(t)}return r},E=function(t,e){for(var n=[];t;t=t.nextSibling)1===t.nodeType&&t!==e&&n.push(t);return n},A=_.expr.match.needsContext;function O(t,e){return t.nodeName&&t.nodeName.toLowerCase()===e.toLowerCase()}var D=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(t,e,n){return y(e)?_.grep(t,function(t,r){return!!e.call(t,r,t)!==n}):e.nodeType?_.grep(t,function(t){return t===e!==n}):"string"!=typeof e?_.grep(t,function(t){return f.call(e,t)>-1!==n}):_.filter(e,t,n)}_.filter=function(t,e,n){var r=e[0];return n&&(t=":not("+t+")"),1===e.length&&1===r.nodeType?_.find.matchesSelector(r,t)?[r]:[]:_.find.matches(t,_.grep(e,function(t){return 1===t.nodeType}))},_.fn.extend({find:function(t){var e,n,r=this.length,o=this;if("string"!=typeof t)return this.pushStack(_(t).filter(function(){for(e=0;e1?_.uniqueSort(n):n},filter:function(t){return this.pushStack(j(this,t||[],!1))},not:function(t){return this.pushStack(j(this,t||[],!0))},is:function(t){return!!j(this,"string"==typeof t&&A.test(t)?_(t):t||[],!1).length}});var N,I=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(_.fn.init=function(t,e,n){var r,o;if(!t)return this;if(n=n||N,"string"==typeof t){if(!(r="<"===t[0]&&">"===t[t.length-1]&&t.length>=3?[null,t,null]:I.exec(t))||!r[1]&&e)return!e||e.jquery?(e||n).find(t):this.constructor(e).find(t);if(r[1]){if(e=e instanceof _?e[0]:e,_.merge(this,_.parseHTML(r[1],e&&e.nodeType?e.ownerDocument||e:a,!0)),D.test(r[1])&&_.isPlainObject(e))for(r in e)y(this[r])?this[r](e[r]):this.attr(r,e[r]);return this}return(o=a.getElementById(r[2]))&&(this[0]=o,this.length=1),this}return t.nodeType?(this[0]=t,this.length=1,this):y(t)?void 0!==n.ready?n.ready(t):t(_):_.makeArray(t,this)}).prototype=_.fn,N=_(a);var R=/^(?:parents|prev(?:Until|All))/,F={children:!0,contents:!0,next:!0,prev:!0};function L(t,e){for(;(t=t[e])&&1!==t.nodeType;);return t}_.fn.extend({has:function(t){var e=_(t,this),n=e.length;return this.filter(function(){for(var t=0;t-1:1===n.nodeType&&_.find.matchesSelector(n,t))){i.push(n);break}return this.pushStack(i.length>1?_.uniqueSort(i):i)},index:function(t){return t?"string"==typeof t?f.call(_(t),this[0]):f.call(this,t.jquery?t[0]:t):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(t,e){return this.pushStack(_.uniqueSort(_.merge(this.get(),_(t,e))))},addBack:function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}}),_.each({parent:function(t){var e=t.parentNode;return e&&11!==e.nodeType?e:null},parents:function(t){return k(t,"parentNode")},parentsUntil:function(t,e,n){return k(t,"parentNode",n)},next:function(t){return L(t,"nextSibling")},prev:function(t){return L(t,"previousSibling")},nextAll:function(t){return k(t,"nextSibling")},prevAll:function(t){return k(t,"previousSibling")},nextUntil:function(t,e,n){return k(t,"nextSibling",n)},prevUntil:function(t,e,n){return k(t,"previousSibling",n)},siblings:function(t){return E((t.parentNode||{}).firstChild,t)},children:function(t){return E(t.firstChild)},contents:function(t){return O(t,"iframe")?t.contentDocument:(O(t,"template")&&(t=t.content||t),_.merge([],t.childNodes))}},function(t,e){_.fn[t]=function(n,r){var o=_.map(this,e,n);return"Until"!==t.slice(-5)&&(r=n),r&&"string"==typeof r&&(o=_.filter(r,o)),this.length>1&&(F[t]||_.uniqueSort(o),R.test(t)&&o.reverse()),this.pushStack(o)}});var M=/[^\x20\t\r\n\f]+/g;function P(t){return t}function H(t){throw t}function q(t,e,n,r){var o;try{t&&y(o=t.promise)?o.call(t).done(e).fail(n):t&&y(o=t.then)?o.call(t,e,n):e.apply(void 0,[t].slice(r))}catch(t){n.apply(void 0,[t])}}_.Callbacks=function(t){t="string"==typeof t?function(t){var e={};return _.each(t.match(M)||[],function(t,n){e[n]=!0}),e}(t):_.extend({},t);var e,n,r,o,i=[],a=[],s=-1,c=function(){for(o=o||t.once,r=e=!0;a.length;s=-1)for(n=a.shift();++s-1;)i.splice(n,1),n<=s&&s--}),this},has:function(t){return t?_.inArray(t,i)>-1:i.length>0},empty:function(){return i&&(i=[]),this},disable:function(){return o=a=[],i=n="",this},disabled:function(){return!i},lock:function(){return o=a=[],n||e||(i=n=""),this},locked:function(){return!!o},fireWith:function(t,n){return o||(n=[t,(n=n||[]).slice?n.slice():n],a.push(n),e||c()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l},_.extend({Deferred:function(t){var e=[["notify","progress",_.Callbacks("memory"),_.Callbacks("memory"),2],["resolve","done",_.Callbacks("once memory"),_.Callbacks("once memory"),0,"resolved"],["reject","fail",_.Callbacks("once memory"),_.Callbacks("once memory"),1,"rejected"]],r="pending",o={state:function(){return r},always:function(){return i.done(arguments).fail(arguments),this},catch:function(t){return o.then(null,t)},pipe:function(){var t=arguments;return _.Deferred(function(n){_.each(e,function(e,r){var o=y(t[r[4]])&&t[r[4]];i[r[1]](function(){var t=o&&o.apply(this,arguments);t&&y(t.promise)?t.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[r[0]+"With"](this,o?[t]:arguments)})}),t=null}).promise()},then:function(t,r,o){var i=0;function a(t,e,r,o){return function(){var s=this,c=arguments,l=function(){var n,l;if(!(t=i&&(r!==H&&(s=void 0,c=[n]),e.rejectWith(s,c))}};t?u():(_.Deferred.getStackHook&&(u.stackTrace=_.Deferred.getStackHook()),n.setTimeout(u))}}return _.Deferred(function(n){e[0][3].add(a(0,n,y(o)?o:P,n.notifyWith)),e[1][3].add(a(0,n,y(t)?t:P)),e[2][3].add(a(0,n,y(r)?r:H))}).promise()},promise:function(t){return null!=t?_.extend(t,o):o}},i={};return _.each(e,function(t,n){var a=n[2],s=n[5];o[n[1]]=a.add,s&&a.add(function(){r=s},e[3-t][2].disable,e[3-t][3].disable,e[0][2].lock,e[0][3].lock),a.add(n[3].fire),i[n[0]]=function(){return i[n[0]+"With"](this===i?void 0:this,arguments),this},i[n[0]+"With"]=a.fireWith}),o.promise(i),t&&t.call(i,i),i},when:function(t){var e=arguments.length,n=e,r=Array(n),o=c.call(arguments),i=_.Deferred(),a=function(t){return function(n){r[t]=this,o[t]=arguments.length>1?c.call(arguments):n,--e||i.resolveWith(r,o)}};if(e<=1&&(q(t,i.done(a(n)).resolve,i.reject,!e),"pending"===i.state()||y(o[n]&&o[n].then)))return i.then();for(;n--;)q(o[n],a(n),i.reject);return i.promise()}});var z=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;_.Deferred.exceptionHook=function(t,e){n.console&&n.console.warn&&t&&z.test(t.name)&&n.console.warn("jQuery.Deferred exception: "+t.message,t.stack,e)},_.readyException=function(t){n.setTimeout(function(){throw t})};var B=_.Deferred();function U(){a.removeEventListener("DOMContentLoaded",U),n.removeEventListener("load",U),_.ready()}_.fn.ready=function(t){return B.then(t).catch(function(t){_.readyException(t)}),this},_.extend({isReady:!1,readyWait:1,ready:function(t){(!0===t?--_.readyWait:_.isReady)||(_.isReady=!0,!0!==t&&--_.readyWait>0||B.resolveWith(a,[_]))}}),_.ready.then=B.then,"complete"===a.readyState||"loading"!==a.readyState&&!a.documentElement.doScroll?n.setTimeout(_.ready):(a.addEventListener("DOMContentLoaded",U),n.addEventListener("load",U));var W=function(t,e,n,r,o,i,a){var s=0,c=t.length,l=null==n;if("object"===C(n))for(s in o=!0,n)W(t,e,s,n[s],!0,i,a);else if(void 0!==r&&(o=!0,y(r)||(a=!0),l&&(a?(e.call(t,r),e=null):(l=e,e=function(t,e,n){return l.call(_(t),n)})),e))for(;s1,null,!0)},removeData:function(t){return this.each(function(){Z.remove(this,t)})}}),_.extend({queue:function(t,e,n){var r;if(t)return e=(e||"fx")+"queue",r=Q.get(t,e),n&&(!r||Array.isArray(n)?r=Q.access(t,e,_.makeArray(n)):r.push(n)),r||[]},dequeue:function(t,e){e=e||"fx";var n=_.queue(t,e),r=n.length,o=n.shift(),i=_._queueHooks(t,e);"inprogress"===o&&(o=n.shift(),r--),o&&("fx"===e&&n.unshift("inprogress"),delete i.stop,o.call(t,function(){_.dequeue(t,e)},i)),!r&&i&&i.empty.fire()},_queueHooks:function(t,e){var n=e+"queueHooks";return Q.get(t,n)||Q.access(t,n,{empty:_.Callbacks("once memory").add(function(){Q.remove(t,[e+"queue",n])})})}}),_.fn.extend({queue:function(t,e){var n=2;return"string"!=typeof t&&(e=t,t="fx",n--),arguments.length\x20\t\r\n\f]+)/i,ht=/^$|^module$|\/(?:java|ecma)script/i,gt={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function mt(t,e){var n;return n=void 0!==t.getElementsByTagName?t.getElementsByTagName(e||"*"):void 0!==t.querySelectorAll?t.querySelectorAll(e||"*"):[],void 0===e||e&&O(t,e)?_.merge([t],n):n}function vt(t,e){for(var n=0,r=t.length;n-1)o&&o.push(i);else if(l=_.contains(i.ownerDocument,i),a=mt(f.appendChild(i),"script"),l&&vt(a),n)for(u=0;i=a[u++];)ht.test(i.type||"")&&n.push(i);return f}yt=a.createDocumentFragment().appendChild(a.createElement("div")),(bt=a.createElement("input")).setAttribute("type","radio"),bt.setAttribute("checked","checked"),bt.setAttribute("name","t"),yt.appendChild(bt),v.checkClone=yt.cloneNode(!0).cloneNode(!0).lastChild.checked,yt.innerHTML="",v.noCloneChecked=!!yt.cloneNode(!0).lastChild.defaultValue;var Ct=a.documentElement,_t=/^key/,$t=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Tt=/^([^.]*)(?:\.(.+)|)/;function St(){return!0}function kt(){return!1}function Et(){try{return a.activeElement}catch(t){}}function At(t,e,n,r,o,i){var a,s;if("object"==typeof e){for(s in"string"!=typeof n&&(r=r||n,n=void 0),e)At(t,s,n,r,e[s],i);return t}if(null==r&&null==o?(o=n,r=n=void 0):null==o&&("string"==typeof n?(o=r,r=void 0):(o=r,r=n,n=void 0)),!1===o)o=kt;else if(!o)return t;return 1===i&&(a=o,(o=function(t){return _().off(t),a.apply(this,arguments)}).guid=a.guid||(a.guid=_.guid++)),t.each(function(){_.event.add(this,e,o,r,n)})}_.event={global:{},add:function(t,e,n,r,o){var i,a,s,c,l,u,f,d,p,h,g,m=Q.get(t);if(m)for(n.handler&&(n=(i=n).handler,o=i.selector),o&&_.find.matchesSelector(Ct,o),n.guid||(n.guid=_.guid++),(c=m.events)||(c=m.events={}),(a=m.handle)||(a=m.handle=function(e){return void 0!==_&&_.event.triggered!==e.type?_.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(M)||[""]).length;l--;)p=g=(s=Tt.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),p&&(f=_.event.special[p]||{},p=(o?f.delegateType:f.bindType)||p,f=_.event.special[p]||{},u=_.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:o,needsContext:o&&_.expr.match.needsContext.test(o),namespace:h.join(".")},i),(d=c[p])||((d=c[p]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(p,a)),f.add&&(f.add.call(t,u),u.handler.guid||(u.handler.guid=n.guid)),o?d.splice(d.delegateCount++,0,u):d.push(u),_.event.global[p]=!0)},remove:function(t,e,n,r,o){var i,a,s,c,l,u,f,d,p,h,g,m=Q.hasData(t)&&Q.get(t);if(m&&(c=m.events)){for(l=(e=(e||"").match(M)||[""]).length;l--;)if(p=g=(s=Tt.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),p){for(f=_.event.special[p]||{},d=c[p=(r?f.delegateType:f.bindType)||p]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=i=d.length;i--;)u=d[i],!o&&g!==u.origType||n&&n.guid!==u.guid||s&&!s.test(u.namespace)||r&&r!==u.selector&&("**"!==r||!u.selector)||(d.splice(i,1),u.selector&&d.delegateCount--,f.remove&&f.remove.call(t,u));a&&!d.length&&(f.teardown&&!1!==f.teardown.call(t,h,m.handle)||_.removeEvent(t,p,m.handle),delete c[p])}else for(p in c)_.event.remove(t,p+e[l],n,r,!0);_.isEmptyObject(c)&&Q.remove(t,"handle events")}},dispatch:function(t){var e,n,r,o,i,a,s=_.event.fix(t),c=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],u=_.event.special[s.type]||{};for(c[0]=s,e=1;e=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==t.type||!0!==l.disabled)){for(i=[],a={},n=0;n-1:_.find(o,this,null,[l]).length),a[o]&&i.push(r);i.length&&s.push({elem:l,handlers:i})}return l=this,c\x20\t\r\n\f]*)[^>]*)\/>/gi,Dt=/\s*$/g;function It(t,e){return O(t,"table")&&O(11!==e.nodeType?e:e.firstChild,"tr")&&_(t).children("tbody")[0]||t}function Rt(t){return t.type=(null!==t.getAttribute("type"))+"/"+t.type,t}function Ft(t){return"true/"===(t.type||"").slice(0,5)?t.type=t.type.slice(5):t.removeAttribute("type"),t}function Lt(t,e){var n,r,o,i,a,s,c,l;if(1===e.nodeType){if(Q.hasData(t)&&(i=Q.access(t),a=Q.set(e,i),l=i.events))for(o in delete a.handle,a.events={},l)for(n=0,r=l[o].length;n1&&"string"==typeof h&&!v.checkClone&&jt.test(h))return t.each(function(o){var i=t.eq(o);g&&(e[0]=h.call(this,o,i.html())),Mt(i,e,n,r)});if(d&&(i=(o=xt(e,t[0].ownerDocument,!1,t,r)).firstChild,1===o.childNodes.length&&(o=i),i||r)){for(s=(a=_.map(mt(o,"script"),Rt)).length;f")},clone:function(t,e,n){var r,o,i,a,s,c,l,u=t.cloneNode(!0),f=_.contains(t.ownerDocument,t);if(!(v.noCloneChecked||1!==t.nodeType&&11!==t.nodeType||_.isXMLDoc(t)))for(a=mt(u),r=0,o=(i=mt(t)).length;r0&&vt(a,!f&&mt(t,"script")),u},cleanData:function(t){for(var e,n,r,o=_.event.special,i=0;void 0!==(n=t[i]);i++)if(G(n)){if(e=n[Q.expando]){if(e.events)for(r in e.events)o[r]?_.event.remove(n,r):_.removeEvent(n,r,e.handle);n[Q.expando]=void 0}n[Z.expando]&&(n[Z.expando]=void 0)}}}),_.fn.extend({detach:function(t){return Pt(this,t,!0)},remove:function(t){return Pt(this,t)},text:function(t){return W(this,function(t){return void 0===t?_.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=t)})},null,t,arguments.length)},append:function(){return Mt(this,arguments,function(t){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||It(this,t).appendChild(t)})},prepend:function(){return Mt(this,arguments,function(t){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var e=It(this,t);e.insertBefore(t,e.firstChild)}})},before:function(){return Mt(this,arguments,function(t){this.parentNode&&this.parentNode.insertBefore(t,this)})},after:function(){return Mt(this,arguments,function(t){this.parentNode&&this.parentNode.insertBefore(t,this.nextSibling)})},empty:function(){for(var t,e=0;null!=(t=this[e]);e++)1===t.nodeType&&(_.cleanData(mt(t,!1)),t.textContent="");return this},clone:function(t,e){return t=null!=t&&t,e=null==e?t:e,this.map(function(){return _.clone(this,t,e)})},html:function(t){return W(this,function(t){var e=this[0]||{},n=0,r=this.length;if(void 0===t&&1===e.nodeType)return e.innerHTML;if("string"==typeof t&&!Dt.test(t)&&!gt[(pt.exec(t)||["",""])[1].toLowerCase()]){t=_.htmlPrefilter(t);try{for(;n=0&&(c+=Math.max(0,Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-i-c-s-.5))),c}function te(t,e,n){var r=qt(t),o=Bt(t,e,r),i="border-box"===_.css(t,"boxSizing",!1,r),a=i;if(Ht.test(o)){if(!n)return o;o="auto"}return a=a&&(v.boxSizingReliable()||o===t.style[e]),("auto"===o||!parseFloat(o)&&"inline"===_.css(t,"display",!1,r))&&(o=t["offset"+e[0].toUpperCase()+e.slice(1)],a=!0),(o=parseFloat(o)||0)+Zt(t,e,n||(i?"border":"content"),a,r,o)+"px"}function ee(t,e,n,r,o){return new ee.prototype.init(t,e,n,r,o)}_.extend({cssHooks:{opacity:{get:function(t,e){if(e){var n=Bt(t,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(t,e,n,r){if(t&&3!==t.nodeType&&8!==t.nodeType&&t.style){var o,i,a,s=Y(e),c=Vt.test(e),l=t.style;if(c||(e=Jt(s)),a=_.cssHooks[e]||_.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(o=a.get(t,!1,r))?o:l[e];"string"===(i=typeof n)&&(o=ot.exec(n))&&o[1]&&(n=ct(t,e,o),i="number"),null!=n&&n==n&&("number"===i&&(n+=o&&o[3]||(_.cssNumber[s]?"":"px")),v.clearCloneStyle||""!==n||0!==e.indexOf("background")||(l[e]="inherit"),a&&"set"in a&&void 0===(n=a.set(t,n,r))||(c?l.setProperty(e,n):l[e]=n))}},css:function(t,e,n,r){var o,i,a,s=Y(e);return Vt.test(e)||(e=Jt(s)),(a=_.cssHooks[e]||_.cssHooks[s])&&"get"in a&&(o=a.get(t,!0,n)),void 0===o&&(o=Bt(t,e,r)),"normal"===o&&e in Xt&&(o=Xt[e]),""===n||n?(i=parseFloat(o),!0===n||isFinite(i)?i||0:o):o}}),_.each(["height","width"],function(t,e){_.cssHooks[e]={get:function(t,n,r){if(n)return!Wt.test(_.css(t,"display"))||t.getClientRects().length&&t.getBoundingClientRect().width?te(t,e,r):st(t,Kt,function(){return te(t,e,r)})},set:function(t,n,r){var o,i=qt(t),a="border-box"===_.css(t,"boxSizing",!1,i),s=r&&Zt(t,e,r,a,i);return a&&v.scrollboxSize()===i.position&&(s-=Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-parseFloat(i[e])-Zt(t,e,"border",!1,i)-.5)),s&&(o=ot.exec(n))&&"px"!==(o[3]||"px")&&(t.style[e]=n,n=_.css(t,e)),Qt(0,n,s)}}}),_.cssHooks.marginLeft=Ut(v.reliableMarginLeft,function(t,e){if(e)return(parseFloat(Bt(t,"marginLeft"))||t.getBoundingClientRect().left-st(t,{marginLeft:0},function(){return t.getBoundingClientRect().left}))+"px"}),_.each({margin:"",padding:"",border:"Width"},function(t,e){_.cssHooks[t+e]={expand:function(n){for(var r=0,o={},i="string"==typeof n?n.split(" "):[n];r<4;r++)o[t+it[r]+e]=i[r]||i[r-2]||i[0];return o}},"margin"!==t&&(_.cssHooks[t+e].set=Qt)}),_.fn.extend({css:function(t,e){return W(this,function(t,e,n){var r,o,i={},a=0;if(Array.isArray(e)){for(r=qt(t),o=e.length;a1)}}),_.Tween=ee,ee.prototype={constructor:ee,init:function(t,e,n,r,o,i){this.elem=t,this.prop=n,this.easing=o||_.easing._default,this.options=e,this.start=this.now=this.cur(),this.end=r,this.unit=i||(_.cssNumber[n]?"":"px")},cur:function(){var t=ee.propHooks[this.prop];return t&&t.get?t.get(this):ee.propHooks._default.get(this)},run:function(t){var e,n=ee.propHooks[this.prop];return this.options.duration?this.pos=e=_.easing[this.easing](t,this.options.duration*t,0,1,this.options.duration):this.pos=e=t,this.now=(this.end-this.start)*e+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):ee.propHooks._default.set(this),this}},ee.prototype.init.prototype=ee.prototype,ee.propHooks={_default:{get:function(t){var e;return 1!==t.elem.nodeType||null!=t.elem[t.prop]&&null==t.elem.style[t.prop]?t.elem[t.prop]:(e=_.css(t.elem,t.prop,""))&&"auto"!==e?e:0},set:function(t){_.fx.step[t.prop]?_.fx.step[t.prop](t):1!==t.elem.nodeType||null==t.elem.style[_.cssProps[t.prop]]&&!_.cssHooks[t.prop]?t.elem[t.prop]=t.now:_.style(t.elem,t.prop,t.now+t.unit)}}},ee.propHooks.scrollTop=ee.propHooks.scrollLeft={set:function(t){t.elem.nodeType&&t.elem.parentNode&&(t.elem[t.prop]=t.now)}},_.easing={linear:function(t){return t},swing:function(t){return.5-Math.cos(t*Math.PI)/2},_default:"swing"},_.fx=ee.prototype.init,_.fx.step={};var ne,re,oe=/^(?:toggle|show|hide)$/,ie=/queueHooks$/;function ae(){re&&(!1===a.hidden&&n.requestAnimationFrame?n.requestAnimationFrame(ae):n.setTimeout(ae,_.fx.interval),_.fx.tick())}function se(){return n.setTimeout(function(){ne=void 0}),ne=Date.now()}function ce(t,e){var n,r=0,o={height:t};for(e=e?1:0;r<4;r+=2-e)o["margin"+(n=it[r])]=o["padding"+n]=t;return e&&(o.opacity=o.width=t),o}function le(t,e,n){for(var r,o=(ue.tweeners[e]||[]).concat(ue.tweeners["*"]),i=0,a=o.length;i1)},removeAttr:function(t){return this.each(function(){_.removeAttr(this,t)})}}),_.extend({attr:function(t,e,n){var r,o,i=t.nodeType;if(3!==i&&8!==i&&2!==i)return void 0===t.getAttribute?_.prop(t,e,n):(1===i&&_.isXMLDoc(t)||(o=_.attrHooks[e.toLowerCase()]||(_.expr.match.bool.test(e)?fe:void 0)),void 0!==n?null===n?void _.removeAttr(t,e):o&&"set"in o&&void 0!==(r=o.set(t,n,e))?r:(t.setAttribute(e,n+""),n):o&&"get"in o&&null!==(r=o.get(t,e))?r:null==(r=_.find.attr(t,e))?void 0:r)},attrHooks:{type:{set:function(t,e){if(!v.radioValue&&"radio"===e&&O(t,"input")){var n=t.value;return t.setAttribute("type",e),n&&(t.value=n),e}}}},removeAttr:function(t,e){var n,r=0,o=e&&e.match(M);if(o&&1===t.nodeType)for(;n=o[r++];)t.removeAttribute(n)}}),fe={set:function(t,e,n){return!1===e?_.removeAttr(t,n):t.setAttribute(n,n),n}},_.each(_.expr.match.bool.source.match(/\w+/g),function(t,e){var n=de[e]||_.find.attr;de[e]=function(t,e,r){var o,i,a=e.toLowerCase();return r||(i=de[a],de[a]=o,o=null!=n(t,e,r)?a:null,de[a]=i),o}});var pe=/^(?:input|select|textarea|button)$/i,he=/^(?:a|area)$/i;function ge(t){return(t.match(M)||[]).join(" ")}function me(t){return t.getAttribute&&t.getAttribute("class")||""}function ve(t){return Array.isArray(t)?t:"string"==typeof t&&t.match(M)||[]}_.fn.extend({prop:function(t,e){return W(this,_.prop,t,e,arguments.length>1)},removeProp:function(t){return this.each(function(){delete this[_.propFix[t]||t]})}}),_.extend({prop:function(t,e,n){var r,o,i=t.nodeType;if(3!==i&&8!==i&&2!==i)return 1===i&&_.isXMLDoc(t)||(e=_.propFix[e]||e,o=_.propHooks[e]),void 0!==n?o&&"set"in o&&void 0!==(r=o.set(t,n,e))?r:t[e]=n:o&&"get"in o&&null!==(r=o.get(t,e))?r:t[e]},propHooks:{tabIndex:{get:function(t){var e=_.find.attr(t,"tabindex");return e?parseInt(e,10):pe.test(t.nodeName)||he.test(t.nodeName)&&t.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),v.optSelected||(_.propHooks.selected={get:function(t){var e=t.parentNode;return e&&e.parentNode&&e.parentNode.selectedIndex,null},set:function(t){var e=t.parentNode;e&&(e.selectedIndex,e.parentNode&&e.parentNode.selectedIndex)}}),_.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){_.propFix[this.toLowerCase()]=this}),_.fn.extend({addClass:function(t){var e,n,r,o,i,a,s,c=0;if(y(t))return this.each(function(e){_(this).addClass(t.call(this,e,me(this)))});if((e=ve(t)).length)for(;n=this[c++];)if(o=me(n),r=1===n.nodeType&&" "+ge(o)+" "){for(a=0;i=e[a++];)r.indexOf(" "+i+" ")<0&&(r+=i+" ");o!==(s=ge(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,o,i,a,s,c=0;if(y(t))return this.each(function(e){_(this).removeClass(t.call(this,e,me(this)))});if(!arguments.length)return this.attr("class","");if((e=ve(t)).length)for(;n=this[c++];)if(o=me(n),r=1===n.nodeType&&" "+ge(o)+" "){for(a=0;i=e[a++];)for(;r.indexOf(" "+i+" ")>-1;)r=r.replace(" "+i+" "," ");o!==(s=ge(r))&&n.setAttribute("class",s)}return this},toggleClass:function(t,e){var n=typeof t,r="string"===n||Array.isArray(t);return"boolean"==typeof e&&r?e?this.addClass(t):this.removeClass(t):y(t)?this.each(function(n){_(this).toggleClass(t.call(this,n,me(this),e),e)}):this.each(function(){var e,o,i,a;if(r)for(o=0,i=_(this),a=ve(t);e=a[o++];)i.hasClass(e)?i.removeClass(e):i.addClass(e);else void 0!==t&&"boolean"!==n||((e=me(this))&&Q.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===t?"":Q.get(this,"__className__")||""))})},hasClass:function(t){var e,n,r=0;for(e=" "+t+" ";n=this[r++];)if(1===n.nodeType&&(" "+ge(me(n))+" ").indexOf(e)>-1)return!0;return!1}});var ye=/\r/g;_.fn.extend({val:function(t){var e,n,r,o=this[0];return arguments.length?(r=y(t),this.each(function(n){var o;1===this.nodeType&&(null==(o=r?t.call(this,n,_(this).val()):t)?o="":"number"==typeof o?o+="":Array.isArray(o)&&(o=_.map(o,function(t){return null==t?"":t+""})),(e=_.valHooks[this.type]||_.valHooks[this.nodeName.toLowerCase()])&&"set"in e&&void 0!==e.set(this,o,"value")||(this.value=o))})):o?(e=_.valHooks[o.type]||_.valHooks[o.nodeName.toLowerCase()])&&"get"in e&&void 0!==(n=e.get(o,"value"))?n:"string"==typeof(n=o.value)?n.replace(ye,""):null==n?"":n:void 0}}),_.extend({valHooks:{option:{get:function(t){var e=_.find.attr(t,"value");return null!=e?e:ge(_.text(t))}},select:{get:function(t){var e,n,r,o=t.options,i=t.selectedIndex,a="select-one"===t.type,s=a?null:[],c=a?i+1:o.length;for(r=i<0?c:a?i:0;r-1)&&(n=!0);return n||(t.selectedIndex=-1),i}}}}),_.each(["radio","checkbox"],function(){_.valHooks[this]={set:function(t,e){if(Array.isArray(e))return t.checked=_.inArray(_(t).val(),e)>-1}},v.checkOn||(_.valHooks[this].get=function(t){return null===t.getAttribute("value")?"on":t.value})}),v.focusin="onfocusin"in n;var be=/^(?:focusinfocus|focusoutblur)$/,we=function(t){t.stopPropagation()};_.extend(_.event,{trigger:function(t,e,r,o){var i,s,c,l,u,f,d,p,g=[r||a],m=h.call(t,"type")?t.type:t,v=h.call(t,"namespace")?t.namespace.split("."):[];if(s=p=c=r=r||a,3!==r.nodeType&&8!==r.nodeType&&!be.test(m+_.event.triggered)&&(m.indexOf(".")>-1&&(v=m.split("."),m=v.shift(),v.sort()),u=m.indexOf(":")<0&&"on"+m,(t=t[_.expando]?t:new _.Event(m,"object"==typeof t&&t)).isTrigger=o?2:3,t.namespace=v.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+v.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=r),e=null==e?[t]:_.makeArray(e,[t]),d=_.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(r,e))){if(!o&&!d.noBubble&&!b(r)){for(l=d.delegateType||m,be.test(l+m)||(s=s.parentNode);s;s=s.parentNode)g.push(s),c=s;c===(r.ownerDocument||a)&&g.push(c.defaultView||c.parentWindow||n)}for(i=0;(s=g[i++])&&!t.isPropagationStopped();)p=s,t.type=i>1?l:d.bindType||m,(f=(Q.get(s,"events")||{})[t.type]&&Q.get(s,"handle"))&&f.apply(s,e),(f=u&&s[u])&&f.apply&&G(s)&&(t.result=f.apply(s,e),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(g.pop(),e)||!G(r)||u&&y(r[m])&&!b(r)&&((c=r[u])&&(r[u]=null),_.event.triggered=m,t.isPropagationStopped()&&p.addEventListener(m,we),r[m](),t.isPropagationStopped()&&p.removeEventListener(m,we),_.event.triggered=void 0,c&&(r[u]=c)),t.result}},simulate:function(t,e,n){var r=_.extend(new _.Event,n,{type:t,isSimulated:!0});_.event.trigger(r,null,e)}}),_.fn.extend({trigger:function(t,e){return this.each(function(){_.event.trigger(t,e,this)})},triggerHandler:function(t,e){var n=this[0];if(n)return _.event.trigger(t,e,n,!0)}}),v.focusin||_.each({focus:"focusin",blur:"focusout"},function(t,e){var n=function(t){_.event.simulate(e,t.target,_.event.fix(t))};_.event.special[e]={setup:function(){var r=this.ownerDocument||this,o=Q.access(r,e);o||r.addEventListener(t,n,!0),Q.access(r,e,(o||0)+1)},teardown:function(){var r=this.ownerDocument||this,o=Q.access(r,e)-1;o?Q.access(r,e,o):(r.removeEventListener(t,n,!0),Q.remove(r,e))}}});var xe=n.location,Ce=Date.now(),_e=/\?/;_.parseXML=function(t){var e;if(!t||"string"!=typeof t)return null;try{e=(new n.DOMParser).parseFromString(t,"text/xml")}catch(t){e=void 0}return e&&!e.getElementsByTagName("parsererror").length||_.error("Invalid XML: "+t),e};var $e=/\[\]$/,Te=/\r?\n/g,Se=/^(?:submit|button|image|reset|file)$/i,ke=/^(?:input|select|textarea|keygen)/i;function Ee(t,e,n,r){var o;if(Array.isArray(e))_.each(e,function(e,o){n||$e.test(t)?r(t,o):Ee(t+"["+("object"==typeof o&&null!=o?e:"")+"]",o,n,r)});else if(n||"object"!==C(e))r(t,e);else for(o in e)Ee(t+"["+o+"]",e[o],n,r)}_.param=function(t,e){var n,r=[],o=function(t,e){var n=y(e)?e():e;r[r.length]=encodeURIComponent(t)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(t)||t.jquery&&!_.isPlainObject(t))_.each(t,function(){o(this.name,this.value)});else for(n in t)Ee(n,t[n],e,o);return r.join("&")},_.fn.extend({serialize:function(){return _.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var t=_.prop(this,"elements");return t?_.makeArray(t):this}).filter(function(){var t=this.type;return this.name&&!_(this).is(":disabled")&&ke.test(this.nodeName)&&!Se.test(t)&&(this.checked||!dt.test(t))}).map(function(t,e){var n=_(this).val();return null==n?null:Array.isArray(n)?_.map(n,function(t){return{name:e.name,value:t.replace(Te,"\r\n")}}):{name:e.name,value:n.replace(Te,"\r\n")}}).get()}});var Ae=/%20/g,Oe=/#.*$/,De=/([?&])_=[^&]*/,je=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ne=/^(?:GET|HEAD)$/,Ie=/^\/\//,Re={},Fe={},Le="*/".concat("*"),Me=a.createElement("a");function Pe(t){return function(e,n){"string"!=typeof e&&(n=e,e="*");var r,o=0,i=e.toLowerCase().match(M)||[];if(y(n))for(;r=i[o++];)"+"===r[0]?(r=r.slice(1)||"*",(t[r]=t[r]||[]).unshift(n)):(t[r]=t[r]||[]).push(n)}}function He(t,e,n,r){var o={},i=t===Fe;function a(s){var c;return o[s]=!0,_.each(t[s]||[],function(t,s){var l=s(e,n,r);return"string"!=typeof l||i||o[l]?i?!(c=l):void 0:(e.dataTypes.unshift(l),a(l),!1)}),c}return a(e.dataTypes[0])||!o["*"]&&a("*")}function qe(t,e){var n,r,o=_.ajaxSettings.flatOptions||{};for(n in e)void 0!==e[n]&&((o[n]?t:r||(r={}))[n]=e[n]);return r&&_.extend(!0,t,r),t}Me.href=xe.href,_.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:xe.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(xe.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Le,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":_.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(t,e){return e?qe(qe(t,_.ajaxSettings),e):qe(_.ajaxSettings,t)},ajaxPrefilter:Pe(Re),ajaxTransport:Pe(Fe),ajax:function(t,e){"object"==typeof t&&(e=t,t=void 0),e=e||{};var r,o,i,s,c,l,u,f,d,p,h=_.ajaxSetup({},e),g=h.context||h,m=h.context&&(g.nodeType||g.jquery)?_(g):_.event,v=_.Deferred(),y=_.Callbacks("once memory"),b=h.statusCode||{},w={},x={},C="canceled",$={readyState:0,getResponseHeader:function(t){var e;if(u){if(!s)for(s={};e=je.exec(i);)s[e[1].toLowerCase()]=e[2];e=s[t.toLowerCase()]}return null==e?null:e},getAllResponseHeaders:function(){return u?i:null},setRequestHeader:function(t,e){return null==u&&(t=x[t.toLowerCase()]=x[t.toLowerCase()]||t,w[t]=e),this},overrideMimeType:function(t){return null==u&&(h.mimeType=t),this},statusCode:function(t){var e;if(t)if(u)$.always(t[$.status]);else for(e in t)b[e]=[b[e],t[e]];return this},abort:function(t){var e=t||C;return r&&r.abort(e),T(0,e),this}};if(v.promise($),h.url=((t||h.url||xe.href)+"").replace(Ie,xe.protocol+"//"),h.type=e.method||e.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=a.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Me.protocol+"//"+Me.host!=l.protocol+"//"+l.host}catch(t){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=_.param(h.data,h.traditional)),He(Re,h,e,$),u)return $;for(d in(f=_.event&&h.global)&&0==_.active++&&_.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Ne.test(h.type),o=h.url.replace(Oe,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(Ae,"+")):(p=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(_e.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(De,"$1"),p=(_e.test(o)?"&":"?")+"_="+Ce+++p),h.url=o+p),h.ifModified&&(_.lastModified[o]&&$.setRequestHeader("If-Modified-Since",_.lastModified[o]),_.etag[o]&&$.setRequestHeader("If-None-Match",_.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||e.contentType)&&$.setRequestHeader("Content-Type",h.contentType),$.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+Le+"; q=0.01":""):h.accepts["*"]),h.headers)$.setRequestHeader(d,h.headers[d]);if(h.beforeSend&&(!1===h.beforeSend.call(g,$,h)||u))return $.abort();if(C="abort",y.add(h.complete),$.done(h.success),$.fail(h.error),r=He(Fe,h,e,$)){if($.readyState=1,f&&m.trigger("ajaxSend",[$,h]),u)return $;h.async&&h.timeout>0&&(c=n.setTimeout(function(){$.abort("timeout")},h.timeout));try{u=!1,r.send(w,T)}catch(t){if(u)throw t;T(-1,t)}}else T(-1,"No Transport");function T(t,e,a,s){var l,d,p,w,x,C=e;u||(u=!0,c&&n.clearTimeout(c),r=void 0,i=s||"",$.readyState=t>0?4:0,l=t>=200&&t<300||304===t,a&&(w=function(t,e,n){for(var r,o,i,a,s=t.contents,c=t.dataTypes;"*"===c[0];)c.shift(),void 0===r&&(r=t.mimeType||e.getResponseHeader("Content-Type"));if(r)for(o in s)if(s[o]&&s[o].test(r)){c.unshift(o);break}if(c[0]in n)i=c[0];else{for(o in n){if(!c[0]||t.converters[o+" "+c[0]]){i=o;break}a||(a=o)}i=i||a}if(i)return i!==c[0]&&c.unshift(i),n[i]}(h,$,a)),w=function(t,e,n,r){var o,i,a,s,c,l={},u=t.dataTypes.slice();if(u[1])for(a in t.converters)l[a.toLowerCase()]=t.converters[a];for(i=u.shift();i;)if(t.responseFields[i]&&(n[t.responseFields[i]]=e),!c&&r&&t.dataFilter&&(e=t.dataFilter(e,t.dataType)),c=i,i=u.shift())if("*"===i)i=c;else if("*"!==c&&c!==i){if(!(a=l[c+" "+i]||l["* "+i]))for(o in l)if((s=o.split(" "))[1]===i&&(a=l[c+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[o]:!0!==l[o]&&(i=s[0],u.unshift(s[1]));break}if(!0!==a)if(a&&t.throws)e=a(e);else try{e=a(e)}catch(t){return{state:"parsererror",error:a?t:"No conversion from "+c+" to "+i}}}return{state:"success",data:e}}(h,w,$,l),l?(h.ifModified&&((x=$.getResponseHeader("Last-Modified"))&&(_.lastModified[o]=x),(x=$.getResponseHeader("etag"))&&(_.etag[o]=x)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=w.state,d=w.data,l=!(p=w.error))):(p=C,!t&&C||(C="error",t<0&&(t=0))),$.status=t,$.statusText=(e||C)+"",l?v.resolveWith(g,[d,C,$]):v.rejectWith(g,[$,C,p]),$.statusCode(b),b=void 0,f&&m.trigger(l?"ajaxSuccess":"ajaxError",[$,h,l?d:p]),y.fireWith(g,[$,C]),f&&(m.trigger("ajaxComplete",[$,h]),--_.active||_.event.trigger("ajaxStop")))}return $},getJSON:function(t,e,n){return _.get(t,e,n,"json")},getScript:function(t,e){return _.get(t,void 0,e,"script")}}),_.each(["get","post"],function(t,e){_[e]=function(t,n,r,o){return y(n)&&(o=o||r,r=n,n=void 0),_.ajax(_.extend({url:t,type:e,dataType:o,data:n,success:r},_.isPlainObject(t)&&t))}}),_._evalUrl=function(t){return _.ajax({url:t,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},_.fn.extend({wrapAll:function(t){var e;return this[0]&&(y(t)&&(t=t.call(this[0])),e=_(t,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&e.insertBefore(this[0]),e.map(function(){for(var t=this;t.firstElementChild;)t=t.firstElementChild;return t}).append(this)),this},wrapInner:function(t){return y(t)?this.each(function(e){_(this).wrapInner(t.call(this,e))}):this.each(function(){var e=_(this),n=e.contents();n.length?n.wrapAll(t):e.append(t)})},wrap:function(t){var e=y(t);return this.each(function(n){_(this).wrapAll(e?t.call(this,n):t)})},unwrap:function(t){return this.parent(t).not("body").each(function(){_(this).replaceWith(this.childNodes)}),this}}),_.expr.pseudos.hidden=function(t){return!_.expr.pseudos.visible(t)},_.expr.pseudos.visible=function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)},_.ajaxSettings.xhr=function(){try{return new n.XMLHttpRequest}catch(t){}};var ze={0:200,1223:204},Be=_.ajaxSettings.xhr();v.cors=!!Be&&"withCredentials"in Be,v.ajax=Be=!!Be,_.ajaxTransport(function(t){var e,r;if(v.cors||Be&&!t.crossDomain)return{send:function(o,i){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];for(a in t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||o["X-Requested-With"]||(o["X-Requested-With"]="XMLHttpRequest"),o)s.setRequestHeader(a,o[a]);e=function(t){return function(){e&&(e=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===t?s.abort():"error"===t?"number"!=typeof s.status?i(0,"error"):i(s.status,s.statusText):i(ze[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=e(),r=s.onerror=s.ontimeout=e("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&n.setTimeout(function(){e&&r()})},e=e("abort");try{s.send(t.hasContent&&t.data||null)}catch(t){if(e)throw t}},abort:function(){e&&e()}}}),_.ajaxPrefilter(function(t){t.crossDomain&&(t.contents.script=!1)}),_.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(t){return _.globalEval(t),t}}}),_.ajaxPrefilter("script",function(t){void 0===t.cache&&(t.cache=!1),t.crossDomain&&(t.type="GET")}),_.ajaxTransport("script",function(t){var e,n;if(t.crossDomain)return{send:function(r,o){e=_("\n\n\n\n\n\n// WEBPACK FOOTER //\n// Button.vue?3b36fc63","import Vue from 'vue'\nimport Button from './Button.vue'\n\nconst plugin = {\n install(Vue, options) {\n \tVue.component('ToggleButton', Button)\n }\n}\n\nexport default plugin\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js","exports = module.exports = require(\"../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".vue-js-switch[data-v-25adc6c0]{display:inline-block;position:relative;overflow:hidden;vertical-align:middle;user-select:none;font-size:10px;cursor:pointer}.vue-js-switch .v-switch-input[data-v-25adc6c0]{display:none}.vue-js-switch .v-switch-label[data-v-25adc6c0]{position:absolute;top:0;font-weight:600;color:#fff}.vue-js-switch .v-switch-label.v-left[data-v-25adc6c0]{left:10px}.vue-js-switch .v-switch-label.v-right[data-v-25adc6c0]{right:10px}.vue-js-switch .v-switch-core[data-v-25adc6c0]{display:block;position:relative;box-sizing:border-box;outline:0;margin:0;transition:border-color .3s,background-color .3s;user-select:none}.vue-js-switch .v-switch-core .v-switch-button[data-v-25adc6c0]{display:block;position:absolute;overflow:hidden;top:0;left:0;transform:translate3d(3px,3px,0);border-radius:100%;background-color:#fff}.vue-js-switch.disabled[data-v-25adc6c0]{pointer-events:none;opacity:.6}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader!./~/vue-loader/lib/style-compiler?{\"id\":\"data-v-25adc6c0\",\"scoped\":true,\"hasInlineConfig\":false}!./~/sass-loader/lib/loader.js!./~/vue-loader/lib/selector.js?type=styles&index=0!./src/Button.vue\n// module id = 4\n// module chunks = 0","/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join(\"\");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === \"string\")\r\n\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === \"number\")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader/lib/css-base.js\n// module id = 5\n// module chunks = 0","// this module is a runtime utility for cleaner component module output and will\n// be included in the final webpack user bundle\n\nmodule.exports = function normalizeComponent (\n rawScriptExports,\n compiledTemplate,\n scopeId,\n cssModules\n) {\n var esModule\n var scriptExports = rawScriptExports = rawScriptExports || {}\n\n // ES6 modules interop\n var type = typeof rawScriptExports.default\n if (type === 'object' || type === 'function') {\n esModule = rawScriptExports\n scriptExports = rawScriptExports.default\n }\n\n // Vue.extend constructor export interop\n var options = typeof scriptExports === 'function'\n ? scriptExports.options\n : scriptExports\n\n // render functions\n if (compiledTemplate) {\n options.render = compiledTemplate.render\n options.staticRenderFns = compiledTemplate.staticRenderFns\n }\n\n // scopedId\n if (scopeId) {\n options._scopeId = scopeId\n }\n\n // inject cssModules\n if (cssModules) {\n var computed = Object.create(options.computed || null)\n Object.keys(cssModules).forEach(function (key) {\n var module = cssModules[key]\n computed[key] = function () { return module }\n })\n options.computed = computed\n }\n\n return {\n esModule: esModule,\n exports: scriptExports,\n options: options\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/component-normalizer.js\n// module id = 6\n// module chunks = 0","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('label', {\n class: _vm.className,\n attrs: {\n \"role\": \"checkbox\",\n \"aria-checked\": _vm.ariaChecked\n }\n }, [_c('input', {\n staticClass: \"v-switch-input\",\n attrs: {\n \"type\": \"checkbox\",\n \"name\": _vm.name\n },\n on: {\n \"change\": function($event) {\n $event.stopPropagation();\n return _vm.toggle($event)\n }\n }\n }), _vm._v(\" \"), _c('div', {\n staticClass: \"v-switch-core\",\n style: (_vm.coreStyle)\n }, [_c('div', {\n staticClass: \"v-switch-button\",\n style: (_vm.buttonStyle)\n })]), _vm._v(\" \"), (_vm.labels) ? [(_vm.toggled) ? _c('span', {\n staticClass: \"v-switch-label v-left\",\n style: (_vm.labelStyle),\n domProps: {\n \"innerHTML\": _vm._s(_vm.labelChecked)\n }\n }) : _c('span', {\n staticClass: \"v-switch-label v-right\",\n style: (_vm.labelStyle),\n domProps: {\n \"innerHTML\": _vm._s(_vm.labelUnchecked)\n }\n })] : _vm._e()], 2)\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-25adc6c0\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/Button.vue\n// module id = 7\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a \").prop(\"disabled\",!0).appendTo(\"head\"),a.$breakpoints=h(\"\").prop(\"disabled\",!0).appendTo(\"head\"),a.isInitializing=!0,S.setUpColspan(t,o),S.setupSelector(t,o),o.columnSelector_mediaquery&&S.setupBreakpoints(t,o),a.isInitializing=!1,a.$container.length?S.updateCols(t,o):n&&console.warn(\"ColumnSelector >> container not found\"),t.$table.off(\"refreshColumnSelector\"+c).on(\"refreshColumnSelector\"+c,function(e,t,o){S.refreshColumns(this.config,t,o)}),n&&console.log(\"ColumnSelector >> Widget initialized\")):n&&console.error(\"ColumnSelector >> ERROR: Column Selector aborting, no input found in the layout! ***\")},refreshColumns:function(e,t,o){var l,a,n,c,r=e.selector,s=h.isArray(o||t),i=e.widgetOptions;if(null!=t&&r.$container.length){if(\"selectors\"===t&&(r.$container.empty(),S.setupSelector(e,i),S.setupBreakpoints(e,i),void 0===o&&null!==o&&(o=r.auto)),s)for(a=o||t,h.each(a,function(e,t){a[e]=parseInt(t,10)}),l=0;l'),o=n.selector,l=n.widgetOptions,c.find(\".tablesorter-column-selector\").html(o.$container.html()).find(\"input\").each(function(){var e=h(this).attr(\"data-column\"),t=\"auto\"===e?o.auto:o.states[e];h(this).toggleClass(l.columnSelector_cssChecked,t).prop(\"checked\",t)}),o.$popup=c.on(\"change\",\"input\",function(){if(!o.isInitializing){if(!S.checkChange(n,this.checked))return this.checked=!this.checked,!1;a=h(this).toggleClass(l.columnSelector_cssChecked,this.checked).attr(\"data-column\"),o.$container.find('input[data-column=\"'+a+'\"]').prop(\"checked\",this.checked).trigger(\"change\")}}))}};f.window_resize=function(){f.timer_resize&&clearTimeout(f.timer_resize),f.timer_resize=setTimeout(function(){h(window).trigger(\"resizeEnd\")},250)},f.addWidget({id:\"columnSelector\",priority:10,options:{columnSelector_container:null,columnSelector_columns:{},columnSelector_saveColumns:!0,columnSelector_layout:'',columnSelector_layoutCustomizer:null,columnSelector_name:\"data-selector-name\",columnSelector_mediaquery:!0,columnSelector_mediaqueryName:\"Auto: \",columnSelector_mediaqueryState:!0,columnSelector_mediaqueryHidden:!1,columnSelector_maxVisible:null,columnSelector_minVisible:null,columnSelector_breakpoints:[\"20em\",\"30em\",\"40em\",\"50em\",\"60em\",\"70em\"],columnSelector_maxPriorities:6,columnSelector_priority:\"data-priority\",columnSelector_cssChecked:\"checked\",columnSelector_classHasSpan:\"hasSpan\",columnSelector_updated:\"columnUpdate\"},init:function(e,t,o,l){S.init(e,o,l)},remove:function(e,t,o,l){var a=t.selector;!l&&a&&(a&&a.$container.empty(),a.$popup&&a.$popup.empty(),a.$style.remove(),a.$breakpoints.remove(),h(t.namespace+\"columnselector\"+o.columnSelector_classHasSpan).removeClass(o.filter_filteredRow||\"filtered\"),t.$table.find(\"[data-col-span]\").each(function(e,t){var o=h(t);o.attr(\"colspan\",o.attr(\"data-col-span\"))}),t.$table.off(\"updateAll\"+c+\" update\"+c))}})}(jQuery);return jQuery;}));\n","(function(factory){if (typeof define === 'function' && define.amd){define(['jquery'], factory);} else if (typeof module === 'object' && typeof module.exports === 'object'){module.exports = factory(require('jquery'));} else {factory(jQuery);}}(function(jQuery){\n\n/*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) */\n!function(T,w){\"use strict\";var S=T.tablesorter||{};function x(e,s){var t=isNaN(s.stickyHeaders_offset)?T(s.stickyHeaders_offset):[];return t.length?t.height()||0:parseInt(s.stickyHeaders_offset,10)||0}T.extend(S.css,{sticky:\"tablesorter-stickyHeader\",stickyVis:\"tablesorter-sticky-visible\",stickyHide:\"tablesorter-sticky-hidden\",stickyWrap:\"tablesorter-sticky-wrapper\"}),S.addHeaderResizeEvent=function(e,s,t){if((e=T(e)[0]).config){var i=T.extend({},{timer:250},t),c=e.config,l=c.widgetOptions,r=function(e){var s,t,i,r,a,d,n=c.$headers.length;for(l.resize_flag=!0,t=[],s=0;s'),v=o.parent().addClass(S.css.stickyHide).css({position:g.length?\"absolute\":\"fixed\",padding:parseInt(o.parent().parent().css(\"padding-left\"),10),top:l+_,left:0,visibility:\"hidden\",zIndex:y.stickyHeaders_zIndex||2}),p=o.children(\"thead:first\"),m=\"\",f=function(e,s){var t,i,r,a,d,n=e.filter(\":visible\"),c=n.length;for(t=0;tt.top&&c thead:gt(0), tr.sticky-false\").hide(),o.find(\"> tbody, > tfoot\").remove(),o.find(\"caption\").toggle(y.stickyHeaders_includeCaption),a=p.children().children(),o.css({height:0,width:0,margin:0}),a.find(\".\"+S.css.resizer).remove(),k.addClass(\"hasStickyHeaders\").bind(\"pagerComplete\"+d,function(){C()}),S.bindEvents(e,p.children().children(\".\"+S.css.header)),y.stickyHeaders_appendTo?T(y.stickyHeaders_appendTo).append(v):k.after(v),t.onRenderHeader)for(i=(r=p.children(\"tr\").children()).length,s=0;s> Saving last sort: \"+t.sortList+v.benchmark(a))):(e.addClass(\"hasSaveSort\"),n=\"\",v.storage&&(n=g(t),l&&console.log('saveSort >> Last sort loaded: \"'+n+'\"'+v.benchmark(a)),e.bind(\"saveSortReset\",function(t){t.stopPropagation(),v.storage(s,\"tablesorter-savesort\",\"\")})),r&&n&&0=]/g,query:\"(q|query)\",wild01:/\\?/g,wild0More:/\\*/g,quote:/\\\"/g,isNeg1:/(>=?\\s*-\\d)/,isNeg2:/(<=?\\s*\\d)/},types:{or:function(e,t,r){if(!D.orTest.test(t.iFilter)&&!D.orSplit.test(t.filter)||D.regex.test(t.filter))return null;var i,l,a,n=M.extend({},t),s=t.filter.split(D.orSplit),o=t.iFilter.split(D.orSplit),c=s.length;for(i=0;i]=?/,gtTest:/>/,gteTest:/>=/,ltTest:/'+(l.data(\"placeholder\")||l.attr(\"data-placeholder\")||f.filter_placeholder.select||\"\")+\"\":\"\",0<=(i=n=t).indexOf(f.filter_selectSourceSeparator)&&(i=(n=t.split(f.filter_selectSourceSeparator))[1],n=n[0]),e+=\"\");c.$table.find(\"thead\").find(\"select.\"+_.filter+'[data-column=\"'+a+'\"]').append(e),(s=\"function\"==typeof(i=f.filter_selectSource)||z.getColumnData(r,i,a))&&I.buildSelect(c.table,a,\"\",!0,l.hasClass(f.filter_onlyAvail))}I.buildDefault(r,!0),I.bindSearch(r,c.$table.find(\".\"+_.filter),!0),f.filter_external&&I.bindSearch(r,f.filter_external),f.filter_hideFilters&&I.hideFilters(c),c.showProcessing&&(i=\"filterStart filterEnd \".split(\" \").join(c.namespace+\"filter-sp \"),c.$table.unbind(i.replace(z.regex.spaces,\" \")).bind(i,function(e,t){l=t?c.$table.find(\".\"+_.header).filter(\"[data-column]\").filter(function(){return\"\"!==t[M(this).data(\"column\")]}):\"\",z.isProcessing(r,\"filterStart\"===e.type,t?l:\"\")})),c.filteredRows=c.totalRows,i=\"tablesorter-initialized pagerBeforeInitialized \".split(\" \").join(c.namespace+\"filter \"),c.$table.unbind(i.replace(z.regex.spaces,\" \")).bind(i,function(){I.completeInit(this)}),c.pager&&c.pager.initialized&&!f.filter_initialized?(c.$table.triggerHandler(\"filterFomatterUpdate\"),setTimeout(function(){I.filterInitComplete(c)},100)):f.filter_initialized||I.completeInit(r)},completeInit:function(e){var t=e.config,r=t.widgetOptions,i=I.setDefaults(e,t,r)||[];i.length&&(t.delayInit&&\"\"===i.join(\"\")||z.setFilters(e,i,!0)),t.$table.triggerHandler(\"filterFomatterUpdate\"),setTimeout(function(){r.filter_initialized||I.filterInitComplete(t)},100)},formatterUpdated:function(e,t){var r=e&&e.closest(\"table\"),i=r.length&&r[0].config,l=i&&i.widgetOptions;l&&!l.filter_initialized&&(l.filter_formatterInit[t]=1)},filterInitComplete:function(e){var t,r,i=e.widgetOptions,l=0,a=function(){i.filter_initialized=!0,e.lastSearch=e.$table.data(\"lastSearch\"),e.$table.triggerHandler(\"filterInit\",e),I.findRows(e.table,e.lastSearch||[]),z.debug(e,\"filter\")&&console.log(\"Filter >> Widget initialized\")};if(M.isEmptyObject(i.filter_formatter))a();else{for(r=i.filter_formatterInit.length,t=0;t';for(a=0;a\");for(t.$filters=M(g+=\"\").appendTo(t.$table.children(\"thead\").eq(0)).children(\"td\"),a=0;a\").appendTo(i):((f=z.getColumnData(e,r.filter_formatter,a))?(r.filter_formatterCount++,(g=f(i,a))&&0===g.length&&(g=i.children(\"input\")),g&&(0===g.parent().length||g.parent().length&&g.parent()[0]!==i[0])&&i.append(g)):g=M('').appendTo(i),g&&(d=n.data(\"placeholder\")||n.attr(\"data-placeholder\")||r.filter_placeholder.search||\"\",g.attr(\"placeholder\",d))),g&&(c=(M.isArray(r.filter_cssFilter)?void 0!==r.filter_cssFilter[a]&&r.filter_cssFilter[a]||\"\":r.filter_cssFilter)||\"\",g.addClass(_.filter+\" \"+c),(d=(c=r.filter_filterLabel).match(/{{([^}]+?)}}/g))||(d=[\"{{label}}\"]),M.each(d,function(e,t){var r=new RegExp(t,\"g\"),i=n.attr(\"data-\"+t.replace(/{{|}}/g,\"\")),l=void 0===i?n.text():i;c=c.replace(r,M.trim(l))}),g.attr({\"data-column\":i.attr(\"data-column\"),\"aria-label\":c}),o&&(g.attr(\"placeholder\",\"\").addClass(_.filterDisabled)[0].disabled=!0)))},bindSearch:function(l,e,t){if(l=M(l)[0],(e=M(e)).length){var r,a=l.config,n=a.widgetOptions,i=a.namespace+\"filter\",s=n.filter_$externalFilters;!0!==t&&(r=n.filter_anyColumnSelector+\",\"+n.filter_multipleColumnSelector,n.filter_$anyMatch=e.filter(r),s&&s.length?n.filter_$externalFilters=n.filter_$externalFilters.add(e):n.filter_$externalFilters=e,z.setFilters(l,a.$table.data(\"lastSearch\")||[],!1===t)),r=\"keypress keyup keydown search change input \".split(\" \").join(i+\" \"),e.attr(\"data-lastSearchTime\",(new Date).getTime()).unbind(r.replace(z.regex.spaces,\" \")).bind(\"keydown\"+i,function(e){if(e.which===o.escape&&!l.config.widgetOptions.filter_resetOnEsc)return!1}).bind(\"keyup\"+i,function(e){n=l.config.widgetOptions;var t=parseInt(M(this).attr(\"data-column\"),10),r=\"boolean\"==typeof n.filter_liveSearch?n.filter_liveSearch:z.getColumnData(l,n.filter_liveSearch,t);if(void 0===r&&(r=n.filter_liveSearch.fallback||!1),M(this).attr(\"data-lastSearchTime\",(new Date).getTime()),e.which===o.escape)this.value=n.filter_resetOnEsc?\"\":a.lastSearch[t];else{if(\"\"!==this.value&&(\"number\"==typeof r&&this.value.length=o.left&&e.which<=o.down)))return;if(!1===r&&\"\"!==this.value&&e.which!==o.enter)return}I.searching(l,!0,!0,t)}).bind(\"search change keypress input blur \".split(\" \").join(i+\" \"),function(e){var t=parseInt(M(this).attr(\"data-column\"),10),r=e.type,i=\"boolean\"==typeof n.filter_liveSearch?n.filter_liveSearch:z.getColumnData(l,n.filter_liveSearch,t);!l.config.widgetOptions.filter_initialized||e.which!==o.enter&&\"search\"!==r&&\"blur\"!==r&&(\"change\"!==r&&\"input\"!==r||!0!==i&&(!0===i||\"INPUT\"===e.target.nodeName)||this.value===a.lastSearch[t])||(e.preventDefault(),M(this).attr(\"data-lastSearchTime\",(new Date).getTime()),I.searching(l,\"keypress\"!==r,!0,t))})}},searching:function(e,t,r,i){var l,a=e.config.widgetOptions;void 0===i?l=!1:void 0===(l=\"boolean\"==typeof a.filter_liveSearch?a.filter_liveSearch:z.getColumnData(e,a.filter_liveSearch,i))&&(l=a.filter_liveSearch.fallback||!1),clearTimeout(a.filter_searchTimer),void 0===t||!0===t?a.filter_searchTimer=setTimeout(function(){I.checkFilters(e,t,r)},l?a.filter_searchDelay:10):I.checkFilters(e,t,r)},equalFilters:function(e,t,r){var i,l=[],a=[],n=e.columns+1;for(t=M.isArray(t)?t:[],r=M.isArray(r)?r:[],i=0;i=e.columns&&(s=e.columns-1);n<=s;n++)u[u.length]=n;t=t.replace(l[f],\"\")}if(!r&&/,/.test(t))for(d=(o=t.split(/\\s*,\\s*/)).length,c=0;c> Starting filter widget search\",r),m=new Date),R.filteredRows=0,t=S||[],c=R.totalRows=0;c> Searching through \"+(w&&F> Completed search\"+z.benchmark(m)),T.filter_initialized&&(R.$table.triggerHandler(\"filterBeforeEnd\",R),R.$table.triggerHandler(\"filterEnd\",R)),setTimeout(function(){z.applyWidget(R.table)},0)}},getOptionSource:function(e,t,r){var i=(e=M(e)[0]).config,l=!1,a=i.widgetOptions.filter_selectSource,n=i.$table.data(\"lastSearch\")||[],s=\"function\"==typeof a||z.getColumnData(e,a,t);if(r&&\"\"!==n[t]&&(r=!1),!0===s)l=a(e,t,r);else{if(s instanceof M||\"string\"===M.type(s)&&0<=s.indexOf(\"\"))return s;if(M.isArray(s))l=s;else if(\"object\"===M.type(a)&&s&&null===(l=s(e,t,r)))return null}return!1===l&&(l=I.getOptions(e,t,r)),I.processOptions(e,t,l)},processOptions:function(l,a,r){if(!M.isArray(r))return!1;var n,e,t,i,s,o,c=(l=M(l)[0]).config,f=null!=a&&0<=a&&a'+(p.data(\"placeholder\")||p.attr(\"data-placeholder\")||h.filter_placeholder.select||\"\")+\"\",m=u.$table.find(\"thead\").find(\"select.\"+_.filter+'[data-column=\"'+t+'\"]').val();if(void 0!==r&&\"\"!==r||null!==(r=I.getOptionSource(e,t,l))){if(M.isArray(r)){for(a=0;a\"+d.text.replace(D.quote,\""\")+\"\"}else\"\"+d!=\"[object Object]\"&&(0<=(n=s=d=(\"\"+d).replace(D.quote,\""\")).indexOf(h.filter_selectSourceSeparator)&&(n=(o=s.split(h.filter_selectSourceSeparator))[0],s=o[1]),g+=\"\"!==d?\"\":\"\");r=[]}c=(u.$filters?u.$filters:u.$table.children(\"thead\")).find(\".\"+_.filter),h.filter_$externalFilters&&(c=c&&c.length?c.add(h.filter_$externalFilters):h.filter_$externalFilters),(f=c.filter('select[data-column=\"'+t+'\"]')).length&&(f[i?\"html\":\"append\"](g),M.isArray(r)||f.append(r).val(m),f.val(m))}}},buildDefault:function(e,t){var r,i,l,a=e.config,n=a.widgetOptions,s=a.columns;for(r=0;r= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// setimmediate attaches itself to the global object\nrequire(\"setimmediate\");\n// On some exotic environments, it's not clear which object `setimmediate` was\n// able to install onto. Search each possibility in the same order as the\n// `setimmediate` library.\nexports.setImmediate = (typeof self !== \"undefined\" && self.setImmediate) ||\n (typeof global !== \"undefined\" && global.setImmediate) ||\n (this && this.setImmediate);\nexports.clearImmediate = (typeof self !== \"undefined\" && self.clearImmediate) ||\n (typeof global !== \"undefined\" && global.clearImmediate) ||\n (this && this.clearImmediate);\n","(function (global, undefined) {\n \"use strict\";\n\n if (global.setImmediate) {\n return;\n }\n\n var nextHandle = 1; // Spec says greater than zero\n var tasksByHandle = {};\n var currentlyRunningATask = false;\n var doc = global.document;\n var registerImmediate;\n\n function setImmediate(callback) {\n // Callback can either be a function or a string\n if (typeof callback !== \"function\") {\n callback = new Function(\"\" + callback);\n }\n // Copy function arguments\n var args = new Array(arguments.length - 1);\n for (var i = 0; i < args.length; i++) {\n args[i] = arguments[i + 1];\n }\n // Store and register the task\n var task = { callback: callback, args: args };\n tasksByHandle[nextHandle] = task;\n registerImmediate(nextHandle);\n return nextHandle++;\n }\n\n function clearImmediate(handle) {\n delete tasksByHandle[handle];\n }\n\n function run(task) {\n var callback = task.callback;\n var args = task.args;\n switch (args.length) {\n case 0:\n callback();\n break;\n case 1:\n callback(args[0]);\n break;\n case 2:\n callback(args[0], args[1]);\n break;\n case 3:\n callback(args[0], args[1], args[2]);\n break;\n default:\n callback.apply(undefined, args);\n break;\n }\n }\n\n function runIfPresent(handle) {\n // From the spec: \"Wait until any invocations of this algorithm started before this one have completed.\"\n // So if we're currently running a task, we'll need to delay this invocation.\n if (currentlyRunningATask) {\n // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a\n // \"too much recursion\" error.\n setTimeout(runIfPresent, 0, handle);\n } else {\n var task = tasksByHandle[handle];\n if (task) {\n currentlyRunningATask = true;\n try {\n run(task);\n } finally {\n clearImmediate(handle);\n currentlyRunningATask = false;\n }\n }\n }\n }\n\n function installNextTickImplementation() {\n registerImmediate = function(handle) {\n process.nextTick(function () { runIfPresent(handle); });\n };\n }\n\n function canUsePostMessage() {\n // The test against `importScripts` prevents this implementation from being installed inside a web worker,\n // where `global.postMessage` means something completely different and can't be used for this purpose.\n if (global.postMessage && !global.importScripts) {\n var postMessageIsAsynchronous = true;\n var oldOnMessage = global.onmessage;\n global.onmessage = function() {\n postMessageIsAsynchronous = false;\n };\n global.postMessage(\"\", \"*\");\n global.onmessage = oldOnMessage;\n return postMessageIsAsynchronous;\n }\n }\n\n function installPostMessageImplementation() {\n // Installs an event handler on `global` for the `message` event: see\n // * https://developer.mozilla.org/en/DOM/window.postMessage\n // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages\n\n var messagePrefix = \"setImmediate$\" + Math.random() + \"$\";\n var onGlobalMessage = function(event) {\n if (event.source === global &&\n typeof event.data === \"string\" &&\n event.data.indexOf(messagePrefix) === 0) {\n runIfPresent(+event.data.slice(messagePrefix.length));\n }\n };\n\n if (global.addEventListener) {\n global.addEventListener(\"message\", onGlobalMessage, false);\n } else {\n global.attachEvent(\"onmessage\", onGlobalMessage);\n }\n\n registerImmediate = function(handle) {\n global.postMessage(messagePrefix + handle, \"*\");\n };\n }\n\n function installMessageChannelImplementation() {\n var channel = new MessageChannel();\n channel.port1.onmessage = function(event) {\n var handle = event.data;\n runIfPresent(handle);\n };\n\n registerImmediate = function(handle) {\n channel.port2.postMessage(handle);\n };\n }\n\n function installReadyStateChangeImplementation() {\n var html = doc.documentElement;\n registerImmediate = function(handle) {\n // Create a \n\n\n\n\n\n// WEBPACK FOOTER //\n// Button.vue?4bb6d3a8","import ToggleButton from './Button.vue'\n\nlet installed = false\n\nexport default {\n install(Vue) {\n if (installed) {\n return\n }\n \n Vue.component('ToggleButton', ToggleButton)\n installed = true\n }\n}\n\nexport {\n ToggleButton\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js","exports = module.exports = require(\"../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".vue-js-switch[data-v-25adc6c0]{display:inline-block;position:relative;vertical-align:middle;user-select:none;font-size:10px;cursor:pointer}.vue-js-switch .v-switch-input[data-v-25adc6c0]{opacity:0;position:absolute;width:1px;height:1px}.vue-js-switch .v-switch-label[data-v-25adc6c0]{position:absolute;top:0;font-weight:600;color:#fff;z-index:1}.vue-js-switch .v-switch-label.v-left[data-v-25adc6c0]{left:10px}.vue-js-switch .v-switch-label.v-right[data-v-25adc6c0]{right:10px}.vue-js-switch .v-switch-core[data-v-25adc6c0]{display:block;position:relative;box-sizing:border-box;outline:0;margin:0;transition:border-color .3s,background-color .3s;user-select:none}.vue-js-switch .v-switch-core .v-switch-button[data-v-25adc6c0]{display:block;position:absolute;overflow:hidden;top:0;left:0;border-radius:100%;background-color:#fff;z-index:2}.vue-js-switch.disabled[data-v-25adc6c0]{pointer-events:none;opacity:.6}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader!./~/vue-loader/lib/style-compiler?{\"id\":\"data-v-25adc6c0\",\"scoped\":true,\"hasInlineConfig\":false}!./~/sass-loader/lib/loader.js!./~/vue-loader/lib/selector.js?type=styles&index=0!./src/Button.vue\n// module id = 3\n// module chunks = 0","/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join(\"\");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === \"string\")\r\n\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === \"number\")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader/lib/css-base.js\n// module id = 4\n// module chunks = 0","// this module is a runtime utility for cleaner component module output and will\n// be included in the final webpack user bundle\n\nmodule.exports = function normalizeComponent (\n rawScriptExports,\n compiledTemplate,\n scopeId,\n cssModules\n) {\n var esModule\n var scriptExports = rawScriptExports = rawScriptExports || {}\n\n // ES6 modules interop\n var type = typeof rawScriptExports.default\n if (type === 'object' || type === 'function') {\n esModule = rawScriptExports\n scriptExports = rawScriptExports.default\n }\n\n // Vue.extend constructor export interop\n var options = typeof scriptExports === 'function'\n ? scriptExports.options\n : scriptExports\n\n // render functions\n if (compiledTemplate) {\n options.render = compiledTemplate.render\n options.staticRenderFns = compiledTemplate.staticRenderFns\n }\n\n // scopedId\n if (scopeId) {\n options._scopeId = scopeId\n }\n\n // inject cssModules\n if (cssModules) {\n var computed = Object.create(options.computed || null)\n Object.keys(cssModules).forEach(function (key) {\n var module = cssModules[key]\n computed[key] = function () { return module }\n })\n options.computed = computed\n }\n\n return {\n esModule: esModule,\n exports: scriptExports,\n options: options\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/component-normalizer.js\n// module id = 5\n// module chunks = 0","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('label', {\n class: _vm.className\n }, [_c('input', {\n staticClass: \"v-switch-input\",\n attrs: {\n \"type\": \"checkbox\",\n \"name\": _vm.name,\n \"disabled\": _vm.disabled\n },\n domProps: {\n \"checked\": _vm.value\n },\n on: {\n \"change\": function($event) {\n $event.stopPropagation();\n return _vm.toggle($event)\n }\n }\n }), _vm._v(\" \"), _c('div', {\n staticClass: \"v-switch-core\",\n style: (_vm.coreStyle)\n }, [_c('div', {\n staticClass: \"v-switch-button\",\n style: (_vm.buttonStyle)\n })]), _vm._v(\" \"), (_vm.labels) ? [(_vm.toggled) ? _c('span', {\n staticClass: \"v-switch-label v-left\",\n style: (_vm.labelStyle)\n }, [_vm._t(\"checked\", [\n [_vm._v(_vm._s(_vm.labelChecked))]\n ])], 2) : _c('span', {\n staticClass: \"v-switch-label v-right\",\n style: (_vm.labelStyle)\n }, [_vm._t(\"unchecked\", [\n [_vm._v(_vm._s(_vm.labelUnchecked))]\n ])], 2)] : _vm._e()], 2)\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-25adc6c0\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/Button.vue\n// module id = 6\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a \").prop(\"disabled\",!0).appendTo(\"head\"),a.$breakpoints=h(\"\").prop(\"disabled\",!0).appendTo(\"head\"),a.isInitializing=!0,S.setUpColspan(t,o),S.setupSelector(t,o),o.columnSelector_mediaquery&&S.setupBreakpoints(t,o),a.isInitializing=!1,a.$container.length?S.updateCols(t,o):n&&console.warn(\"ColumnSelector >> container not found\"),t.$table.off(\"refreshColumnSelector\"+c).on(\"refreshColumnSelector\"+c,function(e,t,o){S.refreshColumns(this.config,t,o)}),n&&console.log(\"ColumnSelector >> Widget initialized\")):n&&console.error(\"ColumnSelector >> ERROR: Column Selector aborting, no input found in the layout! ***\")},refreshColumns:function(e,t,o){var l,a,n,c,r=e.selector,s=h.isArray(o||t),i=e.widgetOptions;if(null!=t&&r.$container.length){if(\"selectors\"===t&&(r.$container.empty(),S.setupSelector(e,i),S.setupBreakpoints(e,i),void 0===o&&null!==o&&(o=r.auto)),s)for(a=o||t,h.each(a,function(e,t){a[e]=parseInt(t,10)}),l=0;l'),o=n.selector,l=n.widgetOptions,c.find(\".tablesorter-column-selector\").html(o.$container.html()).find(\"input\").each(function(){var e=h(this).attr(\"data-column\"),t=\"auto\"===e?o.auto:o.states[e];h(this).toggleClass(l.columnSelector_cssChecked,t).prop(\"checked\",t)}),o.$popup=c.on(\"change\",\"input\",function(){if(!o.isInitializing){if(!S.checkChange(n,this.checked))return this.checked=!this.checked,!1;a=h(this).toggleClass(l.columnSelector_cssChecked,this.checked).attr(\"data-column\"),o.$container.find('input[data-column=\"'+a+'\"]').prop(\"checked\",this.checked).trigger(\"change\")}}))}};f.window_resize=function(){f.timer_resize&&clearTimeout(f.timer_resize),f.timer_resize=setTimeout(function(){h(window).trigger(\"resizeEnd\")},250)},f.addWidget({id:\"columnSelector\",priority:10,options:{columnSelector_container:null,columnSelector_columns:{},columnSelector_saveColumns:!0,columnSelector_layout:'',columnSelector_layoutCustomizer:null,columnSelector_name:\"data-selector-name\",columnSelector_mediaquery:!0,columnSelector_mediaqueryName:\"Auto: \",columnSelector_mediaqueryState:!0,columnSelector_mediaqueryHidden:!1,columnSelector_maxVisible:null,columnSelector_minVisible:null,columnSelector_breakpoints:[\"20em\",\"30em\",\"40em\",\"50em\",\"60em\",\"70em\"],columnSelector_maxPriorities:6,columnSelector_priority:\"data-priority\",columnSelector_cssChecked:\"checked\",columnSelector_classHasSpan:\"hasSpan\",columnSelector_updated:\"columnUpdate\"},init:function(e,t,o,l){S.init(e,o,l)},remove:function(e,t,o,l){var a=t.selector;!l&&a&&(a&&a.$container.empty(),a.$popup&&a.$popup.empty(),a.$style.remove(),a.$breakpoints.remove(),h(t.namespace+\"columnselector\"+o.columnSelector_classHasSpan).removeClass(o.filter_filteredRow||\"filtered\"),t.$table.find(\"[data-col-span]\").each(function(e,t){var o=h(t);o.attr(\"colspan\",o.attr(\"data-col-span\"))}),t.$table.off(\"updateAll\"+c+\" update\"+c))}})}(jQuery);return jQuery;}));\n","(function(factory){if (typeof define === 'function' && define.amd){define(['jquery'], factory);} else if (typeof module === 'object' && typeof module.exports === 'object'){module.exports = factory(require('jquery'));} else {factory(jQuery);}}(function(jQuery){\r\n\r\n/*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) */\r\n!function(T,w){\"use strict\";var S=T.tablesorter||{};function x(e,s){var t=isNaN(s.stickyHeaders_offset)?T(s.stickyHeaders_offset):[];return t.length?t.height()||0:parseInt(s.stickyHeaders_offset,10)||0}T.extend(S.css,{sticky:\"tablesorter-stickyHeader\",stickyVis:\"tablesorter-sticky-visible\",stickyHide:\"tablesorter-sticky-hidden\",stickyWrap:\"tablesorter-sticky-wrapper\"}),S.addHeaderResizeEvent=function(e,s,t){if((e=T(e)[0]).config){var i=T.extend({},{timer:250},t),c=e.config,l=c.widgetOptions,r=function(e){var s,t,i,r,a,d,n=c.$headers.length;for(l.resize_flag=!0,t=[],s=0;s'),v=o.parent().addClass(S.css.stickyHide).css({position:g.length?\"absolute\":\"fixed\",padding:parseInt(o.parent().parent().css(\"padding-left\"),10),top:l+_,left:0,visibility:\"hidden\",zIndex:y.stickyHeaders_zIndex||2}),p=o.children(\"thead:first\"),m=\"\",f=function(e,s){var t,i,r,a,d,n=e.filter(\":visible\"),c=n.length;for(t=0;tt.top&&c thead:gt(0), tr.sticky-false\").hide(),o.find(\"> tbody, > tfoot\").remove(),o.find(\"caption\").toggle(y.stickyHeaders_includeCaption),a=p.children().children(),o.css({height:0,width:0,margin:0}),a.find(\".\"+S.css.resizer).remove(),k.addClass(\"hasStickyHeaders\").bind(\"pagerComplete\"+d,function(){C()}),S.bindEvents(e,p.children().children(\".\"+S.css.header)),y.stickyHeaders_appendTo?T(y.stickyHeaders_appendTo).append(v):k.after(v),t.onRenderHeader)for(i=(r=p.children(\"tr\").children()).length,s=0;s> Saving last sort: \"+t.sortList+v.benchmark(a))):(e.addClass(\"hasSaveSort\"),n=\"\",v.storage&&(n=g(t),l&&console.log('saveSort >> Last sort loaded: \"'+n+'\"'+v.benchmark(a)),e.bind(\"saveSortReset\",function(t){t.stopPropagation(),v.storage(s,\"tablesorter-savesort\",\"\")})),r&&n&&0=]/g,query:\"(q|query)\",wild01:/\\?/g,wild0More:/\\*/g,quote:/\\\"/g,isNeg1:/(>=?\\s*-\\d)/,isNeg2:/(<=?\\s*\\d)/},types:{or:function(e,t,r){if(!D.orTest.test(t.iFilter)&&!D.orSplit.test(t.filter)||D.regex.test(t.filter))return null;var i,l,a,n=M.extend({},t),s=t.filter.split(D.orSplit),o=t.iFilter.split(D.orSplit),c=s.length;for(i=0;i]=?/,gtTest:/>/,gteTest:/>=/,ltTest:/'+(l.data(\"placeholder\")||l.attr(\"data-placeholder\")||f.filter_placeholder.select||\"\")+\"\":\"\",0<=(i=n=t).indexOf(f.filter_selectSourceSeparator)&&(i=(n=t.split(f.filter_selectSourceSeparator))[1],n=n[0]),e+=\"\");c.$table.find(\"thead\").find(\"select.\"+_.filter+'[data-column=\"'+a+'\"]').append(e),(s=\"function\"==typeof(i=f.filter_selectSource)||z.getColumnData(r,i,a))&&I.buildSelect(c.table,a,\"\",!0,l.hasClass(f.filter_onlyAvail))}I.buildDefault(r,!0),I.bindSearch(r,c.$table.find(\".\"+_.filter),!0),f.filter_external&&I.bindSearch(r,f.filter_external),f.filter_hideFilters&&I.hideFilters(c),c.showProcessing&&(i=\"filterStart filterEnd \".split(\" \").join(c.namespace+\"filter-sp \"),c.$table.unbind(i.replace(z.regex.spaces,\" \")).bind(i,function(e,t){l=t?c.$table.find(\".\"+_.header).filter(\"[data-column]\").filter(function(){return\"\"!==t[M(this).data(\"column\")]}):\"\",z.isProcessing(r,\"filterStart\"===e.type,t?l:\"\")})),c.filteredRows=c.totalRows,i=\"tablesorter-initialized pagerBeforeInitialized \".split(\" \").join(c.namespace+\"filter \"),c.$table.unbind(i.replace(z.regex.spaces,\" \")).bind(i,function(){I.completeInit(this)}),c.pager&&c.pager.initialized&&!f.filter_initialized?(c.$table.triggerHandler(\"filterFomatterUpdate\"),setTimeout(function(){I.filterInitComplete(c)},100)):f.filter_initialized||I.completeInit(r)},completeInit:function(e){var t=e.config,r=t.widgetOptions,i=I.setDefaults(e,t,r)||[];i.length&&(t.delayInit&&\"\"===i.join(\"\")||z.setFilters(e,i,!0)),t.$table.triggerHandler(\"filterFomatterUpdate\"),setTimeout(function(){r.filter_initialized||I.filterInitComplete(t)},100)},formatterUpdated:function(e,t){var r=e&&e.closest(\"table\"),i=r.length&&r[0].config,l=i&&i.widgetOptions;l&&!l.filter_initialized&&(l.filter_formatterInit[t]=1)},filterInitComplete:function(e){var t,r,i=e.widgetOptions,l=0,a=function(){i.filter_initialized=!0,e.lastSearch=e.$table.data(\"lastSearch\"),e.$table.triggerHandler(\"filterInit\",e),I.findRows(e.table,e.lastSearch||[]),z.debug(e,\"filter\")&&console.log(\"Filter >> Widget initialized\")};if(M.isEmptyObject(i.filter_formatter))a();else{for(r=i.filter_formatterInit.length,t=0;t';for(a=0;a\");for(t.$filters=M(g+=\"\").appendTo(t.$table.children(\"thead\").eq(0)).children(\"td\"),a=0;a\").appendTo(i):((f=z.getColumnData(e,r.filter_formatter,a))?(r.filter_formatterCount++,(g=f(i,a))&&0===g.length&&(g=i.children(\"input\")),g&&(0===g.parent().length||g.parent().length&&g.parent()[0]!==i[0])&&i.append(g)):g=M('').appendTo(i),g&&(d=n.data(\"placeholder\")||n.attr(\"data-placeholder\")||r.filter_placeholder.search||\"\",g.attr(\"placeholder\",d))),g&&(c=(M.isArray(r.filter_cssFilter)?void 0!==r.filter_cssFilter[a]&&r.filter_cssFilter[a]||\"\":r.filter_cssFilter)||\"\",g.addClass(_.filter+\" \"+c),(d=(c=r.filter_filterLabel).match(/{{([^}]+?)}}/g))||(d=[\"{{label}}\"]),M.each(d,function(e,t){var r=new RegExp(t,\"g\"),i=n.attr(\"data-\"+t.replace(/{{|}}/g,\"\")),l=void 0===i?n.text():i;c=c.replace(r,M.trim(l))}),g.attr({\"data-column\":i.attr(\"data-column\"),\"aria-label\":c}),o&&(g.attr(\"placeholder\",\"\").addClass(_.filterDisabled)[0].disabled=!0)))},bindSearch:function(l,e,t){if(l=M(l)[0],(e=M(e)).length){var r,a=l.config,n=a.widgetOptions,i=a.namespace+\"filter\",s=n.filter_$externalFilters;!0!==t&&(r=n.filter_anyColumnSelector+\",\"+n.filter_multipleColumnSelector,n.filter_$anyMatch=e.filter(r),s&&s.length?n.filter_$externalFilters=n.filter_$externalFilters.add(e):n.filter_$externalFilters=e,z.setFilters(l,a.$table.data(\"lastSearch\")||[],!1===t)),r=\"keypress keyup keydown search change input \".split(\" \").join(i+\" \"),e.attr(\"data-lastSearchTime\",(new Date).getTime()).unbind(r.replace(z.regex.spaces,\" \")).bind(\"keydown\"+i,function(e){if(e.which===o.escape&&!l.config.widgetOptions.filter_resetOnEsc)return!1}).bind(\"keyup\"+i,function(e){n=l.config.widgetOptions;var t=parseInt(M(this).attr(\"data-column\"),10),r=\"boolean\"==typeof n.filter_liveSearch?n.filter_liveSearch:z.getColumnData(l,n.filter_liveSearch,t);if(void 0===r&&(r=n.filter_liveSearch.fallback||!1),M(this).attr(\"data-lastSearchTime\",(new Date).getTime()),e.which===o.escape)this.value=n.filter_resetOnEsc?\"\":a.lastSearch[t];else{if(\"\"!==this.value&&(\"number\"==typeof r&&this.value.length=o.left&&e.which<=o.down)))return;if(!1===r&&\"\"!==this.value&&e.which!==o.enter)return}I.searching(l,!0,!0,t)}).bind(\"search change keypress input blur \".split(\" \").join(i+\" \"),function(e){var t=parseInt(M(this).attr(\"data-column\"),10),r=e.type,i=\"boolean\"==typeof n.filter_liveSearch?n.filter_liveSearch:z.getColumnData(l,n.filter_liveSearch,t);!l.config.widgetOptions.filter_initialized||e.which!==o.enter&&\"search\"!==r&&\"blur\"!==r&&(\"change\"!==r&&\"input\"!==r||!0!==i&&(!0===i||\"INPUT\"===e.target.nodeName)||this.value===a.lastSearch[t])||(e.preventDefault(),M(this).attr(\"data-lastSearchTime\",(new Date).getTime()),I.searching(l,\"keypress\"!==r,!0,t))})}},searching:function(e,t,r,i){var l,a=e.config.widgetOptions;void 0===i?l=!1:void 0===(l=\"boolean\"==typeof a.filter_liveSearch?a.filter_liveSearch:z.getColumnData(e,a.filter_liveSearch,i))&&(l=a.filter_liveSearch.fallback||!1),clearTimeout(a.filter_searchTimer),void 0===t||!0===t?a.filter_searchTimer=setTimeout(function(){I.checkFilters(e,t,r)},l?a.filter_searchDelay:10):I.checkFilters(e,t,r)},equalFilters:function(e,t,r){var i,l=[],a=[],n=e.columns+1;for(t=M.isArray(t)?t:[],r=M.isArray(r)?r:[],i=0;i=e.columns&&(s=e.columns-1);n<=s;n++)u[u.length]=n;t=t.replace(l[f],\"\")}if(!r&&/,/.test(t))for(d=(o=t.split(/\\s*,\\s*/)).length,c=0;c> Starting filter widget search\",r),m=new Date),R.filteredRows=0,t=S||[],c=R.totalRows=0;c> Searching through \"+(w&&F> Completed search\"+z.benchmark(m)),T.filter_initialized&&(R.$table.triggerHandler(\"filterBeforeEnd\",R),R.$table.triggerHandler(\"filterEnd\",R)),setTimeout(function(){z.applyWidget(R.table)},0)}},getOptionSource:function(e,t,r){var i=(e=M(e)[0]).config,l=!1,a=i.widgetOptions.filter_selectSource,n=i.$table.data(\"lastSearch\")||[],s=\"function\"==typeof a||z.getColumnData(e,a,t);if(r&&\"\"!==n[t]&&(r=!1),!0===s)l=a(e,t,r);else{if(s instanceof M||\"string\"===M.type(s)&&0<=s.indexOf(\"\"))return s;if(M.isArray(s))l=s;else if(\"object\"===M.type(a)&&s&&null===(l=s(e,t,r)))return null}return!1===l&&(l=I.getOptions(e,t,r)),I.processOptions(e,t,l)},processOptions:function(l,a,r){if(!M.isArray(r))return!1;var n,e,t,i,s,o,c=(l=M(l)[0]).config,f=null!=a&&0<=a&&a'+(p.data(\"placeholder\")||p.attr(\"data-placeholder\")||h.filter_placeholder.select||\"\")+\"\",m=u.$table.find(\"thead\").find(\"select.\"+_.filter+'[data-column=\"'+t+'\"]').val();if(void 0!==r&&\"\"!==r||null!==(r=I.getOptionSource(e,t,l))){if(M.isArray(r)){for(a=0;a\"+d.text.replace(D.quote,\""\")+\"\"}else\"\"+d!=\"[object Object]\"&&(0<=(n=s=d=(\"\"+d).replace(D.quote,\""\")).indexOf(h.filter_selectSourceSeparator)&&(n=(o=s.split(h.filter_selectSourceSeparator))[0],s=o[1]),g+=\"\"!==d?\"\":\"\");r=[]}c=(u.$filters?u.$filters:u.$table.children(\"thead\")).find(\".\"+_.filter),h.filter_$externalFilters&&(c=c&&c.length?c.add(h.filter_$externalFilters):h.filter_$externalFilters),(f=c.filter('select[data-column=\"'+t+'\"]')).length&&(f[i?\"html\":\"append\"](g),M.isArray(r)||f.append(r).val(m),f.val(m))}}},buildDefault:function(e,t){var r,i,l,a=e.config,n=a.widgetOptions,s=a.columns;for(r=0;r= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// setimmediate attaches itself to the global object\nrequire(\"setimmediate\");\n// On some exotic environments, it's not clear which object `setimmediate` was\n// able to install onto. Search each possibility in the same order as the\n// `setimmediate` library.\nexports.setImmediate = (typeof self !== \"undefined\" && self.setImmediate) ||\n (typeof global !== \"undefined\" && global.setImmediate) ||\n (this && this.setImmediate);\nexports.clearImmediate = (typeof self !== \"undefined\" && self.clearImmediate) ||\n (typeof global !== \"undefined\" && global.clearImmediate) ||\n (this && this.clearImmediate);\n","(function (global, undefined) {\n \"use strict\";\n\n if (global.setImmediate) {\n return;\n }\n\n var nextHandle = 1; // Spec says greater than zero\n var tasksByHandle = {};\n var currentlyRunningATask = false;\n var doc = global.document;\n var registerImmediate;\n\n function setImmediate(callback) {\n // Callback can either be a function or a string\n if (typeof callback !== \"function\") {\n callback = new Function(\"\" + callback);\n }\n // Copy function arguments\n var args = new Array(arguments.length - 1);\n for (var i = 0; i < args.length; i++) {\n args[i] = arguments[i + 1];\n }\n // Store and register the task\n var task = { callback: callback, args: args };\n tasksByHandle[nextHandle] = task;\n registerImmediate(nextHandle);\n return nextHandle++;\n }\n\n function clearImmediate(handle) {\n delete tasksByHandle[handle];\n }\n\n function run(task) {\n var callback = task.callback;\n var args = task.args;\n switch (args.length) {\n case 0:\n callback();\n break;\n case 1:\n callback(args[0]);\n break;\n case 2:\n callback(args[0], args[1]);\n break;\n case 3:\n callback(args[0], args[1], args[2]);\n break;\n default:\n callback.apply(undefined, args);\n break;\n }\n }\n\n function runIfPresent(handle) {\n // From the spec: \"Wait until any invocations of this algorithm started before this one have completed.\"\n // So if we're currently running a task, we'll need to delay this invocation.\n if (currentlyRunningATask) {\n // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a\n // \"too much recursion\" error.\n setTimeout(runIfPresent, 0, handle);\n } else {\n var task = tasksByHandle[handle];\n if (task) {\n currentlyRunningATask = true;\n try {\n run(task);\n } finally {\n clearImmediate(handle);\n currentlyRunningATask = false;\n }\n }\n }\n }\n\n function installNextTickImplementation() {\n registerImmediate = function(handle) {\n process.nextTick(function () { runIfPresent(handle); });\n };\n }\n\n function canUsePostMessage() {\n // The test against `importScripts` prevents this implementation from being installed inside a web worker,\n // where `global.postMessage` means something completely different and can't be used for this purpose.\n if (global.postMessage && !global.importScripts) {\n var postMessageIsAsynchronous = true;\n var oldOnMessage = global.onmessage;\n global.onmessage = function() {\n postMessageIsAsynchronous = false;\n };\n global.postMessage(\"\", \"*\");\n global.onmessage = oldOnMessage;\n return postMessageIsAsynchronous;\n }\n }\n\n function installPostMessageImplementation() {\n // Installs an event handler on `global` for the `message` event: see\n // * https://developer.mozilla.org/en/DOM/window.postMessage\n // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages\n\n var messagePrefix = \"setImmediate$\" + Math.random() + \"$\";\n var onGlobalMessage = function(event) {\n if (event.source === global &&\n typeof event.data === \"string\" &&\n event.data.indexOf(messagePrefix) === 0) {\n runIfPresent(+event.data.slice(messagePrefix.length));\n }\n };\n\n if (global.addEventListener) {\n global.addEventListener(\"message\", onGlobalMessage, false);\n } else {\n global.attachEvent(\"onmessage\", onGlobalMessage);\n }\n\n registerImmediate = function(handle) {\n global.postMessage(messagePrefix + handle, \"*\");\n };\n }\n\n function installMessageChannelImplementation() {\n var channel = new MessageChannel();\n channel.port1.onmessage = function(event) {\n var handle = event.data;\n runIfPresent(handle);\n };\n\n registerImmediate = function(handle) {\n channel.port2.postMessage(handle);\n };\n }\n\n function installReadyStateChangeImplementation() {\n var html = doc.documentElement;\n registerImmediate = function(handle) {\n // Create a diff --git a/themes/dark/templates/config_general.mako b/themes/dark/templates/config_general.mako index 4216de5faf..4465997f56 100644 --- a/themes/dark/templates/config_general.mako +++ b/themes/dark/templates/config_general.mako @@ -381,7 +381,7 @@ window.app = new Vue({ diff --git a/themes/dark/templates/config_notifications.mako b/themes/dark/templates/config_notifications.mako index f6ba873be2..4d64161460 100644 --- a/themes/dark/templates/config_notifications.mako +++ b/themes/dark/templates/config_notifications.mako @@ -153,7 +153,7 @@ window.app = new Vue({ enabled: null, api: [], messageTitle: null, - piority: null, + priority: null, notifyOnSnatch: null, notifyOnDownload: null, notifyOnSubtitleDownload: null @@ -451,7 +451,7 @@ window.app = new Vue({ const response = await apiRoute('home/testTwitter'); const { data } = response; this.twitterTestInfo = data; - } catch { + } catch (e) { this.twitterTestInfo = 'Error while trying to request for a test on the twitter api.' } }, @@ -1659,7 +1659,7 @@ window.app = new Vue({ - + @@ -1668,7 +1668,7 @@ window.app = new Vue({ - + + diff --git a/themes/dark/templates/config_search.mako b/themes/dark/templates/config_search.mako index 318e56986f..a164434a65 100644 --- a/themes/dark/templates/config_search.mako +++ b/themes/dark/templates/config_search.mako @@ -48,7 +48,8 @@ window.app = new Vue({ labelOption: true, labelAnimeOption: true, seedTimeOption: true, - pausedOption: true + pausedOption: true, + testStatus: 'Click below to test' }, transmission: { title: 'Transmission', @@ -58,6 +59,7 @@ window.app = new Vue({ seedLocationOption: true, seedTimeOption: true, pausedOption: true, + testStatus: 'Click below to test' }, deluge: { title: 'Deluge (via WebUI)', @@ -69,7 +71,8 @@ window.app = new Vue({ labelAnimeOption: true, seedLocationOption: true, pausedOption: true, - verifyCertOption: true + verifyCertOption: true, + testStatus: 'Click below to test' }, deluged: { title: 'Deluge (via Daemon)', @@ -81,12 +84,14 @@ window.app = new Vue({ labelAnimeOption: true, seedLocationOption: true, pausedOption: true, - verifyCertOption: true + verifyCertOption: true, + testStatus: 'Click below to test' }, downloadstation: { title: 'Synology DS', description: 'URL to your Synology DS client (e.g. http://localhost:5000)', - pathOption: true + pathOption: true, + testStatus: 'Click below to test' }, rtorrent: { title: 'rTorrent', @@ -94,19 +99,22 @@ window.app = new Vue({ pathOption: true, labelOption: true, labelAnimeOption: true, - verifyCertOption: true + verifyCertOption: true, + testStatus: 'Click below to test' }, qbittorrent: { title: 'qBittorrent', description: 'URL to your qBittorrent client (e.g. http://localhost:8080)', labelOption: true, labelAnimeOption: true, - pausedOption: true + pausedOption: true, + testStatus: 'Click below to test' }, mlnet: { title: 'MLDonkey', description: 'URL to your MLDonkey (e.g. http://localhost:4080)', - verifyCertOption: true + verifyCertOption: true, + testStatus: 'Click below to test' } }, nzb: { @@ -138,7 +146,7 @@ window.app = new Vue({ method: null, path: null, paused: null, - rpcurl: null, + rpcUrl: null, seedLocation: null, seedTime: null, username: null, @@ -457,7 +465,7 @@ window.app = new Vue({ - +

time in minutes between searches (min. {{search.general.minBacklogFrequency}})

diff --git a/themes/dark/templates/displayShow.mako b/themes/dark/templates/displayShow.mako index 1bf57ac7d7..75738eb48e 100644 --- a/themes/dark/templates/displayShow.mako +++ b/themes/dark/templates/displayShow.mako @@ -9,12 +9,14 @@ %> <%block name="scripts"> <%block name="scripts" /> diff --git a/themes/dark/templates/partials/footer.mako b/themes/dark/templates/partials/footer.mako index 555009f14f..697e1356bd 100644 --- a/themes/dark/templates/partials/footer.mako +++ b/themes/dark/templates/partials/footer.mako @@ -6,6 +6,7 @@ import re from medusa import app from medusa.helper.common import pretty_file_size + from medusa.sbdatetime import sbdatetime from medusa.show.show import Show mem_usage = None @@ -50,7 +51,7 @@ % endif Load time: ${"%.4f" % (time() - sbStartTime)}s / Mako: ${"%.4f" % (time() - makoStartTime)}s | Branch: ${app.BRANCH} | - Now: ${datetime.now().strftime(app.DATE_PRESET+" "+app.TIME_PRESET).decode(app.SYS_ENCODING)} + Now: ${sbdatetime.now().sbfdatetime(d_preset=app.DATE_PRESET, t_preset=app.TIME_PRESET)} diff --git a/themes/dark/templates/partials/home/banner.mako b/themes/dark/templates/partials/home/banner.mako index 8f8d9d08ca..aa57699878 100644 --- a/themes/dark/templates/partials/home/banner.mako +++ b/themes/dark/templates/partials/home/banner.mako @@ -114,7 +114,7 @@ else: den = 1 download_stat_tip = "Unaired" - progressbar_percent = nom * 100 / den + progressbar_percent = nom * 100 // den %> % if cur_airs_next: diff --git a/themes/dark/templates/partials/home/poster.mako b/themes/dark/templates/partials/home/poster.mako index a79a95dbed..19bd7d8308 100644 --- a/themes/dark/templates/partials/home/poster.mako +++ b/themes/dark/templates/partials/home/poster.mako @@ -87,7 +87,7 @@ else: den = 1 download_stat_tip = "Unaired" - progressbar_percent = nom * 100 / den + progressbar_percent = nom * 100 // den data_date = '6000000000.0' if cur_airs_next: data_date = calendar.timegm(sbdatetime.sbdatetime.convert_to_setting(network_timezones.parse_date_time(cur_airs_next, cur_show.airs, cur_show.network)).timetuple()) diff --git a/themes/dark/templates/partials/home/simple.mako b/themes/dark/templates/partials/home/simple.mako index b99e248710..a90ba2d533 100644 --- a/themes/dark/templates/partials/home/simple.mako +++ b/themes/dark/templates/partials/home/simple.mako @@ -115,7 +115,7 @@ else: den = 1 download_stat_tip = "Unaired" - progressbar_percent = nom * 100 / den + progressbar_percent = nom * 100 // den %> % if cur_airs_next: diff --git a/themes/dark/templates/partials/home/small.mako b/themes/dark/templates/partials/home/small.mako index aa45fef442..18b73b25a7 100644 --- a/themes/dark/templates/partials/home/small.mako +++ b/themes/dark/templates/partials/home/small.mako @@ -114,7 +114,7 @@ else: den = 1 download_stat_tip = "Unaired" - progressbar_percent = nom * 100 / den + progressbar_percent = nom * 100 // den %> % if cur_airs_next: diff --git a/themes/dark/templates/partials/schedule/banner.mako b/themes/dark/templates/partials/schedule/banner.mako index 8bdbf99890..9fe2bdbef1 100644 --- a/themes/dark/templates/partials/schedule/banner.mako +++ b/themes/dark/templates/partials/schedule/banner.mako @@ -4,7 +4,7 @@ from medusa import app from medusa.indexers.indexer_api import indexerApi from medusa.indexers.utils import indexer_id_to_name - from medusa import sbdatetime + from medusa.sbdatetime import sbdatetime %> <% @@ -59,17 +59,17 @@ <% too_late_header = True %> % elif cur_ep_enddate >= today and cur_ep_airdate < next_week.date(): % if cur_ep_airdate == today.date(): -

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()}[Today]

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()}[Today]

<% today_header = True %> % else: -

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()}

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()}

% endif % endif <% cur_segment = cur_ep_airdate %> % endif % if cur_ep_airdate == today.date() and not today_header:
-

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()} [Today]

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()} [Today]

<% today_header = True %> % endif @@ -128,7 +128,7 @@ Next Episode: ${'S%02iE%02i' % (int(cur_result['season']), int(cur_result['episode']))} - ${cur_result['name']}
- Airs: ${sbdatetime.sbdatetime.sbfdatetime(cur_result['localtime'])}${('', ' on %s' % cur_result['network'])[bool(cur_result['network'])]} + Airs: ${sbdatetime.sbfdatetime(cur_result['localtime'])}${('', ' on %s' % cur_result['network'])[bool(cur_result['network'])]}
Quality: diff --git a/themes/dark/templates/partials/schedule/calendar.mako b/themes/dark/templates/partials/schedule/calendar.mako index 2d2055724f..7c788767ba 100644 --- a/themes/dark/templates/partials/schedule/calendar.mako +++ b/themes/dark/templates/partials/schedule/calendar.mako @@ -5,7 +5,7 @@ from medusa import app from medusa.indexers.utils import indexer_id_to_name - from medusa import sbdatetime + from medusa.sbdatetime import sbdatetime %> <% dates = [today.date() + datetime.timedelta(days = i) for i in range(7)] %> @@ -15,7 +15,7 @@ % for day in dates: <% tbl_day += 1 %> - + <% day_has_show = False %> % for cur_result in results: @@ -28,7 +28,7 @@ % if airday == day: % try: <% day_has_show = True %> - <% airtime = sbdatetime.sbdatetime.fromtimestamp(time.mktime(cur_result['localtime'].timetuple())).sbftime().decode(app.SYS_ENCODING) %> + <% airtime = sbdatetime.fromtimestamp(time.mktime(cur_result['localtime'].timetuple())).sbftime() %> % if app.TRIM_ZERO: <% airtime = re.sub(r'0(\d:\d\d)', r'\1', airtime, 0, re.IGNORECASE | re.MULTILINE) %> % endif diff --git a/themes/dark/templates/partials/schedule/poster.mako b/themes/dark/templates/partials/schedule/poster.mako index ab7e98b9e4..557b119c89 100644 --- a/themes/dark/templates/partials/schedule/poster.mako +++ b/themes/dark/templates/partials/schedule/poster.mako @@ -4,7 +4,7 @@ from medusa import app from medusa.indexers.indexer_api import indexerApi from medusa.indexers.utils import indexer_id_to_name - from medusa import sbdatetime + from medusa.sbdatetime import sbdatetime %> <% @@ -59,17 +59,17 @@ <% too_late_header = True %> % elif cur_ep_enddate >= today and cur_ep_airdate < next_week.date(): % if cur_ep_airdate == today.date(): -

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()}[Today]

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()}[Today]

<% today_header = True %> % else: -

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()}

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()}

% endif % endif <% cur_segment = cur_ep_airdate %> % endif % if cur_ep_airdate == today.date() and not today_header:
-

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()} [Today]

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()} [Today]

<% today_header = True %> % endif @@ -126,7 +126,7 @@ Next Episode:${'S%02iE%02i' % (int(cur_result['season']), int(cur_result['episode']))} - ${cur_result['name']}
- Airs: ${sbdatetime.sbdatetime.sbfdatetime(cur_result['localtime'])}${('', ' on %s' % cur_result['network'])[bool(cur_result['network'])]} + Airs: ${sbdatetime.sbfdatetime(cur_result['localtime'])}${('', ' on %s' % cur_result['network'])[bool(cur_result['network'])]}
Quality: diff --git a/themes/dark/templates/partials/showheader.mako b/themes/dark/templates/partials/showheader.mako deleted file mode 100644 index 43cc528228..0000000000 --- a/themes/dark/templates/partials/showheader.mako +++ /dev/null @@ -1,274 +0,0 @@ -<%! - import json - import operator - - from medusa import app, helpers, subtitles, network_timezones - from medusa.common import SKIPPED, WANTED, ARCHIVED, IGNORED, FAILED, DOWNLOADED - from medusa.common import Quality, qualityPresets, statusStrings, Overview - from medusa.helper.common import pretty_file_size - from medusa.indexers.indexer_api import indexerApi -%> -
- ## @TODO: Remove data attributes - ## @SEE: https://github.com/pymedusa/Medusa/pull/5087#discussion_r214074436 -
-
- ## @TODO: Remove data attributes - ## @SEE: https://github.com/pymedusa/Medusa/pull/5087#discussion_r214077142 -

- {{ show.title }} -

-
- -
- - Manual search for:
- {{ show.title }} / Season {{ season }} -
-
-
- - Display Specials: {{ config.layout.show.specials ? 'Hide' : 'Show' }} - - -
- - - - -
-
-
-
- -% if show_message: -
-
- ${show_message} -
-
-% endif - -
-
-
-
-
- -
-
-
- -
- -
-
- -
- - - - - - - [trakt] - - - - - % if xem_numbering or xem_absolute_numbering: - - [xem] - - % endif - [fanart.tv] -
-
-
    - %if show.genre: -
  • {{ genre }}
  • - % elif show.imdb_info.get('genres'): - % for imdbgenre in show.imdb_info['genres'].replace('Sci-Fi', 'Science-Fiction').split('|'): -
  • ${imdbgenre}
  • - % endfor - % endif -
-
-
- -
- -
-
-
${day.strftime('%A').decode(app.SYS_ENCODING).capitalize()}
${sbdatetime.sbftime(dt=day, t_preset='%A').capitalize()}
- - - - - <% allowed_qualities, preferred_qualities = Quality.split_quality(int(show.quality)) %> - - - - - - - % if showLoc[1]: - - % else: - - % endif - % if all_scene_exceptions: - - % endif - % if show.show_words().required_words: - - % endif - % if show.show_words().ignored_words: - - % endif - % if show.show_words().preferred_words: - - % endif - % if show.show_words().undesired_words: - - % endif - % if bwl and bwl.whitelist: - - - - - % endif - % if bwl and bwl.blacklist: - - - - - % endif - -
- -
Quality: - % if show.quality in qualityPresets: - - % else: - % if allowed_qualities: - <% allowed_as_json = json.dumps(sorted(allowed_qualities)) %> - Allowed: - - ${'
' if preferred_qualities else ''} - % endif - % if preferred_qualities: - <% preferred_as_json = json.dumps(sorted(preferred_qualities)) %> - Preferred: - - % endif - % endif -
Originally Airs: {{ show.airs }} ${"" if network_timezones.test_timeformat(show.airs) else "(invalid Timeformat)"} on {{ show.network }}
Originally Airs: {{ show.network }}
Originally Airs: {{ show.airs }} ${"" if network_timezones.test_timeformat(show.airs) else "(invalid Timeformat)"}
Show Status: {{ show.status }}
Default EP Status: {{ show.config.defaultEpisodeStatus }}
Location: ${showLoc[0]}
Location: ${showLoc[0]} (Missing)
Scene Name:${all_scene_exceptions}
Required Words: ${', '.join(show.show_words().required_words)}
Ignored Words: ${', '.join(show.show_words().ignored_words)}
Preferred Words: ${', '.join(show.show_words().preferred_words)}
Undesired Words: ${', '.join(show.show_words().undesired_words)}
Wanted Group${"s" if len(bwl.whitelist) > 1 else ""}:${', '.join(bwl.whitelist)}
Unwanted Group${"s" if len(bwl.blacklist) > 1 else ""}:${', '.join(bwl.blacklist)}
Size:${pretty_file_size(helpers.get_size(showLoc[0]))}
-
- - -
- - <% info_flag = subtitles.code_from_code(show.lang) if show.lang else '' %> - - - - - - - - - -
Info Language:${show.lang}
Subtitles:
Season Folders:
Paused:
Air-by-Date:
Sports:
Anime:
DVD Order:
Scene Numbering:
-
- - - - - - -
-
-
-
-
- <% total_snatched = ep_counts[Overview.SNATCHED] + ep_counts[Overview.SNATCHED_PROPER] + ep_counts[Overview.SNATCHED_BEST] %> - - - - - - - -
-
- - - - - - -
-
-
-
-
-
diff --git a/themes/dark/templates/snatchSelection.mako b/themes/dark/templates/snatchSelection.mako index f6283c0c86..90b46c5697 100644 --- a/themes/dark/templates/snatchSelection.mako +++ b/themes/dark/templates/snatchSelection.mako @@ -2,6 +2,7 @@ <%! from datetime import datetime from medusa import app + from medusa.sbdatetime import sbdatetime %> <%block name="scripts"> @@ -11,7 +12,11 @@
- <%include file="/partials/showheader.mako"/> +
@@ -137,12 +142,11 @@ - <% user_preset = app.DATE_PRESET + ' ' + app.TIME_PRESET %> - ${hItem['pubdate'].strftime(user_preset).decode(app.SYS_ENCODING) if hItem['pubdate'] else 'N/A'} + ${sbdatetime.sbfdatetime(dt=hItem['pubdate'], d_preset=app.DATE_PRESET, t_preset=app.TIME_PRESET) if hItem['pubdate'] else 'N/A'} - ${hItem['date_added'].strftime(user_preset).decode(app.SYS_ENCODING) if hItem['date_added'] else 'N/A'} + ${sbdatetime.sbfdatetime(dt=hItem['date_added'], d_preset=app.DATE_PRESET, t_preset=app.TIME_PRESET) if hItem['date_added'] else 'N/A'} search diff --git a/themes/dark/templates/status.mako b/themes/dark/templates/status.mako index 59cf56017e..0f92672d63 100644 --- a/themes/dark/templates/status.mako +++ b/themes/dark/templates/status.mako @@ -5,6 +5,7 @@ from medusa.show_queue import ShowQueueActions from medusa.helper.common import dateTimeFormat from random import choice + from six import iteritems %> <%block name="scripts"> \n\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./anidb-release-group-ui.vue?vue&type=template&id=10f4092b&scoped=true&\"\nimport script from \"./anidb-release-group-ui.vue?vue&type=script&lang=js&\"\nexport * from \"./anidb-release-group-ui.vue?vue&type=script&lang=js&\"\nimport style0 from \"./anidb-release-group-ui.vue?vue&type=style&index=0&id=10f4092b&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"10f4092b\",\n null\n \n)\n\ncomponent.options.__file = \"anidb-release-group-ui.vue\"\nexport default component.exports","\n\n\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-show-options.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-show-options.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./add-show-options.vue?vue&type=template&id=699d27b6&\"\nimport script from \"./add-show-options.vue?vue&type=script&lang=js&\"\nexport * from \"./add-show-options.vue?vue&type=script&lang=js&\"\nimport style0 from \"./add-show-options.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"add-show-options.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"nav\",\n {\n staticClass: \"navbar navbar-default navbar-fixed-top hidden-print\",\n attrs: { role: \"navigation\" }\n },\n [\n _c(\"div\", { staticClass: \"container-fluid\" }, [\n _c(\n \"div\",\n { staticClass: \"navbar-header\" },\n [\n _c(\n \"button\",\n {\n staticClass: \"navbar-toggle collapsed\",\n attrs: {\n type: \"button\",\n \"data-toggle\": \"collapse\",\n \"data-target\": \"#main_nav\"\n }\n },\n [\n _vm.toolsBadgeCount > 0\n ? _c(\n \"span\",\n { class: \"floating-badge\" + _vm.toolsBadgeClass },\n [_vm._v(_vm._s(_vm.toolsBadgeCount))]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"span\", { staticClass: \"sr-only\" }, [\n _vm._v(\"Toggle navigation\")\n ]),\n _vm._v(\" \"),\n _c(\"span\", { staticClass: \"icon-bar\" }),\n _vm._v(\" \"),\n _c(\"span\", { staticClass: \"icon-bar\" }),\n _vm._v(\" \"),\n _c(\"span\", { staticClass: \"icon-bar\" })\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"app-link\",\n {\n staticClass: \"navbar-brand\",\n attrs: { href: \"home/\", title: \"Medusa\" }\n },\n [\n _c(\"img\", {\n staticClass: \"img-responsive pull-left\",\n staticStyle: { height: \"50px\" },\n attrs: { alt: \"Medusa\", src: \"images/medusa.png\" }\n })\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _vm.isAuthenticated\n ? _c(\n \"div\",\n {\n staticClass: \"collapse navbar-collapse\",\n attrs: { id: \"main_nav\" }\n },\n [\n _c(\"ul\", { staticClass: \"nav navbar-nav navbar-right\" }, [\n _c(\n \"li\",\n {\n staticClass: \"navbar-split dropdown\",\n class: { active: _vm.topMenu === \"home\" },\n attrs: { id: \"NAVhome\" }\n },\n [\n _c(\n \"app-link\",\n {\n staticClass: \"dropdown-toggle\",\n attrs: {\n href: \"home/\",\n \"aria-haspopup\": \"true\",\n \"data-toggle\": \"dropdown\",\n \"data-hover\": \"dropdown\"\n }\n },\n [\n _c(\"span\", [_vm._v(\"Shows\")]),\n _vm._v(\" \"),\n _c(\"b\", { staticClass: \"caret\" })\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"ul\",\n { staticClass: \"dropdown-menu\" },\n [\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"home/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-home\" }),\n _vm._v(\" Show List\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"addShows/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-addshow\" }),\n _vm._v(\" Add Shows\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"addRecommended/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-addshow\" }),\n _vm._v(\" Add Recommended Shows\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"home/postprocess/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-postprocess\"\n }),\n _vm._v(\" Manual Post-Processing\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _vm.recentShows.length > 0\n ? [\n _c(\"li\", {\n staticClass: \"divider\",\n attrs: { role: \"separator\" }\n }),\n _vm._v(\" \"),\n _vm._l(_vm.recentShows, function(recentShow) {\n return _c(\n \"li\",\n { key: recentShow.link },\n [\n _c(\n \"app-link\",\n { attrs: { href: recentShow.link } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-addshow\"\n }),\n _vm._v(\n \" \" +\n _vm._s(recentShow.name) +\n \"\\n \"\n )\n ]\n )\n ],\n 1\n )\n })\n ]\n : _vm._e()\n ],\n 2\n ),\n _vm._v(\" \"),\n _c(\"div\", { staticStyle: { clear: \"both\" } })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n {\n class: { active: _vm.topMenu === \"schedule\" },\n attrs: { id: \"NAVschedule\" }\n },\n [\n _c(\"app-link\", { attrs: { href: \"schedule/\" } }, [\n _vm._v(\"Schedule\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n {\n class: { active: _vm.topMenu === \"history\" },\n attrs: { id: \"NAVhistory\" }\n },\n [\n _c(\"app-link\", { attrs: { href: \"history/\" } }, [\n _vm._v(\"History\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n {\n staticClass: \"navbar-split dropdown\",\n class: { active: _vm.topMenu === \"manage\" },\n attrs: { id: \"NAVmanage\" }\n },\n [\n _c(\n \"app-link\",\n {\n staticClass: \"dropdown-toggle\",\n attrs: {\n href: \"manage/episodeStatuses/\",\n \"aria-haspopup\": \"true\",\n \"data-toggle\": \"dropdown\",\n \"data-hover\": \"dropdown\"\n }\n },\n [\n _c(\"span\", [_vm._v(\"Manage\")]),\n _vm._v(\" \"),\n _c(\"b\", { staticClass: \"caret\" })\n ]\n ),\n _vm._v(\" \"),\n _c(\"ul\", { staticClass: \"dropdown-menu\" }, [\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"manage/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-manage\" }),\n _vm._v(\" Mass Update\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"manage/backlogOverview/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-backlog-view\"\n }),\n _vm._v(\" Backlog Overview\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"manage/manageSearches/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-manage-searches\"\n }),\n _vm._v(\" Manage Searches\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"manage/episodeStatuses/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-manage2\" }),\n _vm._v(\" Episode Status Management\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _vm.linkVisible.plex\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"home/updatePLEX/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-plex\" }),\n _vm._v(\" Update PLEX\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.linkVisible.kodi\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"home/updateKODI/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-kodi\" }),\n _vm._v(\" Update KODI\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.linkVisible.emby\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"home/updateEMBY/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-emby\" }),\n _vm._v(\" Update Emby\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.linkVisible.manageTorrents\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href: \"manage/manageTorrents/\",\n target: \"_blank\"\n }\n },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-bittorrent\"\n }),\n _vm._v(\" Manage Torrents\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.linkVisible.failedDownloads\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: { href: \"manage/failedDownloads/\" }\n },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-failed-download\"\n }),\n _vm._v(\" Failed Downloads\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.linkVisible.subtitleMissed\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"manage/subtitleMissed/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-backlog\"\n }),\n _vm._v(\" Missed Subtitle Management\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.linkVisible.subtitleMissedPP\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: { href: \"manage/subtitleMissedPP/\" }\n },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-backlog\"\n }),\n _vm._v(\n \" Missed Subtitle in Post-Process folder\"\n )\n ]\n )\n ],\n 1\n )\n : _vm._e()\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticStyle: { clear: \"both\" } })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n {\n staticClass: \"navbar-split dropdown\",\n class: { active: _vm.topMenu === \"config\" },\n attrs: { id: \"NAVconfig\" }\n },\n [\n _c(\n \"app-link\",\n {\n staticClass: \"dropdown-toggle\",\n attrs: {\n href: \"config/\",\n \"aria-haspopup\": \"true\",\n \"data-toggle\": \"dropdown\",\n \"data-hover\": \"dropdown\"\n }\n },\n [\n _c(\"span\", { staticClass: \"visible-xs-inline\" }, [\n _vm._v(\"Config\")\n ]),\n _c(\"img\", {\n staticClass: \"navbaricon hidden-xs\",\n attrs: { src: \"images/menu/system18.png\" }\n }),\n _vm._v(\" \"),\n _c(\"b\", { staticClass: \"caret\" })\n ]\n ),\n _vm._v(\" \"),\n _c(\"ul\", { staticClass: \"dropdown-menu\" }, [\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"config/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-help\" }),\n _vm._v(\" Help & Info\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/general/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-config\" }),\n _vm._v(\" General\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/backuprestore/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-backup\" }),\n _vm._v(\" Backup & Restore\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/search/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-manage-searches\"\n }),\n _vm._v(\" Search Settings\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/providers/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-provider\" }),\n _vm._v(\" Search Providers\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/subtitles/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-backlog\" }),\n _vm._v(\" Subtitles Settings\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/postProcessing/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-postprocess\"\n }),\n _vm._v(\" Post Processing\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/notifications/\" } },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-notification\"\n }),\n _vm._v(\" Notifications\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"config/anime/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-anime\" }),\n _vm._v(\" Anime\")\n ]\n )\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticStyle: { clear: \"both\" } })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n {\n staticClass: \"navbar-split dropdown\",\n class: { active: _vm.topMenu === \"system\" },\n attrs: { id: \"NAVsystem\" }\n },\n [\n _c(\n \"app-link\",\n {\n staticClass: \"padding-right-15 dropdown-toggle\",\n attrs: {\n href: \"home/status/\",\n \"aria-haspopup\": \"true\",\n \"data-toggle\": \"dropdown\",\n \"data-hover\": \"dropdown\"\n }\n },\n [\n _c(\"span\", { staticClass: \"visible-xs-inline\" }, [\n _vm._v(\"Tools\")\n ]),\n _c(\"img\", {\n staticClass: \"navbaricon hidden-xs\",\n attrs: { src: \"images/menu/system18-2.png\" }\n }),\n _vm._v(\" \"),\n _vm.toolsBadgeCount > 0\n ? _c(\n \"span\",\n { class: \"badge\" + _vm.toolsBadgeClass },\n [_vm._v(_vm._s(_vm.toolsBadgeCount))]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"b\", { staticClass: \"caret\" })\n ]\n ),\n _vm._v(\" \"),\n _c(\"ul\", { staticClass: \"dropdown-menu\" }, [\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"news/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-news\" }),\n _vm._v(\" News \"),\n _vm.config.news.unread > 0\n ? _c(\"span\", { staticClass: \"badge\" }, [\n _vm._v(_vm._s(_vm.config.news.unread))\n ])\n : _vm._e()\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"IRC/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-irc\" }),\n _vm._v(\" IRC\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"changes/\" } }, [\n _c(\"i\", { staticClass: \"menu-icon-changelog\" }),\n _vm._v(\" Changelog\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: _vm.config.donationsUrl } },\n [\n _c(\"i\", { staticClass: \"menu-icon-support\" }),\n _vm._v(\" Support Medusa\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\"li\", {\n staticClass: \"divider\",\n attrs: { role: \"separator\" }\n }),\n _vm._v(\" \"),\n _vm.config.logs.numErrors > 0\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"errorlogs/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-error\" }),\n _vm._v(\" View Errors \"),\n _c(\n \"span\",\n { staticClass: \"badge btn-danger\" },\n [\n _vm._v(\n _vm._s(_vm.config.logs.numErrors)\n )\n ]\n )\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.config.logs.numWarnings > 0\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href:\n \"errorlogs/?level=\" + _vm.warningLevel\n }\n },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-viewlog-errors\"\n }),\n _vm._v(\" View Warnings \"),\n _c(\n \"span\",\n { staticClass: \"badge btn-warning\" },\n [\n _vm._v(\n _vm._s(_vm.config.logs.numWarnings)\n )\n ]\n )\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"errorlogs/viewlog/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-viewlog\" }),\n _vm._v(\" View Log\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\"li\", {\n staticClass: \"divider\",\n attrs: { role: \"separator\" }\n }),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href: \"home/updateCheck?pid=\" + _vm.config.pid\n }\n },\n [\n _c(\"i\", { staticClass: \"menu-icon-update\" }),\n _vm._v(\" Check For Updates\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href: \"home/restart/?pid=\" + _vm.config.pid\n },\n nativeOn: {\n click: function($event) {\n $event.preventDefault()\n _vm.confirmDialog($event, \"restart\")\n }\n }\n },\n [\n _c(\"i\", { staticClass: \"menu-icon-restart\" }),\n _vm._v(\" Restart\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href: \"home/shutdown/?pid=\" + _vm.config.pid\n },\n nativeOn: {\n click: function($event) {\n $event.preventDefault()\n _vm.confirmDialog($event, \"shutdown\")\n }\n }\n },\n [\n _c(\"i\", { staticClass: \"menu-icon-shutdown\" }),\n _vm._v(\" Shutdown\")\n ]\n )\n ],\n 1\n ),\n _vm._v(\" \"),\n _vm.username\n ? _c(\n \"li\",\n [\n _c(\n \"app-link\",\n {\n attrs: { href: \"logout\" },\n nativeOn: {\n click: function($event) {\n $event.preventDefault()\n _vm.confirmDialog($event, \"logout\")\n }\n }\n },\n [\n _c(\"i\", {\n staticClass: \"menu-icon-shutdown\"\n }),\n _vm._v(\" Logout\")\n ]\n )\n ],\n 1\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"li\", {\n staticClass: \"divider\",\n attrs: { role: \"separator\" }\n }),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"home/status/\" } },\n [\n _c(\"i\", { staticClass: \"menu-icon-info\" }),\n _vm._v(\" Server Status\")\n ]\n )\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticStyle: { clear: \"both\" } })\n ],\n 1\n )\n ])\n ]\n )\n : _vm._e()\n ])\n ]\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./app-header.vue?vue&type=template&id=33b81de2&\"\nimport script from \"./app-header.vue?vue&type=script&lang=js&\"\nexport * from \"./app-header.vue?vue&type=script&lang=js&\"\nimport style0 from \"./app-header.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"app-header.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\")\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./backstretch.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./backstretch.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./backstretch.vue?vue&type=template&id=630a2e1f&\"\nimport script from \"./backstretch.vue?vue&type=script&lang=js&\"\nexport * from \"./backstretch.vue?vue&type=script&lang=js&\"\nimport style0 from \"./backstretch.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"backstretch.vue\"\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./home.vue?vue&type=script&lang=js&\"\nexport * from \"./home.vue?vue&type=script&lang=js&\"\nimport style0 from \"./home.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"home.vue\"\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manual-post-process.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manual-post-process.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./manual-post-process.vue?vue&type=script&lang=js&\"\nexport * from \"./manual-post-process.vue?vue&type=script&lang=js&\"\nimport style0 from \"./manual-post-process.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"manual-post-process.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"root-dirs-wrapper\" } }, [\n _c(\"div\", { staticClass: \"root-dirs-selectbox\" }, [\n _c(\n \"select\",\n _vm._g(\n _vm._b(\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.selectedRootDir,\n expression: \"selectedRootDir\"\n }\n ],\n ref: \"rootDirs\",\n attrs: { name: \"rootDir\", id: \"rootDirs\", size: \"6\" },\n on: {\n change: function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val = \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.selectedRootDir = $event.target.multiple\n ? $$selectedVal\n : $$selectedVal[0]\n }\n }\n },\n \"select\",\n _vm.$attrs,\n false\n ),\n _vm.$listeners\n ),\n _vm._l(_vm.rootDirs, function(curDir) {\n return _c(\n \"option\",\n { key: curDir.path, domProps: { value: curDir.path } },\n [\n _vm._v(\n \"\\n \" +\n _vm._s(_vm._f(\"markDefault\")(curDir)) +\n \"\\n \"\n )\n ]\n )\n })\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"root-dirs-controls\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa\",\n attrs: { type: \"button\" },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.add($event)\n }\n }\n },\n [_vm._v(\"New\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa\",\n attrs: { type: \"button\", disabled: !_vm.selectedRootDir },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.edit($event)\n }\n }\n },\n [_vm._v(\"Edit\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa\",\n attrs: { type: \"button\", disabled: !_vm.selectedRootDir },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.remove($event)\n }\n }\n },\n [_vm._v(\"Delete\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa\",\n attrs: { type: \"button\", disabled: !_vm.selectedRootDir },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.setDefault($event)\n }\n }\n },\n [_vm._v(\"Set as Default *\")]\n )\n ])\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./root-dirs.vue?vue&type=template&id=76f972d6&\"\nimport script from \"./root-dirs.vue?vue&type=script&lang=js&\"\nexport * from \"./root-dirs.vue?vue&type=script&lang=js&\"\nimport style0 from \"./root-dirs.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"root-dirs.vue\"\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./show.vue?vue&type=script&lang=js&\"\nexport * from \"./show.vue?vue&type=script&lang=js&\"\nimport style0 from \"./show.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"show.vue\"\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./snatch-selection.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./snatch-selection.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./snatch-selection.vue?vue&type=script&lang=js&\"\nexport * from \"./snatch-selection.vue?vue&type=script&lang=js&\"\nimport style0 from \"./snatch-selection.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"snatch-selection.vue\"\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./status.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./status.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./status.vue?vue&type=script&lang=js&\"\nexport * from \"./status.vue?vue&type=script&lang=js&\"\nimport style0 from \"./status.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"status.vue\"\nexport default component.exports","export { default as AddRecommended } from './add-recommended.vue';\nexport { default as AddShowOptions } from './add-show-options.vue';\nexport { default as AddShows } from './add-shows.vue';\nexport { default as AnidbReleaseGroupUi } from './anidb-release-group-ui.vue';\nexport { default as AppHeader } from './app-header.vue';\nexport { default as Backstretch } from './backstretch.vue';\nexport { default as Config } from './config.vue';\nexport { default as ConfigPostProcessing } from './config-post-processing.vue';\nexport { default as Home } from './home.vue';\nexport { default as IRC } from './irc.vue';\nexport { default as Login } from './login.vue';\nexport { default as ManualPostProcess } from './manual-post-process.vue';\nexport { default as RootDirs } from './root-dirs.vue';\nexport { default as Show } from './show.vue';\nexport { default as SnatchSelection } from './snatch-selection.vue';\nexport { default as Status } from './status.vue';\nexport * from './http';\nexport * from './helpers';\n","import axios from 'axios';\n\nconst webRoot = document.body.getAttribute('web-root');\nconst apiKey = document.body.getAttribute('api-key');\n\n/**\n * Api client based on the axios client, to communicate with medusa's web routes, which return json data.\n */\nconst apiRoute = axios.create({ // eslint-disable-line no-unused-vars\n baseURL: webRoot + '/',\n timeout: 30000,\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json'\n }\n});\n\n/**\n * Api client based on the axios client, to communicate with medusa's api v1.\n */\nconst apiv1 = axios.create({ // eslint-disable-line no-unused-vars\n baseURL: webRoot + '/api/v1/' + apiKey + '/',\n timeout: 30000,\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json'\n }\n});\n\n/**\n * Api client based on the axios client, to communicate with medusa's api v2.\n */\nconst api = axios.create({ // eslint-disable-line no-unused-vars\n baseURL: webRoot + '/api/v2/',\n timeout: 30000,\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n 'X-Api-Key': apiKey\n }\n});\n\nexport {\n webRoot,\n apiKey,\n apiRoute,\n apiv1,\n api\n};\n","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n _vm.linkProperties.is,\n {\n tag: \"component\",\n class: { \"router-link\": _vm.linkProperties.is === \"router-link\" },\n attrs: {\n to: _vm.linkProperties.to,\n href: _vm.linkProperties.href,\n target: _vm.linkProperties.target,\n rel: _vm.linkProperties.rel,\n \"false-link\": _vm.linkProperties.falseLink\n }\n },\n [_vm._t(\"default\")],\n 2\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./app-link.vue?vue&type=template&id=3da1d90a&\"\nimport script from \"./app-link.vue?vue&type=script&lang=js&\"\nexport * from \"./app-link.vue?vue&type=script&lang=js&\"\nimport style0 from \"./app-link.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"app-link.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return !_vm.link\n ? _c(\"img\", {\n class: _vm.cls,\n attrs: { src: _vm.src },\n on: {\n error: function($event) {\n _vm.error = true\n }\n }\n })\n : _c(\"app-link\", { attrs: { href: _vm.href } }, [\n _c(\"img\", {\n class: _vm.cls,\n attrs: { src: _vm.src },\n on: {\n error: function($event) {\n _vm.error = true\n }\n }\n })\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./asset.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./asset.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./asset.vue?vue&type=template&id=4d502334&\"\nimport script from \"./asset.vue?vue&type=script&lang=js&\"\nexport * from \"./asset.vue?vue&type=script&lang=js&\"\nimport style0 from \"./asset.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"asset.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"config-template-content\" } }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: _vm.labelFor }\n },\n [_c(\"span\", [_vm._v(_vm._s(_vm.label))])]\n ),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [_vm._t(\"default\")], 2)\n ])\n ])\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-template.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-template.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./config-template.vue?vue&type=template&id=0da1fcab&\"\nimport script from \"./config-template.vue?vue&type=script&lang=js&\"\nexport * from \"./config-template.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-template.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"config-template.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"config-textbox-number-content\" } }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: _vm.id } },\n [_c(\"span\", [_vm._v(_vm._s(_vm.label))])]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\n \"input\",\n _vm._b(\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.localValue,\n expression: \"localValue\"\n }\n ],\n attrs: { type: \"number\" },\n domProps: { value: _vm.localValue },\n on: {\n input: [\n function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.localValue = $event.target.value\n },\n function($event) {\n _vm.updateValue()\n }\n ]\n }\n },\n \"input\",\n {\n min: _vm.min,\n max: _vm.max,\n step: _vm.step,\n id: _vm.id,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n },\n false\n )\n ),\n _vm._v(\" \"),\n _vm._l(_vm.explanations, function(explanation, index) {\n return _c(\"p\", { key: index }, [_vm._v(_vm._s(explanation))])\n }),\n _vm._v(\" \"),\n _vm._t(\"default\")\n ],\n 2\n )\n ])\n ])\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./config-textbox-number.vue?vue&type=template&id=159c522c&\"\nimport script from \"./config-textbox-number.vue?vue&type=script&lang=js&\"\nexport * from \"./config-textbox-number.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-textbox-number.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"config-textbox-number.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"config-textbox\" } }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: _vm.id } },\n [_c(\"span\", [_vm._v(_vm._s(_vm.label))])]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n {\n id: _vm.id,\n type: _vm.type,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n }.type === \"checkbox\"\n ? _c(\n \"input\",\n _vm._b(\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.localValue,\n expression: \"localValue\"\n }\n ],\n attrs: { type: \"checkbox\" },\n domProps: {\n checked: Array.isArray(_vm.localValue)\n ? _vm._i(_vm.localValue, null) > -1\n : _vm.localValue\n },\n on: {\n input: function($event) {\n _vm.updateValue()\n },\n change: function($event) {\n var $$a = _vm.localValue,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 && (_vm.localValue = $$a.concat([$$v]))\n } else {\n $$i > -1 &&\n (_vm.localValue = $$a\n .slice(0, $$i)\n .concat($$a.slice($$i + 1)))\n }\n } else {\n _vm.localValue = $$c\n }\n }\n }\n },\n \"input\",\n {\n id: _vm.id,\n type: _vm.type,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n },\n false\n )\n )\n : {\n id: _vm.id,\n type: _vm.type,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n }.type === \"radio\"\n ? _c(\n \"input\",\n _vm._b(\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.localValue,\n expression: \"localValue\"\n }\n ],\n attrs: { type: \"radio\" },\n domProps: { checked: _vm._q(_vm.localValue, null) },\n on: {\n input: function($event) {\n _vm.updateValue()\n },\n change: function($event) {\n _vm.localValue = null\n }\n }\n },\n \"input\",\n {\n id: _vm.id,\n type: _vm.type,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n },\n false\n )\n )\n : _c(\n \"input\",\n _vm._b(\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.localValue,\n expression: \"localValue\"\n }\n ],\n attrs: {\n type: {\n id: _vm.id,\n type: _vm.type,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n }.type\n },\n domProps: { value: _vm.localValue },\n on: {\n input: [\n function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.localValue = $event.target.value\n },\n function($event) {\n _vm.updateValue()\n }\n ]\n }\n },\n \"input\",\n {\n id: _vm.id,\n type: _vm.type,\n name: _vm.id,\n class: _vm.inputClass,\n placeholder: _vm.placeholder,\n disabled: _vm.disabled\n },\n false\n )\n ),\n _vm._v(\" \"),\n _vm._l(_vm.explanations, function(explanation, index) {\n return _c(\"p\", { key: index }, [_vm._v(_vm._s(explanation))])\n }),\n _vm._v(\" \"),\n _vm._t(\"default\")\n ],\n 2\n )\n ])\n ])\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./config-textbox.vue?vue&type=template&id=788aa398&\"\nimport script from \"./config-textbox.vue?vue&type=script&lang=js&\"\nexport * from \"./config-textbox.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-textbox.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"config-textbox.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"config-toggle-slider-content\" } }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: _vm.id } },\n [_c(\"span\", [_vm._v(_vm._s(_vm.label))])]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\n \"toggle-button\",\n _vm._b(\n {\n attrs: { width: 45, height: 22, sync: \"\" },\n on: {\n input: function($event) {\n _vm.updateValue()\n }\n },\n model: {\n value: _vm.localChecked,\n callback: function($$v) {\n _vm.localChecked = $$v\n },\n expression: \"localChecked\"\n }\n },\n \"toggle-button\",\n { id: _vm.id, name: _vm.id, disabled: _vm.disabled },\n false\n )\n ),\n _vm._v(\" \"),\n _vm._l(_vm.explanations, function(explanation, index) {\n return _c(\"p\", { key: index }, [_vm._v(_vm._s(explanation))])\n }),\n _vm._v(\" \"),\n _vm._t(\"default\")\n ],\n 2\n )\n ])\n ])\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./config-toggle-slider.vue?vue&type=template&id=61641df4&\"\nimport script from \"./config-toggle-slider.vue?vue&type=script&lang=js&\"\nexport * from \"./config-toggle-slider.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-toggle-slider.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"config-toggle-slider.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { staticClass: \"file-browser max-width\" }, [\n _c(\n \"div\",\n { class: _vm.showBrowseButton ? \"input-group\" : \"input-group-no-btn\" },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.currentPath,\n expression: \"currentPath\"\n }\n ],\n ref: \"locationInput\",\n staticClass: \"form-control input-sm fileBrowserField\",\n attrs: { name: _vm.name, type: \"text\" },\n domProps: { value: _vm.currentPath },\n on: {\n input: function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.currentPath = $event.target.value\n }\n }\n }),\n _vm._v(\" \"),\n _vm.showBrowseButton\n ? _c(\n \"div\",\n {\n staticClass: \"input-group-btn\",\n attrs: { title: _vm.title, alt: _vm.title },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.openDialog($event)\n }\n }\n },\n [_vm._m(0)]\n )\n : _vm._e()\n ]\n ),\n _vm._v(\" \"),\n _c(\"div\", {\n ref: \"fileBrowserDialog\",\n staticClass: \"fileBrowserDialog\",\n staticStyle: { display: \"none\" }\n }),\n _vm._v(\" \"),\n _c(\"input\", {\n ref: \"fileBrowserSearchBox\",\n staticClass: \"form-control\",\n staticStyle: { display: \"none\" },\n attrs: { type: \"text\" },\n domProps: { value: _vm.currentPath },\n on: {\n keyup: function($event) {\n if (\n !(\"button\" in $event) &&\n _vm._k($event.keyCode, \"enter\", 13, $event.key, \"Enter\")\n ) {\n return null\n }\n _vm.browse($event.target.value)\n }\n }\n }),\n _vm._v(\" \"),\n _c(\n \"ul\",\n { ref: \"fileBrowserFileList\", staticStyle: { display: \"none\" } },\n _vm._l(_vm.files, function(file) {\n return _c(\n \"li\",\n { key: file.name, staticClass: \"ui-state-default ui-corner-all\" },\n [\n _c(\n \"a\",\n {\n on: {\n mouseover: function($event) {\n _vm.toggleFolder(file, $event)\n },\n mouseout: function($event) {\n _vm.toggleFolder(file, $event)\n },\n click: function($event) {\n _vm.fileClicked(file)\n }\n }\n },\n [\n _c(\"span\", {\n class:\n \"ui-icon \" +\n (file.isFile ? \"ui-icon-blank\" : \"ui-icon-folder-collapsed\")\n }),\n _vm._v(\" \" + _vm._s(file.name) + \"\\n \")\n ]\n )\n ]\n )\n })\n )\n ])\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n {\n staticClass: \"btn btn-default input-sm\",\n staticStyle: { \"font-size\": \"14px\" }\n },\n [_c(\"i\", { staticClass: \"glyphicon glyphicon-open\" })]\n )\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./file-browser.vue?vue&type=template&id=5a327762&scoped=true&\"\nimport script from \"./file-browser.vue?vue&type=script&lang=js&\"\nexport * from \"./file-browser.vue?vue&type=script&lang=js&\"\nimport style0 from \"./file-browser.vue?vue&type=style&index=0&id=5a327762&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"5a327762\",\n null\n \n)\n\ncomponent.options.__file = \"file-browser.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"select\")\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./language-select.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./language-select.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./language-select.vue?vue&type=template&id=f30eee9c&\"\nimport script from \"./language-select.vue?vue&type=script&lang=js&\"\nexport * from \"./language-select.vue?vue&type=script&lang=js&\"\nimport style0 from \"./language-select.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"language-select.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"name-pattern-wrapper\" } }, [\n _vm.type\n ? _c(\"div\", { staticClass: \"form-group\" }, [\n _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"enable_naming_custom\" }\n },\n [_c(\"span\", [_vm._v(\"Custom \" + _vm._s(_vm.type))])]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"enable_naming_custom\",\n name: \"enable_naming_custom\",\n sync: \"\"\n },\n on: {\n input: function($event) {\n _vm.update()\n }\n },\n model: {\n value: _vm.isEnabled,\n callback: function($$v) {\n _vm.isEnabled = $$v\n },\n expression: \"isEnabled\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Name \" +\n _vm._s(_vm.type) +\n \" shows differently than regular shows?\"\n )\n ])\n ],\n 1\n )\n ])\n : _vm._e(),\n _vm._v(\" \"),\n !_vm.type || _vm.isEnabled\n ? _c(\"div\", { staticClass: \"episode-naming\" }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(0),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\n \"select\",\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.selectedNamingPattern,\n expression: \"selectedNamingPattern\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: { id: \"name_presets\" },\n on: {\n change: [\n function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val = \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.selectedNamingPattern = $event.target.multiple\n ? $$selectedVal\n : $$selectedVal[0]\n },\n _vm.updatePatternSamples\n ],\n input: function($event) {\n _vm.update()\n }\n }\n },\n _vm._l(_vm.presets, function(preset) {\n return _c(\n \"option\",\n { key: preset.pattern, attrs: { id: preset.pattern } },\n [_vm._v(_vm._s(preset.example))]\n )\n })\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { attrs: { id: \"naming_custom\" } }, [\n _vm.isCustom\n ? _c(\n \"div\",\n {\n staticClass: \"form-group\",\n staticStyle: { \"padding-top\": \"0\" }\n },\n [\n _vm._m(1),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.customName,\n expression: \"customName\"\n }\n ],\n staticClass:\n \"form-control-inline-max input-sm max-input350\",\n attrs: {\n type: \"text\",\n name: \"naming_pattern\",\n id: \"naming_pattern\"\n },\n domProps: { value: _vm.customName },\n on: {\n change: _vm.updatePatternSamples,\n input: [\n function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.customName = $event.target.value\n },\n function($event) {\n _vm.update()\n }\n ]\n }\n }),\n _vm._v(\" \"),\n _c(\"img\", {\n staticClass: \"legend\",\n attrs: {\n src: \"images/legend16.png\",\n width: \"16\",\n height: \"16\",\n alt: \"[Toggle Key]\",\n id: \"show_naming_key\",\n title: \"Toggle Naming Legend\"\n },\n on: {\n click: function($event) {\n _vm.showLegend = !_vm.showLegend\n }\n }\n })\n ])\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.showLegend && _vm.isCustom\n ? _c(\n \"div\",\n { staticClass: \"nocheck\", attrs: { id: \"naming_key\" } },\n [\n _c(\"table\", { staticClass: \"Key\" }, [\n _vm._m(2),\n _vm._v(\" \"),\n _vm._m(3),\n _vm._v(\" \"),\n _c(\"tbody\", [\n _vm._m(4),\n _vm._v(\" \"),\n _vm._m(5),\n _vm._v(\" \"),\n _vm._m(6),\n _vm._v(\" \"),\n _vm._m(7),\n _vm._v(\" \"),\n _vm._m(8),\n _vm._v(\" \"),\n _vm._m(9),\n _vm._v(\" \"),\n _vm._m(10),\n _vm._v(\" \"),\n _vm._m(11),\n _vm._v(\" \"),\n _vm._m(12),\n _vm._v(\" \"),\n _vm._m(13),\n _vm._v(\" \"),\n _vm._m(14),\n _vm._v(\" \"),\n _vm._m(15),\n _vm._v(\" \"),\n _vm._m(16),\n _vm._v(\" \"),\n _vm._m(17),\n _vm._v(\" \"),\n _vm._m(18),\n _vm._v(\" \"),\n _vm._m(19),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(20),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%M\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(_vm._s(_vm.getDateFormat(\"M\")))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%D\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(_vm._s(_vm.getDateFormat(\"D\")))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%Y\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(_vm._s(_vm.getDateFormat(\"YY\")))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(21),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%CM\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(_vm._s(_vm.getDateFormat(\"M\")))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%CD\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(_vm._s(_vm.getDateFormat(\"D\")))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%CY\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(_vm._s(_vm.getDateFormat(\"YY\")))])\n ]),\n _vm._v(\" \"),\n _vm._m(22),\n _vm._v(\" \"),\n _vm._m(23),\n _vm._v(\" \"),\n _vm._m(24),\n _vm._v(\" \"),\n _vm._m(25),\n _vm._v(\" \"),\n _vm._m(26),\n _vm._v(\" \"),\n _vm._m(27),\n _vm._v(\" \"),\n _vm._m(28),\n _vm._v(\" \"),\n _vm._m(29),\n _vm._v(\" \"),\n _vm._m(30)\n ])\n ])\n ]\n )\n : _vm._e()\n ]),\n _vm._v(\" \"),\n _vm.selectedMultiEpStyle\n ? _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(31),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\n \"select\",\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.selectedMultiEpStyle,\n expression: \"selectedMultiEpStyle\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: { id: \"naming_multi_ep\", name: \"naming_multi_ep\" },\n on: {\n change: [\n function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val = \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.selectedMultiEpStyle = $event.target.multiple\n ? $$selectedVal\n : $$selectedVal[0]\n },\n _vm.updatePatternSamples\n ],\n input: function($event) {\n _vm.update($event)\n }\n }\n },\n _vm._l(_vm.availableMultiEpStyles, function(multiEpStyle) {\n return _c(\n \"option\",\n {\n key: multiEpStyle.value,\n attrs: { id: \"multiEpStyle\" },\n domProps: { value: multiEpStyle.value }\n },\n [_vm._v(_vm._s(multiEpStyle.text))]\n )\n })\n )\n ])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group row\" }, [\n _c(\"h3\", { staticClass: \"col-sm-12\" }, [\n _vm._v(\"Single-EP Sample:\")\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"example col-sm-12\" }, [\n _c(\n \"span\",\n { staticClass: \"jumbo\", attrs: { id: \"naming_example\" } },\n [_vm._v(_vm._s(_vm.namingExample))]\n )\n ])\n ]),\n _vm._v(\" \"),\n _vm.isMulti\n ? _c(\"div\", { staticClass: \"form-group row\" }, [\n _c(\"h3\", { staticClass: \"col-sm-12\" }, [\n _vm._v(\"Multi-EP sample:\")\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"example col-sm-12\" }, [\n _c(\n \"span\",\n {\n staticClass: \"jumbo\",\n attrs: { id: \"naming_example_multi\" }\n },\n [_vm._v(_vm._s(_vm.namingExampleMulti))]\n )\n ])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _vm.animeType > 0\n ? _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(32),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.animeType,\n expression: \"animeType\"\n }\n ],\n attrs: {\n type: \"radio\",\n name: \"naming_anime\",\n id: \"naming_anime\",\n value: \"1\"\n },\n domProps: { checked: _vm._q(_vm.animeType, \"1\") },\n on: {\n change: [\n function($event) {\n _vm.animeType = \"1\"\n },\n _vm.updatePatternSamples\n ],\n input: function($event) {\n _vm.update()\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Add the absolute number to the season/episode format?\"\n )\n ]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"Only applies to animes. (e.g. S15E45 - 310 vs S15E45)\"\n )\n ])\n ])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _vm.animeType > 0\n ? _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(33),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.animeType,\n expression: \"animeType\"\n }\n ],\n attrs: {\n type: \"radio\",\n name: \"naming_anime\",\n id: \"naming_anime_only\",\n value: \"2\"\n },\n domProps: { checked: _vm._q(_vm.animeType, \"2\") },\n on: {\n change: [\n function($event) {\n _vm.animeType = \"2\"\n },\n _vm.updatePatternSamples\n ],\n input: function($event) {\n _vm.update()\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\"Replace season/episode format with absolute number\")\n ]),\n _vm._v(\" \"),\n _c(\"p\", [_vm._v(\"Only applies to animes.\")])\n ])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _vm.animeType > 0\n ? _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(34),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.animeType,\n expression: \"animeType\"\n }\n ],\n attrs: {\n type: \"radio\",\n name: \"naming_anime\",\n id: \"naming_anime_none\",\n value: \"3\"\n },\n domProps: { checked: _vm._q(_vm.animeType, \"3\") },\n on: {\n change: [\n function($event) {\n _vm.animeType = \"3\"\n },\n _vm.updatePatternSamples\n ],\n input: function($event) {\n _vm.update()\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [_vm._v(\"Don't include the absolute number\")]),\n _vm._v(\" \"),\n _c(\"p\", [_vm._v(\"Only applies to animes.\")])\n ])\n ])\n : _vm._e()\n ])\n : _vm._e()\n ])\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"name_presets\" } },\n [_c(\"span\", [_vm._v(\"Name Pattern:\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"label\", { staticClass: \"col-sm-2 control-label\" }, [\n _c(\"span\", [_vm._v(\" \")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"thead\", [\n _c(\"tr\", [\n _c(\"th\", { staticClass: \"align-right\" }, [_vm._v(\"Meaning\")]),\n _vm._v(\" \"),\n _c(\"th\", [_vm._v(\"Pattern\")]),\n _vm._v(\" \"),\n _c(\"th\", { attrs: { width: \"60%\" } }, [_vm._v(\"Result\")])\n ])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tfoot\", [\n _c(\"tr\", [\n _c(\"th\", { attrs: { colspan: \"3\" } }, [\n _vm._v(\n \"Use lower case if you want lower case names (eg. %sn, %e.n, %q_n etc)\"\n )\n ])\n ])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Show Name:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%SN\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Show Name\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%S.N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Show.Name\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%S_N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Show_Name\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Season Number:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%S\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"2\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%0S\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"02\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"XEM Season Number:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%XS\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"2\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%0XS\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"02\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Episode Number:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%E\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"3\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%0E\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"03\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"XEM Episode Number:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%XE\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"3\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%0XE\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"03\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Absolute Episode Number:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%AB\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"003\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Xem Absolute Episode Number:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%XAB\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"003\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Episode Name:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%EN\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Episode Name\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%E.N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Episode.Name\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%E_N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Episode_Name\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Air Date:\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Post-Processing Date:\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", { staticClass: \"align-right\" }, [_c(\"b\", [_vm._v(\"Quality:\")])]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%QN\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"720p BluRay\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%Q.N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"720p.BluRay\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%Q_N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"720p_BluRay\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"b\", [_vm._v(\"Scene Quality:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%SQN\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"720p HDTV x264\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%SQ.N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"720p.HDTV.x264\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", [_vm._v(\" \")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%SQ_N\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"720p_HDTV_x264\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-info-sign\",\n attrs: { title: \"Multi-EP style is ignored\" }\n }),\n _vm._v(\" \"),\n _c(\"b\", [_vm._v(\"Release Name:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%RN\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"Show.Name.S02E03.HDTV.x264-RLSGROUP\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-info-sign\",\n attrs: {\n title:\n \"UNKNOWN_RELEASE_GROUP is used in place of RLSGROUP if it could not be properly detected\"\n }\n }),\n _vm._v(\" \"),\n _c(\"b\", [_vm._v(\"Release Group:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%RG\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"RLSGROUP\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"even\" }, [\n _c(\"td\", { staticClass: \"align-right\" }, [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-info-sign\",\n attrs: { title: \"If episode is proper/repack add 'proper' to name.\" }\n }),\n _vm._v(\" \"),\n _c(\"b\", [_vm._v(\"Release Type:\")])\n ]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"%RT\")]),\n _vm._v(\" \"),\n _c(\"td\", [_vm._v(\"PROPER\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"naming_multi_ep\" }\n },\n [_c(\"span\", [_vm._v(\"Multi-Episode Style:\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"naming_anime\" } },\n [_c(\"span\", [_vm._v(\"Add Absolute Number\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"naming_anime_only\" }\n },\n [_c(\"span\", [_vm._v(\"Only Absolute Number\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"naming_anime_none\" }\n },\n [_c(\"span\", [_vm._v(\"No Absolute Number\")])]\n )\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./name-pattern.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./name-pattern.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./name-pattern.vue?vue&type=template&id=462c525e&\"\nimport script from \"./name-pattern.vue?vue&type=script&lang=js&\"\nexport * from \"./name-pattern.vue?vue&type=script&lang=js&\"\nimport style0 from \"./name-pattern.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"name-pattern.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"img\", {\n class: _vm.plotInfoClass,\n attrs: { src: \"images/info32.png\", width: \"16\", height: \"16\", alt: \"\" }\n })\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./plot-info.vue?vue&type=template&id=6b17b4d1&\"\nimport script from \"./plot-info.vue?vue&type=script&lang=js&\"\nexport * from \"./plot-info.vue?vue&type=script&lang=js&\"\nimport style0 from \"./plot-info.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"plot-info.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"span\",\n {\n class: _vm.override.class || [\"quality\", _vm.pill.class],\n attrs: { title: _vm.title }\n },\n [_vm._v(_vm._s(_vm.override.text || _vm.pill.text))]\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./quality-pill.vue?vue&type=template&id=b683ee7a&scoped=true&\"\nimport script from \"./quality-pill.vue?vue&type=script&lang=js&\"\nexport * from \"./quality-pill.vue?vue&type=script&lang=js&\"\nimport style0 from \"./quality-pill.vue?vue&type=style&index=0&id=b683ee7a&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"b683ee7a\",\n null\n \n)\n\ncomponent.options.__file = \"quality-pill.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"scroll-buttons-wrapper\" } }, [\n _c(\n \"div\",\n {\n staticClass: \"scroll-wrapper top\",\n class: { show: _vm.showToTop },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.scrollTop($event)\n }\n }\n },\n [_vm._m(0)]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n {\n staticClass: \"scroll-wrapper left\",\n class: { show: _vm.showLeftRight }\n },\n [\n _c(\"span\", { staticClass: \"scroll-left-inner\" }, [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-circle-arrow-left\",\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.scrollLeft($event)\n }\n }\n })\n ])\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n {\n staticClass: \"scroll-wrapper right\",\n class: { show: _vm.showLeftRight }\n },\n [\n _c(\"span\", { staticClass: \"scroll-right-inner\" }, [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-circle-arrow-right\",\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.scrollRight($event)\n }\n }\n })\n ])\n ]\n )\n ])\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"span\", { staticClass: \"scroll-top-inner\" }, [\n _c(\"i\", { staticClass: \"glyphicon glyphicon-circle-arrow-up\" })\n ])\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./scroll-buttons.vue?vue&type=template&id=96ee7e7e&\"\nimport script from \"./scroll-buttons.vue?vue&type=script&lang=js&\"\nexport * from \"./scroll-buttons.vue?vue&type=script&lang=js&\"\nimport style0 from \"./scroll-buttons.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"scroll-buttons.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n _vm._b(\n { staticClass: \"select-list max-width\" },\n \"div\",\n { disabled: _vm.disabled },\n false\n ),\n [\n _c(\"i\", {\n staticClass: \"switch-input glyphicon glyphicon-refresh\",\n attrs: { title: \"Switch between a list and comma separated values\" },\n on: {\n click: function($event) {\n _vm.switchFields()\n }\n }\n }),\n _vm._v(\" \"),\n !_vm.csvMode\n ? _c(\n \"ul\",\n [\n _vm._l(_vm.editItems, function(item) {\n return _c(\"li\", { key: item.id }, [\n _c(\"div\", { staticClass: \"input-group\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: item.value,\n expression: \"item.value\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: { type: \"text\" },\n domProps: { value: item.value },\n on: {\n input: [\n function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.$set(item, \"value\", $event.target.value)\n },\n function($event) {\n _vm.removeEmpty(item)\n }\n ]\n }\n }),\n _vm._v(\" \"),\n _c(\n \"div\",\n {\n staticClass: \"input-group-btn\",\n on: {\n click: function($event) {\n _vm.deleteItem(item)\n }\n }\n },\n [_vm._m(0, true)]\n )\n ])\n ])\n }),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"new-item\" }, [\n _c(\"div\", { staticClass: \"input-group\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.newItem,\n expression: \"newItem\"\n }\n ],\n ref: \"newItemInput\",\n staticClass: \"form-control input-sm\",\n attrs: {\n type: \"text\",\n placeholder: \"add new values per line\"\n },\n domProps: { value: _vm.newItem },\n on: {\n input: function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.newItem = $event.target.value\n }\n }\n }),\n _vm._v(\" \"),\n _c(\n \"div\",\n {\n staticClass: \"input-group-btn\",\n on: {\n click: function($event) {\n _vm.addNewItem()\n }\n }\n },\n [_vm._m(1)]\n )\n ])\n ]),\n _vm._v(\" \"),\n _vm.newItem.length > 0\n ? _c(\"div\", { staticClass: \"new-item-help\" }, [\n _vm._v(\"\\n Click \"),\n _c(\"i\", { staticClass: \"glyphicon glyphicon-plus\" }),\n _vm._v(\" to finish adding the value.\\n \")\n ])\n : _vm._e()\n ],\n 2\n )\n : _c(\"div\", { staticClass: \"csv\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.csv,\n expression: \"csv\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: {\n type: \"text\",\n placeholder: \"add values comma separated\"\n },\n domProps: { value: _vm.csv },\n on: {\n input: function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.csv = $event.target.value\n }\n }\n })\n ])\n ]\n )\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n {\n staticClass: \"btn btn-default input-sm\",\n staticStyle: { \"font-size\": \"14px\" }\n },\n [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-remove\",\n attrs: { title: \"Remove\" }\n })\n ]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n {\n staticClass: \"btn btn-default input-sm\",\n staticStyle: { \"font-size\": \"14px\" }\n },\n [\n _c(\"i\", {\n staticClass: \"glyphicon glyphicon-plus\",\n attrs: { title: \"Add\" }\n })\n ]\n )\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./select-list.vue?vue&type=template&id=391728a9&scoped=true&\"\nimport script from \"./select-list.vue?vue&type=script&lang=js&\"\nexport * from \"./select-list.vue?vue&type=script&lang=js&\"\nimport style0 from \"./select-list.vue?vue&type=style&index=0&id=391728a9&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"391728a9\",\n null\n \n)\n\ncomponent.options.__file = \"select-list.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _vm.shows.length === 0\n ? _c(\"span\", [_vm._v(\"Loading...\")])\n : _c(\"div\", { staticClass: \"show-selector form-inline hidden-print\" }, [\n _c(\n \"div\",\n { staticClass: \"select-show-group pull-left top-5 bottom-5\" },\n [\n _c(\n \"select\",\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.selectedShowSlug,\n expression: \"selectedShowSlug\"\n }\n ],\n class: _vm.selectClass,\n on: {\n change: [\n function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val = \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.selectedShowSlug = $event.target.multiple\n ? $$selectedVal\n : $$selectedVal[0]\n },\n function($event) {\n _vm.$emit(\"change\", _vm.selectedShowSlug)\n }\n ]\n }\n },\n [\n _vm.placeholder\n ? _c(\n \"option\",\n {\n attrs: { disabled: \"\", hidden: \"\" },\n domProps: {\n value: _vm.placeholder,\n selected: !_vm.selectedShowSlug\n }\n },\n [_vm._v(_vm._s(_vm.placeholder))]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _vm.whichList === -1\n ? _vm._l(_vm.showLists, function(curShowList) {\n return _c(\n \"optgroup\",\n {\n key: curShowList.type,\n attrs: { label: curShowList.type }\n },\n _vm._l(curShowList.shows, function(show) {\n return _c(\n \"option\",\n {\n key: show.id.slug,\n domProps: { value: show.id.slug }\n },\n [_vm._v(_vm._s(show.title))]\n )\n })\n )\n })\n : _vm._l(_vm.showLists[_vm.whichList].shows, function(show) {\n return _c(\n \"option\",\n {\n key: show.id.slug,\n domProps: { value: show.id.slug }\n },\n [_vm._v(_vm._s(show.title))]\n )\n })\n ],\n 2\n )\n ]\n )\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./show-selector.vue?vue&type=template&id=8ca36d42&\"\nimport script from \"./show-selector.vue?vue&type=script&lang=js&\"\nexport * from \"./show-selector.vue?vue&type=script&lang=js&\"\nimport style0 from \"./show-selector.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"show-selector.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"img\",\n _vm._b(\n { attrs: { height: \"16\", width: \"16\" } },\n \"img\",\n { src: _vm.src, alt: _vm.alt },\n false\n )\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./state-switch.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./state-switch.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./state-switch.vue?vue&type=template&id=676026e5&\"\nimport script from \"./state-switch.vue?vue&type=script&lang=js&\"\nexport * from \"./state-switch.vue?vue&type=script&lang=js&\"\nimport style0 from \"./state-switch.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"state-switch.vue\"\nexport default component.exports","export { default as AppLink } from './app-link.vue';\nexport { default as Asset } from './asset.vue';\nexport { default as ConfigTemplate } from './config-template.vue';\nexport { default as ConfigTextboxNumber } from './config-textbox-number.vue';\nexport { default as ConfigTextbox } from './config-textbox.vue';\nexport { default as ConfigToggleSlider } from './config-toggle-slider.vue';\nexport { default as FileBrowser } from './file-browser.vue';\nexport { default as LanguageSelect } from './language-select.vue';\nexport { default as NamePattern } from './name-pattern.vue';\nexport { default as PlotInfo } from './plot-info.vue';\nexport { default as QualityPill } from './quality-pill.vue';\nexport { default as ScrollButtons } from './scroll-buttons.vue';\nexport { default as SelectList } from './select-list.vue';\nexport { default as ShowSelector } from './show-selector.vue';\nexport { default as StateSwitch } from './state-switch.vue';\n","const isDevelopment = process.env.NODE_ENV === 'development';\n\n/**\n * Calculate the combined value of the selected qualities.\n * @param {number[]} allowedQualities - Array of allowed qualities.\n * @param {number[]} preferredQualities - Array of preferred qualities.\n * @returns {number} - An unsigned integer.\n */\nconst combineQualities = (allowedQualities, preferredQualities) => {\n const reducer = (accumulator, currentValue) => accumulator | currentValue;\n const allowed = allowedQualities.reduce(reducer, 0);\n const preferred = preferredQualities.reduce(reducer, 0);\n\n return (allowed | (preferred << 16)) >>> 0; // Unsigned int\n};\n\nexport {\n combineQualities,\n isDevelopment\n};\n","import VueRouter from 'vue-router';\n\nconst AddRecommended = () => import('./components/add-recommended.vue');\nconst AddShows = () => import('./components/add-shows.vue');\nconst Config = () => import('./components/config.vue');\nconst ConfigPostProcessing = () => import('./components/config-post-processing.vue');\nconst IRC = () => import('./components/irc.vue');\nconst Login = () => import('./components/login.vue');\nconst NotFound = () => import('./components/http/404.vue');\n\nconst homeRoutes = [{\n path: '/home',\n name: 'home',\n meta: {\n title: 'Home',\n header: 'Show List',\n topMenu: 'home'\n }\n}, {\n path: '/home/editShow',\n name: 'editShow',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/home/displayShow',\n name: 'show',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/home/snatchSelection',\n name: 'snatchSelection',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/home/testRename',\n name: 'testRename',\n meta: {\n title: 'Preview Rename',\n header: 'Preview Rename',\n topMenu: 'home'\n }\n}, {\n path: '/home/postprocess',\n name: 'postprocess',\n meta: {\n title: 'Manual Post-Processing',\n header: 'Manual Post-Processing',\n topMenu: 'home'\n }\n}, {\n path: '/home/status',\n name: 'status',\n meta: {\n title: 'Status',\n topMenu: 'system'\n }\n}, {\n path: '/home/restart',\n name: 'restart',\n meta: {\n title: 'Restarting...',\n header: 'Performing Restart',\n topMenu: 'system'\n }\n}, {\n path: '/home/shutdown',\n name: 'shutdown',\n meta: {\n header: 'Shutting down',\n topMenu: 'system'\n }\n}, {\n path: '/home/update',\n name: 'update',\n meta: {\n topMenu: 'system'\n }\n}];\n\nconst configRoutes = [{\n path: '/config',\n name: 'config',\n meta: {\n title: 'Help & Info',\n header: 'Medusa Configuration',\n topMenu: 'config',\n converted: true\n },\n component: Config\n}, {\n path: '/config/anime',\n name: 'configAnime',\n meta: {\n title: 'Config - Anime',\n header: 'Anime',\n topMenu: 'config'\n }\n}, {\n path: '/config/backuprestore',\n name: 'configBackupRestore',\n meta: {\n title: 'Config - Backup/Restore',\n header: 'Backup/Restore',\n topMenu: 'config'\n }\n}, {\n path: '/config/general',\n name: 'configGeneral',\n meta: {\n title: 'Config - General',\n header: 'General Configuration',\n topMenu: 'config'\n }\n}, {\n path: '/config/notifications',\n name: 'configNotifications',\n meta: {\n title: 'Config - Notifications',\n header: 'Notifications',\n topMenu: 'config'\n }\n}, {\n path: '/config/postProcessing',\n name: 'configPostProcessing',\n meta: {\n title: 'Config - Post Processing',\n header: 'Post Processing',\n topMenu: 'config'\n },\n component: ConfigPostProcessing\n}, {\n path: '/config/providers',\n name: 'configSearchProviders',\n meta: {\n title: 'Config - Providers',\n header: 'Search Providers',\n topMenu: 'config'\n }\n}, {\n path: '/config/search',\n name: 'configSearchSettings',\n meta: {\n title: 'Config - Episode Search',\n header: 'Search Settings',\n topMenu: 'config'\n }\n}, {\n path: '/config/subtitles',\n name: 'configSubtitles',\n meta: {\n title: 'Config - Subtitles',\n header: 'Subtitles',\n topMenu: 'config'\n }\n}];\n\nconst addShowRoutes = [{\n path: '/addShows',\n name: 'addShows',\n meta: {\n title: 'Add Shows',\n header: 'Add Shows',\n topMenu: 'home',\n converted: true\n },\n component: AddShows\n}, {\n path: '/addShows/addExistingShows',\n name: 'addExistingShows',\n meta: {\n title: 'Add Existing Shows',\n header: 'Add Existing Shows',\n topMenu: 'home'\n }\n}, {\n path: '/addShows/newShow',\n name: 'addNewShow',\n meta: {\n title: 'Add New Show',\n header: 'Add New Show',\n topMenu: 'home'\n }\n}, {\n path: '/addShows/trendingShows',\n name: 'addTrendingShows',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/addShows/popularShows',\n name: 'addPopularShows',\n meta: {\n title: 'Popular Shows',\n header: 'Popular Shows',\n topMenu: 'home'\n }\n}, {\n path: '/addShows/popularAnime',\n name: 'addPopularAnime',\n meta: {\n title: 'Popular Anime Shows',\n header: 'Popular Anime Shows',\n topMenu: 'home'\n }\n}];\n\nconst loginRoute = {\n path: '/login',\n name: 'login',\n meta: {\n title: 'Login'\n },\n component: Login\n};\n\nconst addRecommendedRoute = {\n path: '/addRecommended',\n name: 'addRecommended',\n meta: {\n title: 'Add Recommended Shows',\n header: 'Add Recommended Shows',\n topMenu: 'home'\n },\n component: AddRecommended\n};\n\nconst scheduleRoute = {\n path: '/schedule',\n name: 'schedule',\n meta: {\n title: 'Schedule',\n header: 'Schedule',\n topMenu: 'schedule'\n }\n};\n\nconst historyRoute = {\n path: '/history',\n name: 'history',\n meta: {\n title: 'History',\n header: 'History',\n topMenu: 'history'\n }\n};\n\nconst manageRoutes = [{\n path: '/manage',\n name: 'manage',\n meta: {\n title: 'Mass Update',\n header: 'Mass Update',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/backlogOverview',\n name: 'manageBacklogOverview',\n meta: {\n title: 'Backlog Overview',\n header: 'Backlog Overview',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/episodeStatuses',\n name: 'manageEpisodeOverview',\n meta: {\n title: 'Episode Overview',\n header: 'Episode Overview',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/failedDownloads',\n name: 'manageFailedDownloads',\n meta: {\n title: 'Failed Downloads',\n header: 'Failed Downlaods',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/manageSearches',\n name: 'manageManageSearches',\n meta: {\n title: 'Manage Searches',\n header: 'Manage Searches',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/massEdit',\n name: 'manageMassEdit',\n meta: {\n title: 'Mass Edit',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/subtitleMissed',\n name: 'manageSubtitleMissed',\n meta: {\n title: 'Missing Subtitles',\n header: 'Missing Subtitles',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/subtitleMissedPP',\n name: 'manageSubtitleMissedPP',\n meta: {\n title: 'Missing Subtitles in Post-Process folder',\n header: 'Missing Subtitles in Post-Process folder',\n topMenu: 'manage'\n }\n}];\n\nconst errorLogsRoutes = [{\n path: '/errorlogs',\n name: 'errorlogs',\n meta: {\n title: 'Logs & Errors',\n topMenu: 'system'\n }\n}, {\n path: '/errorlogs/viewlog',\n name: 'viewlog',\n meta: {\n title: 'Logs',\n header: 'Log File',\n topMenu: 'system'\n }\n}];\n\nconst newsRoute = {\n path: '/news',\n name: 'news',\n meta: {\n title: 'News',\n header: 'News',\n topMenu: 'system'\n }\n};\n\nconst changesRoute = {\n path: '/changes',\n name: 'changes',\n meta: {\n title: 'Changelog',\n header: 'Changelog',\n topMenu: 'system'\n }\n};\n\nconst ircRoute = {\n path: '/IRC',\n name: 'IRC',\n meta: {\n title: 'IRC',\n topMenu: 'system'\n },\n component: IRC\n};\n\nconst notFoundRoute = {\n path: '/not-found',\n name: 'not-found',\n meta: {\n title: '404',\n header: '404 - page not found'\n },\n component: NotFound\n};\n\n// @NOTE: Redirect can only be added once all routes are vue\n/*\nconst notFoundRedirect = {\n path: '*',\n redirect: '/not-found'\n};\n*/\n\nconst routes = [\n ...homeRoutes,\n ...configRoutes,\n ...addShowRoutes,\n loginRoute,\n addRecommendedRoute,\n scheduleRoute,\n historyRoute,\n ...manageRoutes,\n ...errorLogsRoutes,\n newsRoute,\n changesRoute,\n ircRoute,\n notFoundRoute\n];\n\nconst router = new VueRouter({\n base: document.body.getAttribute('web-root') + '/',\n mode: 'history',\n routes\n});\n\nrouter.beforeEach((to, from, next) => {\n const { meta } = to;\n const { title } = meta;\n\n // If there's no title then it's not a .vue route\n // or it's handling its own title\n if (title) {\n document.title = `${title} | Medusa`;\n }\n\n // Always call next otherwise the will be empty\n next();\n});\n\nexport default router;\n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./404.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./404.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./404.vue?vue&type=template&id=a851d9c2&\"\nimport script from \"./404.vue?vue&type=script&lang=js&\"\nexport * from \"./404.vue?vue&type=script&lang=js&\"\nimport style0 from \"./404.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"404.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { attrs: { id: \"addShowPortal\" } },\n [\n _c(\n \"app-link\",\n {\n staticClass: \"btn-medusa btn-large\",\n attrs: {\n href: \"addShows/trendingShows/?traktList=anticipated\",\n id: \"btnNewShow\"\n }\n },\n [\n _c(\"div\", { staticClass: \"button\" }, [\n _c(\"div\", { staticClass: \"add-list-icon-addtrakt\" })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"buttontext\" }, [\n _c(\"h3\", [_vm._v(\"Add From Trakt Lists\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"For shows that you haven't downloaded yet, this option lets you choose from a show from one of the Trakt lists to add to Medusa .\"\n )\n ])\n ])\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"app-link\",\n {\n staticClass: \"btn-medusa btn-large\",\n attrs: { href: \"addShows/popularShows/\", id: \"btnNewShow\" }\n },\n [\n _c(\"div\", { staticClass: \"button\" }, [\n _c(\"div\", { staticClass: \"add-list-icon-addimdb\" })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"buttontext\" }, [\n _c(\"h3\", [_vm._v(\"Add From IMDB's Popular Shows\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"View IMDB's list of the most popular shows. This feature uses IMDB's MOVIEMeter algorithm to identify popular TV Shows.\"\n )\n ])\n ])\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"app-link\",\n {\n staticClass: \"btn-medusa btn-large\",\n attrs: { href: \"addShows/popularAnime/\", id: \"btnNewShow\" }\n },\n [\n _c(\"div\", { staticClass: \"button\" }, [\n _c(\"div\", { staticClass: \"add-list-icon-addanime\" })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"buttontext\" }, [\n _c(\"h3\", [_vm._v(\"Add From Anidb's Hot Anime list\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n 'View Anidb\\'s list of the most popular anime shows. Anidb provides lists for Popular Anime, using the \"Hot Anime\" list.'\n )\n ])\n ])\n ]\n )\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-recommended.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-recommended.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./add-recommended.vue?vue&type=template&id=a2186b24&\"\nimport script from \"./add-recommended.vue?vue&type=script&lang=js&\"\nexport * from \"./add-recommended.vue?vue&type=script&lang=js&\"\nimport style0 from \"./add-recommended.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"add-recommended.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _vm._m(0)\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { staticClass: \"login\" }, [\n _c(\"form\", { attrs: { action: \"\", method: \"post\" } }, [\n _c(\"h1\", [_vm._v(\"Medusa\")]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"ctrlHolder\" }, [\n _c(\"input\", {\n staticClass: \"inlay\",\n attrs: {\n name: \"username\",\n type: \"text\",\n placeholder: \"Username\",\n autocomplete: \"off\"\n }\n })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"ctrlHolder\" }, [\n _c(\"input\", {\n staticClass: \"inlay\",\n attrs: {\n name: \"password\",\n type: \"password\",\n placeholder: \"Password\",\n autocomplete: \"off\"\n }\n })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"ctrlHolder\" }, [\n _c(\n \"label\",\n { staticClass: \"remember_me\", attrs: { title: \"for 30 days\" } },\n [\n _c(\"input\", {\n staticClass: \"inlay\",\n attrs: {\n id: \"remember_me\",\n name: \"remember_me\",\n type: \"checkbox\",\n value: \"1\",\n checked: \"checked\"\n }\n }),\n _vm._v(\" Remember me\")\n ]\n ),\n _vm._v(\" \"),\n _c(\"input\", {\n staticClass: \"button\",\n attrs: { name: \"submit\", type: \"submit\", value: \"Login\" }\n })\n ])\n ])\n ])\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./login.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./login.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./login.vue?vue&type=template&id=013dd286&\"\nimport script from \"./login.vue?vue&type=script&lang=js&\"\nexport * from \"./login.vue?vue&type=script&lang=js&\"\nimport style0 from \"./login.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"login.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"config-content\" } }, [\n _c(\n \"table\",\n {\n staticClass: \"infoTable\",\n attrs: {\n cellspacing: \"1\",\n border: \"0\",\n cellpadding: \"0\",\n width: \"100%\"\n }\n },\n [\n _c(\"tr\", [\n _vm._m(0),\n _vm._v(\" \"),\n _c(\"td\", [\n _vm._v(\"\\n Branch:\\n \"),\n _vm.config.branch\n ? _c(\n \"span\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href:\n _vm.config.sourceUrl + \"/tree/\" + _vm.config.branch\n }\n },\n [_vm._v(_vm._s(_vm.config.branch))]\n )\n ],\n 1\n )\n : _c(\"span\", [_vm._v(\"Unknown\")]),\n _vm._v(\" \"),\n _c(\"br\"),\n _vm._v(\"\\n Commit:\\n \"),\n _vm.config.commitHash\n ? _c(\n \"span\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href:\n _vm.config.sourceUrl +\n \"/commit/\" +\n _vm.config.commitHash\n }\n },\n [_vm._v(_vm._s(_vm.config.commitHash))]\n )\n ],\n 1\n )\n : _c(\"span\", [_vm._v(\"Unknown\")]),\n _vm._v(\" \"),\n _c(\"br\"),\n _vm._v(\"\\n Version:\\n \"),\n _vm.config.release\n ? _c(\n \"span\",\n [\n _c(\n \"app-link\",\n {\n attrs: {\n href:\n _vm.config.sourceUrl +\n \"/releases/tag/\" +\n _vm.config.release\n }\n },\n [_vm._v(_vm._s(_vm.config.release))]\n )\n ],\n 1\n )\n : _c(\"span\", [_vm._v(\"Unknown\")]),\n _vm._v(\" \"),\n _c(\"br\"),\n _vm._v(\"\\n Database:\\n \"),\n _vm.config.databaseVersion\n ? _c(\"span\", [\n _vm._v(\n _vm._s(_vm.config.databaseVersion.major) +\n \".\" +\n _vm._s(_vm.config.databaseVersion.minor)\n )\n ])\n : _c(\"span\", [_vm._v(\"Unknown\")])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(1),\n _c(\"td\", [_vm._v(_vm._s(_vm.config.pythonVersion))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(2),\n _c(\"td\", [_vm._v(_vm._s(_vm.config.sslVersion))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [_vm._m(3), _c(\"td\", [_vm._v(_vm._s(_vm.config.os))])]),\n _vm._v(\" \"),\n _c(\"tr\", [_vm._m(4), _c(\"td\", [_vm._v(_vm._s(_vm.config.locale))])]),\n _vm._v(\" \"),\n _vm._m(5),\n _vm._v(\" \"),\n _vm._m(6),\n _vm._v(\" \"),\n _c(\"tr\", [_vm._m(7), _c(\"td\", [_vm._v(_vm._s(_vm.config.localUser))])]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(8),\n _c(\"td\", [_vm._v(_vm._s(_vm.config.programDir))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(9),\n _c(\"td\", [_vm._v(_vm._s(_vm.config.configFile))])\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [_vm._m(10), _c(\"td\", [_vm._v(_vm._s(_vm.config.dbPath))])]),\n _vm._v(\" \"),\n _c(\"tr\", [_vm._m(11), _c(\"td\", [_vm._v(_vm._s(_vm.config.cacheDir))])]),\n _vm._v(\" \"),\n _c(\"tr\", [_vm._m(12), _c(\"td\", [_vm._v(_vm._s(_vm.config.logDir))])]),\n _vm._v(\" \"),\n _vm.config.appArgs\n ? _c(\"tr\", [\n _vm._m(13),\n _c(\"td\", [\n _c(\"pre\", [\n _vm._v(_vm._s(_vm._f(\"prettyPrintJSON\")(_vm.config.appArgs)))\n ])\n ])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _vm.config.webRoot\n ? _c(\"tr\", [\n _vm._m(14),\n _c(\"td\", [_vm._v(_vm._s(_vm.config.webRoot))])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _vm.config.runsInDocker\n ? _c(\"tr\", [\n _vm._m(15),\n _c(\"td\", [_vm._v(_vm._s(_vm.config.runsInDocker ? \"yes\" : \"no\"))])\n ])\n : _vm._e(),\n _vm._v(\" \"),\n _vm._m(16),\n _vm._v(\" \"),\n _vm._m(17),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(18),\n _c(\n \"td\",\n [\n _c(\"app-link\", { attrs: { href: _vm.config.githubUrl } }, [\n _vm._v(_vm._s(_vm.config.githubUrl))\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(19),\n _c(\n \"td\",\n [\n _c(\"app-link\", { attrs: { href: _vm.config.wikiUrl } }, [\n _vm._v(_vm._s(_vm.config.wikiUrl))\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(20),\n _c(\n \"td\",\n [\n _c(\"app-link\", { attrs: { href: _vm.config.sourceUrl } }, [\n _vm._v(_vm._s(_vm.config.sourceUrl))\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"tr\", [\n _vm._m(21),\n _c(\n \"td\",\n [\n _c(\n \"app-link\",\n { attrs: { href: \"irc://irc.freenode.net/#pymedusa\" } },\n [\n _c(\"i\", [_vm._v(\"#pymedusa\")]),\n _vm._v(\" on \"),\n _c(\"i\", [_vm._v(\"irc.freenode.net\")])\n ]\n )\n ],\n 1\n )\n ])\n ]\n )\n ])\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-application\" }),\n _vm._v(\" Medusa Info:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-python\" }),\n _vm._v(\" Python Version:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-ssl\" }),\n _vm._v(\" SSL Version:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-os\" }),\n _vm._v(\" OS:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-locale\" }),\n _vm._v(\" Locale:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [_c(\"td\", [_vm._v(\" \")]), _c(\"td\", [_vm._v(\" \")])])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"infoTableSeperator\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _c(\"td\", [_vm._v(\" \")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-user\" }),\n _vm._v(\" User:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-dir\" }),\n _vm._v(\" Program Folder:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-config\" }),\n _vm._v(\" Config File:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-db\" }),\n _vm._v(\" Database File:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-cache\" }),\n _vm._v(\" Cache Folder:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-log\" }),\n _vm._v(\" Log Folder:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-arguments\" }),\n _vm._v(\" Arguments:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-dir\" }),\n _vm._v(\" Web Root:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-docker\" }),\n _vm._v(\" Runs in docker:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", [_c(\"td\", [_vm._v(\" \")]), _c(\"td\", [_vm._v(\" \")])])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"tr\", { staticClass: \"infoTableSeperator\" }, [\n _c(\"td\", [_vm._v(\" \")]),\n _c(\"td\", [_vm._v(\" \")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-web\" }),\n _vm._v(\" Website:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-wiki\" }),\n _vm._v(\" Wiki:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-github\" }),\n _vm._v(\" Source:\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"td\", [\n _c(\"i\", { staticClass: \"icon16-config-mirc\" }),\n _vm._v(\" IRC Chat:\")\n ])\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./config.vue?vue&type=template&id=2ad9ae57&\"\nimport script from \"./config.vue?vue&type=script&lang=js&\"\nexport * from \"./config.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"config.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { attrs: { id: \"addShowPortal\" } },\n [\n _c(\n \"app-link\",\n {\n staticClass: \"btn-medusa btn-large\",\n attrs: { href: \"addShows/newShow/\", id: \"btnNewShow\" }\n },\n [\n _c(\"div\", { staticClass: \"button\" }, [\n _c(\"div\", { staticClass: \"add-list-icon-addnewshow\" })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"buttontext\" }, [\n _c(\"h3\", [_vm._v(\"Add New Show\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"For shows that you haven't downloaded yet, this option finds a show on your preferred indexer, creates a directory for it's episodes, and adds it to Medusa.\"\n )\n ])\n ])\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"app-link\",\n {\n staticClass: \"btn-medusa btn-large\",\n attrs: { href: \"addShows/existingShows/\", id: \"btnExistingShow\" }\n },\n [\n _c(\"div\", { staticClass: \"button\" }, [\n _c(\"div\", { staticClass: \"add-list-icon-addexistingshow\" })\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"buttontext\" }, [\n _c(\"h3\", [_vm._v(\"Add Existing Shows\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"Use this option to add shows that already have a folder created on your hard drive. Medusa will scan your existing metadata/episodes and add the show accordingly.\"\n )\n ])\n ])\n ]\n )\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-shows.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-shows.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./add-shows.vue?vue&type=template&id=4812b86a&\"\nimport script from \"./add-shows.vue?vue&type=script&lang=js&\"\nexport * from \"./add-shows.vue?vue&type=script&lang=js&\"\nimport style0 from \"./add-shows.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"add-shows.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"iframe\", {\n staticClass: \"irc-frame loading-spinner\",\n attrs: { src: _vm.frameSrc }\n })\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./irc.vue?vue&type=template&id=60f89f30&scoped=true&\"\nimport script from \"./irc.vue?vue&type=script&lang=js&\"\nexport * from \"./irc.vue?vue&type=script&lang=js&\"\nimport style0 from \"./irc.vue?vue&type=style&index=0&id=60f89f30&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"60f89f30\",\n null\n \n)\n\ncomponent.options.__file = \"irc.vue\"\nexport default component.exports","var render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"config\" } }, [\n _c(\"div\", { attrs: { id: \"config-content\" } }, [\n _c(\n \"form\",\n {\n staticClass: \"form-horizontal\",\n attrs: { id: \"configForm\" },\n on: {\n submit: function($event) {\n $event.preventDefault()\n _vm.save()\n }\n }\n },\n [\n _c(\"div\", { attrs: { id: \"config-components\" } }, [\n _c(\"ul\", [\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"#post-processing\" } }, [\n _vm._v(\"Post Processing\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"#episode-naming\" } }, [\n _vm._v(\"Episode Naming\")\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"li\",\n [\n _c(\"app-link\", { attrs: { href: \"#metadata\" } }, [\n _vm._v(\"Metadata\")\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { attrs: { id: \"post-processing\" } }, [\n _c(\"div\", { staticClass: \"row component-group\" }, [\n _vm._m(0),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-xs-12 col-md-10\" }, [\n _c(\"fieldset\", { staticClass: \"component-group-list\" }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(1),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"process_automatically\",\n name: \"process_automatically\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.processAutomatically,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"processAutomatically\",\n $$v\n )\n },\n expression: \"postProcessing.processAutomatically\"\n }\n }),\n _vm._v(\" \"),\n _vm._m(2),\n _vm._v(\" \"),\n _vm._m(3)\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\n \"div\",\n {\n directives: [\n {\n name: \"show\",\n rawName: \"v-show\",\n value: _vm.postProcessing.processAutomatically,\n expression: \"postProcessing.processAutomatically\"\n }\n ],\n attrs: { id: \"post-process-toggle-wrapper\" }\n },\n [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(4),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"file-browser\", {\n attrs: {\n id: \"tv_download_dir\",\n name: \"tv_download_dir\",\n title: \"Select series download location\",\n \"initial-dir\":\n _vm.postProcessing.showDownloadDir\n },\n on: {\n update: function($event) {\n _vm.postProcessing.showDownloadDir = $event\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", { staticClass: \"clear-left\" }, [\n _vm._v(\n \"The folder where your download client puts the completed TV downloads.\"\n )\n ]),\n _vm._v(\" \"),\n _vm._m(5)\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(6),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\n \"select\",\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.postProcessing.processMethod,\n expression: \"postProcessing.processMethod\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: {\n id: \"naming_multi_ep\",\n name: \"naming_multi_ep\"\n },\n on: {\n change: function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val =\n \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.$set(\n _vm.postProcessing,\n \"processMethod\",\n $event.target.multiple\n ? $$selectedVal\n : $$selectedVal[0]\n )\n }\n }\n },\n _vm._l(_vm.processMethods, function(option) {\n return _c(\n \"option\",\n {\n key: option.value,\n domProps: { value: option.value }\n },\n [_vm._v(_vm._s(option.text))]\n )\n })\n ),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"What method should be used to put files into the library?\"\n )\n ]),\n _vm._v(\" \"),\n _vm._m(7),\n _vm._v(\" \"),\n _vm.postProcessing.processMethod == \"reflink\"\n ? _c(\n \"p\",\n [\n _vm._v(\"To use reference linking, the \"),\n _c(\n \"app-link\",\n {\n attrs: {\n href:\n \"http://www.dereferer.org/?https://pypi.python.org/pypi/reflink/0.1.4\"\n }\n },\n [_vm._v(\"reflink package\")]\n ),\n _vm._v(\" needs to be installed.\")\n ],\n 1\n )\n : _vm._e()\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(8),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model.number\",\n value:\n _vm.postProcessing\n .autoPostprocessorFrequency,\n expression:\n \"postProcessing.autoPostprocessorFrequency\",\n modifiers: { number: true }\n }\n ],\n staticClass: \"form-control input-sm input75\",\n attrs: {\n type: \"number\",\n min: \"10\",\n step: \"1\",\n name: \"autopostprocessor_frequency\",\n id: \"autopostprocessor_frequency\"\n },\n domProps: {\n value:\n _vm.postProcessing.autoPostprocessorFrequency\n },\n on: {\n input: function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.$set(\n _vm.postProcessing,\n \"autoPostprocessorFrequency\",\n _vm._n($event.target.value)\n )\n },\n blur: function($event) {\n _vm.$forceUpdate()\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Time in minutes to check for new files to auto post-process (min 10)\"\n )\n ])\n ])\n ])\n ]\n )\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"row component-group\" }, [\n _vm._m(9),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-xs-12 col-md-10\" }, [\n _c(\"fieldset\", { staticClass: \"component-group-list\" }, [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(10),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"postpone_if_sync_files\",\n name: \"postpone_if_sync_files\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.postponeIfSyncFiles,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"postponeIfSyncFiles\",\n $$v\n )\n },\n expression: \"postProcessing.postponeIfSyncFiles\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Wait to process a folder if sync files are present.\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(11),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"select-list\", {\n attrs: {\n name: \"sync_files\",\n id: \"sync_files\",\n \"csv-enabled\": \"\",\n \"list-items\": _vm.postProcessing.syncFiles\n },\n on: { change: _vm.onChangeSyncFiles }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"comma seperated list of extensions or filename globs Medusa ignores when Post Processing\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(12),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"postpone_if_no_subs\",\n name: \"postpone_if_no_subs\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.postponeIfNoSubs,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"postponeIfNoSubs\",\n $$v\n )\n },\n expression: \"postProcessing.postponeIfNoSubs\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Wait to process a file until subtitles are present\"\n )\n ]),\n _c(\"br\"),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Language names are allowed in subtitle filename (en.srt, pt-br.srt, ita.srt, etc.)\"\n )\n ]),\n _c(\"br\"),\n _vm._v(\" \"),\n _vm._m(13),\n _c(\"br\"),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"If you have any active show with subtitle search disabled, you must enable Automatic post processor.\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(14),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"rename_episodes\",\n name: \"rename_episodes\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.renameEpisodes,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"renameEpisodes\",\n $$v\n )\n },\n expression: \"postProcessing.renameEpisodes\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Rename episode using the Episode Naming settings?\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(15),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"create_missing_show_dirs\",\n name: \"create_missing_show_dirs\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.createMissingShowDirs,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"createMissingShowDirs\",\n $$v\n )\n },\n expression: \"postProcessing.createMissingShowDirs\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Create missing show directories when they get deleted\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(16),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"add_shows_wo_dir\",\n name: \"add_shows_wo_dir\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.addShowsWithoutDir,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"addShowsWithoutDir\",\n $$v\n )\n },\n expression: \"postProcessing.addShowsWithoutDir\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Add shows without creating a directory (not recommended)\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(17),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"move_associated_files\",\n name: \"move_associated_files\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.moveAssociatedFiles,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"moveAssociatedFiles\",\n $$v\n )\n },\n expression: \"postProcessing.moveAssociatedFiles\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Delete srt/srr/sfv/etc files while post processing?\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(18),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"select-list\", {\n attrs: {\n name: \"allowed_extensions\",\n id: \"allowed_extensions\",\n \"csv-enabled\": \"\",\n \"list-items\": _vm.postProcessing.allowedExtensions\n },\n on: { change: _vm.onChangeAllowedExtensions }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Comma seperated list of associated file extensions Medusa should keep while post processing.\"\n )\n ]),\n _c(\"br\"),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Leaving it empty means all associated files will be deleted\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(19),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"nfo_rename\",\n name: \"nfo_rename\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.nfoRename,\n callback: function($$v) {\n _vm.$set(_vm.postProcessing, \"nfoRename\", $$v)\n },\n expression: \"postProcessing.nfoRename\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Rename the original .nfo file to .nfo-orig to avoid conflicts?\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(20),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"airdate_episodes\",\n name: \"airdate_episodes\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.airdateEpisodes,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"airdateEpisodes\",\n $$v\n )\n },\n expression: \"postProcessing.airdateEpisodes\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Set last modified filedate to the date that the episode aired?\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(21),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\n \"select\",\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.postProcessing.fileTimestampTimezone,\n expression:\n \"postProcessing.fileTimestampTimezone\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: {\n id: \"file_timestamp_timezone\",\n name: \"file_timestamp_timezone\"\n },\n on: {\n change: function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val = \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.$set(\n _vm.postProcessing,\n \"fileTimestampTimezone\",\n $event.target.multiple\n ? $$selectedVal\n : $$selectedVal[0]\n )\n }\n }\n },\n _vm._l(_vm.timezoneOptions, function(option) {\n return _c(\n \"option\",\n {\n key: option.value,\n domProps: { value: option.value }\n },\n [_vm._v(_vm._s(option.text))]\n )\n })\n ),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"What timezone should be used to change File Date?\"\n )\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(22),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"unpack\",\n name: \"unpack\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.unpack,\n callback: function($$v) {\n _vm.$set(_vm.postProcessing, \"unpack\", $$v)\n },\n expression: \"postProcessing.unpack\"\n }\n }),\n _vm._v(\" \"),\n _vm._m(23),\n _c(\"br\"),\n _vm._v(\" \"),\n _vm._m(24)\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(25),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"del_rar_contents\",\n name: \"del_rar_contents\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.deleteRarContent,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing,\n \"deleteRarContent\",\n $$v\n )\n },\n expression: \"postProcessing.deleteRarContent\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Delete content of RAR files, even if Process Method not set to move?\"\n )\n ])\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(26),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"no_delete\",\n name: \"no_delete\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.noDelete,\n callback: function($$v) {\n _vm.$set(_vm.postProcessing, \"noDelete\", $$v)\n },\n expression: \"postProcessing.noDelete\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\"Leave empty folders when Post Processing?\")\n ]),\n _c(\"br\"),\n _vm._v(\" \"),\n _vm._m(27)\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(28),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"select-list\", {\n attrs: {\n name: \"extra_scripts\",\n id: \"extra_scripts\",\n \"csv-enabled\": \"\",\n \"list-items\": _vm.postProcessing.extraScripts\n },\n on: { change: _vm.onChangeExtraScripts }\n }),\n _vm._v(\" \"),\n _c(\n \"span\",\n [\n _vm._v(\"See \"),\n _c(\n \"app-link\",\n {\n staticClass: \"wikie\",\n attrs: {\n href: _vm.postProcessing.extraScriptsUrl\n }\n },\n [_c(\"strong\", [_vm._v(\"Wiki\")])]\n ),\n _vm._v(\n \" for script arguments description and usage.\"\n )\n ],\n 1\n )\n ],\n 1\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"input\", {\n staticClass: \"btn-medusa config_submitter\",\n attrs: { type: \"submit\", value: \"Save Changes\" }\n })\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { attrs: { id: \"episode-naming\" } }, [\n _c(\"div\", { staticClass: \"row component-group\" }, [\n _vm._m(29),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-xs-12 col-md-10\" }, [\n _c(\n \"fieldset\",\n { staticClass: \"component-group-list\" },\n [\n _c(\"name-pattern\", {\n staticClass: \"component-item\",\n attrs: {\n \"naming-pattern\": _vm.postProcessing.naming.pattern,\n \"naming-presets\": _vm.presets,\n \"multi-ep-style\": _vm.postProcessing.naming.multiEp,\n \"multi-ep-styles\": _vm.multiEpStringsSelect,\n \"flag-loaded\": _vm.configLoaded\n },\n on: { change: _vm.saveNaming }\n }),\n _vm._v(\" \"),\n _c(\"name-pattern\", {\n staticClass: \"component-item\",\n attrs: {\n enabled:\n _vm.postProcessing.naming.enableCustomNamingSports,\n \"naming-pattern\":\n _vm.postProcessing.naming.patternSports,\n \"naming-presets\": _vm.presets,\n type: \"sports\",\n \"enabled-naming-custom\":\n _vm.postProcessing.naming.enableCustomNamingSports,\n \"flag-loaded\": _vm.configLoaded\n },\n on: { change: _vm.saveNamingSports }\n }),\n _vm._v(\" \"),\n _c(\"name-pattern\", {\n staticClass: \"component-item\",\n attrs: {\n enabled:\n _vm.postProcessing.naming\n .enableCustomNamingAirByDate,\n \"naming-pattern\":\n _vm.postProcessing.naming.patternAirByDate,\n \"naming-presets\": _vm.presets,\n type: \"airs by date\",\n \"enabled-naming-custom\":\n _vm.postProcessing.naming\n .enableCustomNamingAirByDate,\n \"flag-loaded\": _vm.configLoaded\n },\n on: { change: _vm.saveNamingAbd }\n }),\n _vm._v(\" \"),\n _c(\"name-pattern\", {\n staticClass: \"component-item\",\n attrs: {\n enabled:\n _vm.postProcessing.naming.enableCustomNamingAnime,\n \"naming-pattern\":\n _vm.postProcessing.naming.patternAnime,\n \"naming-presets\": _vm.presets,\n type: \"anime\",\n \"multi-ep-style\":\n _vm.postProcessing.naming.animeMultiEp,\n \"multi-ep-styles\": _vm.multiEpStringsSelect,\n \"anime-naming-type\":\n _vm.postProcessing.naming.animeNamingType,\n \"enabled-naming-custom\":\n _vm.postProcessing.naming.enableCustomNamingAnime,\n \"flag-loaded\": _vm.configLoaded\n },\n on: { change: _vm.saveNamingAnime }\n }),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group component-item\" }, [\n _vm._m(30),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"col-sm-10 content\" },\n [\n _c(\"toggle-button\", {\n attrs: {\n width: 45,\n height: 22,\n id: \"naming_strip_year\",\n name: \"naming_strip_year\",\n sync: \"\"\n },\n model: {\n value: _vm.postProcessing.naming.stripYear,\n callback: function($$v) {\n _vm.$set(\n _vm.postProcessing.naming,\n \"stripYear\",\n $$v\n )\n },\n expression: \"postProcessing.naming.stripYear\"\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", [\n _vm._v(\n \"Remove the TV show's year when renaming the file?\"\n )\n ]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"Only applies to shows that have year inside parentheses\"\n )\n ])\n ],\n 1\n )\n ])\n ],\n 1\n )\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { attrs: { id: \"metadata\" } }, [\n _c(\"div\", { staticClass: \"row component-group\" }, [\n _vm._m(31),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-xs-12 col-md-10\" }, [\n _c(\n \"fieldset\",\n { staticClass: \"component-group-list\" },\n [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _vm._m(32),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-sm-10 content\" }, [\n _c(\n \"select\",\n {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.metadataProviderSelected,\n expression: \"metadataProviderSelected\"\n }\n ],\n staticClass: \"form-control input-sm\",\n attrs: {\n id: \"metadataType\",\n name: \"metadataType\"\n },\n on: {\n change: function($event) {\n var $$selectedVal = Array.prototype.filter\n .call($event.target.options, function(o) {\n return o.selected\n })\n .map(function(o) {\n var val =\n \"_value\" in o ? o._value : o.value\n return val\n })\n _vm.metadataProviderSelected = $event.target\n .multiple\n ? $$selectedVal\n : $$selectedVal[0]\n }\n }\n },\n _vm._l(_vm.metadataProviders, function(option) {\n return _c(\n \"option\",\n {\n key: option.id,\n domProps: { value: option.id }\n },\n [_vm._v(_vm._s(option.name))]\n )\n })\n ),\n _vm._v(\" \"),\n _vm._m(33)\n ])\n ]),\n _vm._v(\" \"),\n _vm._l(_vm.metadataProviders, function(provider) {\n return _c(\n \"div\",\n {\n directives: [\n {\n name: \"show\",\n rawName: \"v-show\",\n value:\n provider.id === _vm.metadataProviderSelected,\n expression:\n \"provider.id === metadataProviderSelected\"\n }\n ],\n key: provider.id,\n staticClass: \"metadataDiv\",\n attrs: { id: \"provider.id\" }\n },\n [\n _c(\n \"div\",\n { staticClass: \"metadata_options_wrapper\" },\n [\n _c(\"h4\", [_vm._v(\"Create:\")]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"metadata_options\" }, [\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_show_metadata\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.showMetadata,\n expression: \"provider.showMetadata\"\n }\n ],\n staticClass: \"metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_show_metadata\"\n },\n domProps: {\n checked: Array.isArray(\n provider.showMetadata\n )\n ? _vm._i(\n provider.showMetadata,\n null\n ) > -1\n : provider.showMetadata\n },\n on: {\n change: function($event) {\n var $$a = provider.showMetadata,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"showMetadata\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"showMetadata\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"showMetadata\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Show Metadata\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_episode_metadata\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.episodeMetadata,\n expression:\n \"provider.episodeMetadata\"\n }\n ],\n staticClass: \"metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_episode_metadata\",\n disabled: provider.example.episodeMetadata.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.episodeMetadata\n )\n ? _vm._i(\n provider.episodeMetadata,\n null\n ) > -1\n : provider.episodeMetadata\n },\n on: {\n change: function($event) {\n var $$a = provider.episodeMetadata,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"episodeMetadata\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"episodeMetadata\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"episodeMetadata\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Episode Metadata\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n { attrs: { for: provider.id + \"_fanart\" } },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.fanart,\n expression: \"provider.fanart\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_fanart\",\n disabled: provider.example.fanart.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.fanart\n )\n ? _vm._i(provider.fanart, null) > -1\n : provider.fanart\n },\n on: {\n change: function($event) {\n var $$a = provider.fanart,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"fanart\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"fanart\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(provider, \"fanart\", $$c)\n }\n }\n }\n }),\n _vm._v(\" Show Fanart\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n { attrs: { for: provider.id + \"_poster\" } },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.poster,\n expression: \"provider.poster\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_poster\",\n disabled: provider.example.poster.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.poster\n )\n ? _vm._i(provider.poster, null) > -1\n : provider.poster\n },\n on: {\n change: function($event) {\n var $$a = provider.poster,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"poster\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"poster\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(provider, \"poster\", $$c)\n }\n }\n }\n }),\n _vm._v(\" Show Poster\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n { attrs: { for: provider.id + \"_banner\" } },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.banner,\n expression: \"provider.banner\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_banner\",\n disabled: provider.example.banner.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.banner\n )\n ? _vm._i(provider.banner, null) > -1\n : provider.banner\n },\n on: {\n change: function($event) {\n var $$a = provider.banner,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"banner\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"banner\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(provider, \"banner\", $$c)\n }\n }\n }\n }),\n _vm._v(\" Show Banner\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_episode_thumbnails\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.episodeThumbnails,\n expression:\n \"provider.episodeThumbnails\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id:\n provider.id + \"_episode_thumbnails\",\n disabled: provider.example.episodeThumbnails.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.episodeThumbnails\n )\n ? _vm._i(\n provider.episodeThumbnails,\n null\n ) > -1\n : provider.episodeThumbnails\n },\n on: {\n change: function($event) {\n var $$a =\n provider.episodeThumbnails,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"episodeThumbnails\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"episodeThumbnails\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"episodeThumbnails\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Episode Thumbnails\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_posters\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.seasonPosters,\n expression: \"provider.seasonPosters\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_season_posters\",\n disabled: provider.example.seasonPosters.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.seasonPosters\n )\n ? _vm._i(\n provider.seasonPosters,\n null\n ) > -1\n : provider.seasonPosters\n },\n on: {\n change: function($event) {\n var $$a = provider.seasonPosters,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"seasonPosters\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"seasonPosters\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"seasonPosters\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Season Posters\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_banners\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.seasonBanners,\n expression: \"provider.seasonBanners\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id: provider.id + \"_season_banners\",\n disabled: provider.example.seasonBanners.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.seasonBanners\n )\n ? _vm._i(\n provider.seasonBanners,\n null\n ) > -1\n : provider.seasonBanners\n },\n on: {\n change: function($event) {\n var $$a = provider.seasonBanners,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"seasonBanners\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"seasonBanners\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"seasonBanners\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Season Banners\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_all_poster\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.seasonAllPoster,\n expression:\n \"provider.seasonAllPoster\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id:\n provider.id + \"_season_all_poster\",\n disabled: provider.example.seasonAllPoster.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.seasonAllPoster\n )\n ? _vm._i(\n provider.seasonAllPoster,\n null\n ) > -1\n : provider.seasonAllPoster\n },\n on: {\n change: function($event) {\n var $$a = provider.seasonAllPoster,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"seasonAllPoster\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"seasonAllPoster\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"seasonAllPoster\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Season All Poster\")\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_all_banner\"\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: provider.seasonAllBanner,\n expression:\n \"provider.seasonAllBanner\"\n }\n ],\n staticClass:\n \"float-left metadata_checkbox\",\n attrs: {\n type: \"checkbox\",\n id:\n provider.id + \"_season_all_banner\",\n disabled: provider.example.seasonAllBanner.includes(\n \"not supported\"\n )\n },\n domProps: {\n checked: Array.isArray(\n provider.seasonAllBanner\n )\n ? _vm._i(\n provider.seasonAllBanner,\n null\n ) > -1\n : provider.seasonAllBanner\n },\n on: {\n change: function($event) {\n var $$a = provider.seasonAllBanner,\n $$el = $event.target,\n $$c = $$el.checked ? true : false\n if (Array.isArray($$a)) {\n var $$v = null,\n $$i = _vm._i($$a, $$v)\n if ($$el.checked) {\n $$i < 0 &&\n _vm.$set(\n provider,\n \"seasonAllBanner\",\n $$a.concat([$$v])\n )\n } else {\n $$i > -1 &&\n _vm.$set(\n provider,\n \"seasonAllBanner\",\n $$a\n .slice(0, $$i)\n .concat(\n $$a.slice($$i + 1)\n )\n )\n }\n } else {\n _vm.$set(\n provider,\n \"seasonAllBanner\",\n $$c\n )\n }\n }\n }\n }),\n _vm._v(\" Season All Banner\")\n ]\n )\n ])\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"metadata_example_wrapper\" },\n [\n _c(\"h4\", [_vm._v(\"Results:\")]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"metadata_example\" }, [\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_show_metadata\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.showMetadata\n },\n attrs: {\n id:\n provider.id + \"_eg_show_metadata\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .showMetadata +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_episode_metadata\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.episodeMetadata\n },\n attrs: {\n id:\n provider.id +\n \"_eg_episode_metadata\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .episodeMetadata +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n { attrs: { for: provider.id + \"_fanart\" } },\n [\n _c(\n \"span\",\n {\n class: { disabled: !provider.fanart },\n attrs: {\n id: provider.id + \"_eg_fanart\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example.fanart +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n { attrs: { for: provider.id + \"_poster\" } },\n [\n _c(\n \"span\",\n {\n class: { disabled: !provider.poster },\n attrs: {\n id: provider.id + \"_eg_poster\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example.poster +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n { attrs: { for: provider.id + \"_banner\" } },\n [\n _c(\n \"span\",\n {\n class: { disabled: !provider.banner },\n attrs: {\n id: provider.id + \"_eg_banner\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example.banner +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_episode_thumbnails\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.episodeThumbnails\n },\n attrs: {\n id:\n provider.id +\n \"_eg_episode_thumbnails\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .episodeThumbnails +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_posters\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.seasonPosters\n },\n attrs: {\n id:\n provider.id + \"_eg_season_posters\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .seasonPosters +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_banners\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.seasonBanners\n },\n attrs: {\n id:\n provider.id + \"_eg_season_banners\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .seasonBanners +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_all_poster\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.seasonAllPoster\n },\n attrs: {\n id:\n provider.id +\n \"_eg_season_all_poster\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .seasonAllPoster +\n \"\"\n )\n }\n })\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"label\",\n {\n attrs: {\n for: provider.id + \"_season_all_banner\"\n }\n },\n [\n _c(\n \"span\",\n {\n class: {\n disabled: !provider.seasonAllBanner\n },\n attrs: {\n id:\n provider.id +\n \"_eg_season_all_banner\"\n }\n },\n [\n _c(\"span\", {\n domProps: {\n innerHTML: _vm._s(\n \"\" +\n provider.example\n .seasonAllBanner +\n \"\"\n )\n }\n })\n ]\n )\n ]\n )\n ])\n ]\n )\n ]\n )\n })\n ],\n 2\n ),\n _vm._v(\" \"),\n _c(\"input\", {\n staticClass: \"btn-medusa config_submitter\",\n attrs: { type: \"submit\", value: \"Save Changes\" }\n }),\n _c(\"br\")\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"h6\", { staticClass: \"pull-right\" }, [\n _c(\"b\", [\n _vm._v(\"All non-absolute folder locations are relative to \"),\n _c(\"span\", { staticClass: \"path\" }, [\n _vm._v(_vm._s(_vm.config.dataDir))\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\"input\", {\n staticClass: \"btn-medusa pull-left config_submitter button\",\n attrs: { type: \"submit\", value: \"Save Changes\" }\n })\n ])\n ]\n )\n ])\n ])\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"component-group-desc col-xs-12 col-md-2\" },\n [\n _c(\"h3\", [_vm._v(\"Scheduled Post-Processing\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"Settings that dictate how Medusa should process completed downloads.\"\n )\n ]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"The scheduled postprocessor will periodically scan a folder for media to process.\"\n )\n ])\n ]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"process_automatically\" }\n },\n [_c(\"span\", [_vm._v(\"Scheduled Postprocessor\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"p\", [\n _vm._v(\n \"Enable the scheduled post processor to scan and process any files in your \"\n ),\n _c(\"i\", [_vm._v(\"Post Processing Dir\")]),\n _vm._v(\"?\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { staticClass: \"clear-left\" }, [\n _c(\"p\", [\n _c(\"b\", [_vm._v(\"NOTE:\")]),\n _vm._v(\" Do not use if you use an external Post Processing script\")\n ])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"tv_download_dir\" }\n },\n [_c(\"span\", [_vm._v(\"Post Processing Dir\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { staticClass: \"clear-left\" }, [\n _c(\"p\", [\n _c(\"b\", [_vm._v(\"NOTE:\")]),\n _vm._v(\n \" Please use seperate downloading and completed folders in your download client if possible.\"\n )\n ])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"process_method\" }\n },\n [_c(\"span\", [_vm._v(\"Processing Method\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"p\", [\n _c(\"b\", [_vm._v(\"NOTE:\")]),\n _vm._v(\n \" If you keep seeding torrents after they finish, please avoid the 'move' processing method to prevent errors.\"\n )\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"autopostprocessor_frequency\" }\n },\n [_c(\"span\", [_vm._v(\"Auto Post-Processing Frequency\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"component-group-desc col-xs-12 col-md-2\" },\n [\n _c(\"h3\", [_vm._v(\"General Post-Processing\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"Generic postprocessing settings that apply both to the scheduled postprocessor as external scripts\"\n )\n ])\n ]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"postpone_if_sync_files\" }\n },\n [_c(\"span\", [_vm._v(\"Postpone post processing\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"sync_files\" } },\n [_c(\"span\", [_vm._v(\"Sync File Extensions\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"postpone_if_no_subs\" }\n },\n [_c(\"span\", [_vm._v(\"Postpone if no subtitle\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"span\", [\n _c(\"b\", [_vm._v(\"NOTE:\")]),\n _vm._v(\n \" Automatic post processor should be disabled to avoid files with pending subtitles being processed over and over.\"\n )\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"rename_episodes\" }\n },\n [_c(\"span\", [_vm._v(\"Rename Episodes\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"create_missing_show_dirs\" }\n },\n [_c(\"span\", [_vm._v(\"Create missing show directories\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"add_shows_wo_dir\" }\n },\n [_c(\"span\", [_vm._v(\"Add shows without directory\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"move_associated_files\" }\n },\n [_c(\"span\", [_vm._v(\"Delete associated files\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"label\", { staticClass: \"col-sm-2 control-label\" }, [\n _c(\"span\", [_vm._v(\"Keep associated file extensions\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"nfo_rename\" } },\n [_c(\"span\", [_vm._v(\"Rename .nfo file\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"airdate_episodes\" }\n },\n [_c(\"span\", [_vm._v(\"Change File Date\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"file_timestamp_timezone\" }\n },\n [_c(\"span\", [_vm._v(\"Timezone for File Date:\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"unpack\" } },\n [_c(\"span\", [_vm._v(\"Unpack\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"span\", [\n _vm._v(\"Unpack any TV releases in your \"),\n _c(\"i\", [_vm._v(\"TV Download Dir\")]),\n _vm._v(\"?\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"span\", [\n _c(\"b\", [_vm._v(\"NOTE:\")]),\n _vm._v(\" Only working with RAR archive\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"del_rar_contents\" }\n },\n [_c(\"span\", [_vm._v(\"Delete RAR contents\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"no_delete\" } },\n [_c(\"span\", [_vm._v(\"Don't delete empty folders\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"span\", [\n _c(\"b\", [_vm._v(\"NOTE:\")]),\n _vm._v(\" Can be overridden using manual Post Processing\")\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"label\", { staticClass: \"col-sm-2 control-label\" }, [\n _c(\"span\", [_vm._v(\"Extra Scripts\")])\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"component-group-desc col-xs-12 col-md-2\" },\n [\n _c(\"h3\", [_vm._v(\"Episode Naming\")]),\n _vm._v(\" \"),\n _c(\"p\", [_vm._v(\"How Medusa will name and sort your episodes.\")])\n ]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n {\n staticClass: \"col-sm-2 control-label\",\n attrs: { for: \"naming_strip_year\" }\n },\n [_c(\"span\", [_vm._v(\"Strip Show Year\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"component-group-desc col-xs-12 col-md-2\" },\n [\n _c(\"h3\", [_vm._v(\"Metadata\")]),\n _vm._v(\" \"),\n _c(\"p\", [\n _vm._v(\n \"The data associated to the data. These are files associated to a TV show in the form of images and text that, when supported, will enhance the viewing experience.\"\n )\n ])\n ]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"label\",\n { staticClass: \"col-sm-2 control-label\", attrs: { for: \"metadataType\" } },\n [_c(\"span\", [_vm._v(\"Metadata Type\")])]\n )\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"span\", { staticClass: \"d-block\" }, [\n _vm._v(\"Toggle the metadata options that you wish to be created. \"),\n _c(\"b\", [_vm._v(\"Multiple targets may be used.\")])\n ])\n }\n]\nrender._withStripped = true\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-post-processing.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-post-processing.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./config-post-processing.vue?vue&type=template&id=78fe0fd3&\"\nimport script from \"./config-post-processing.vue?vue&type=script&lang=js&\"\nexport * from \"./config-post-processing.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-post-processing.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\ncomponent.options.__file = \"config-post-processing.vue\"\nexport default component.exports","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/*\\n@NOTE: This fixes the header blocking elements when using a hash link\\ne.g. displayShow?indexername=tvdb&seriesid=83462#season-5\\n*/\\n[false-link]::before {\\n content: '';\\n display: block;\\n position: absolute;\\n height: 100px;\\n margin-top: -100px;\\n z-index: -100;\\n}\\n.router-link,\\n.router-link-active {\\n cursor: pointer;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./asset.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./asset.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-template.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-template.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.form-control {\\n color: rgb(0, 0, 0);\\n}\\n.input75 {\\n width: 75px;\\n margin-top: -4px;\\n}\\n.input250 {\\n width: 250px;\\n margin-top: -4px;\\n}\\n.input350 {\\n width: 350px;\\n margin-top: -4px;\\n}\\n.input450 {\\n width: 450px;\\n margin-top: -4px;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.input75 {\\n width: 75px;\\n margin-top: -4px;\\n}\\n.input250 {\\n width: 250px;\\n margin-top: -4px;\\n}\\n.input350 {\\n width: 350px;\\n margin-top: -4px;\\n}\\n.input450 {\\n width: 450px;\\n margin-top: -4px;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.input75 {\\n width: 75px;\\n margin-top: -4px;\\n}\\n.input250 {\\n width: 250px;\\n margin-top: -4px;\\n}\\n.input350 {\\n width: 350px;\\n margin-top: -4px;\\n}\\n.input450 {\\n width: 450px;\\n margin-top: -4px;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=style&index=0&id=5a327762&scoped=true&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=style&index=0&id=5a327762&scoped=true&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\ndiv.file-browser.max-width[data-v-5a327762] {\\n max-width: 450px;\\n}\\ndiv.file-browser .input-group-no-btn[data-v-5a327762] {\\n display: flex;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./language-select.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./language-select.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./name-pattern.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./name-pattern.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.plotInfo {\\n cursor: help;\\n float: right;\\n position: relative;\\n top: 2px;\\n}\\n.plotInfoNone {\\n cursor: help;\\n float: right;\\n position: relative;\\n top: 2px;\\n opacity: 0.4;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=style&index=0&id=b683ee7a&scoped=true&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=style&index=0&id=b683ee7a&scoped=true&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.quality[data-v-b683ee7a] {\\n font: 12px/13px \\\"Open Sans\\\", verdana, sans-serif;\\n background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n background-image: -o-linear-gradient(top, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), inset 0 -1px 3px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 2px rgba(0, 0, 0, 0.15);\\n text-shadow: 0 1px rgba(0, 0, 0, 0.8);\\n color: rgb(255, 255, 255);\\n display: inline-block;\\n padding: 2px 4px;\\n text-align: center;\\n vertical-align: baseline;\\n border-radius: 4px;\\n white-space: nowrap;\\n}\\n.any-hd[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n /* stylelint-disable declaration-block-no-shorthand-property-overrides */\\n background:\\n repeating-linear-gradient(\\n -45deg,\\n rgb(38, 114, 182),\\n rgb(38, 114, 182) 10px,\\n rgb(91, 153, 13) 10px,\\n rgb(91, 153, 13) 20px\\n );\\n /* stylelint-enable */\\n}\\n.Custom[data-v-b683ee7a] {\\n background-color: rgb(98, 25, 147);\\n}\\n.HD[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n}\\n.HDTV[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n}\\n.HD720p[data-v-b683ee7a] {\\n background-color: rgb(91, 153, 13);\\n}\\n.HD1080p[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n}\\n.UHD-4K[data-v-b683ee7a] {\\n background-color: rgb(117, 0, 255);\\n}\\n.UHD-8K[data-v-b683ee7a] {\\n background-color: rgb(65, 0, 119);\\n}\\n.RawHD[data-v-b683ee7a] {\\n background-color: rgb(205, 115, 0);\\n}\\n.RawHDTV[data-v-b683ee7a] {\\n background-color: rgb(205, 115, 0);\\n}\\n.SD[data-v-b683ee7a] {\\n background-color: rgb(190, 38, 37);\\n}\\n.SDTV[data-v-b683ee7a] {\\n background-color: rgb(190, 38, 37);\\n}\\n.SDDVD[data-v-b683ee7a] {\\n background-color: rgb(190, 38, 37);\\n}\\n.Any[data-v-b683ee7a] {\\n background-color: rgb(102, 102, 102);\\n}\\n.Unknown[data-v-b683ee7a] {\\n background-color: rgb(153, 153, 153);\\n}\\n.Proper[data-v-b683ee7a] {\\n background-color: rgb(63, 127, 0);\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.scroll-wrapper {\\n position: fixed;\\n opacity: 0;\\n visibility: hidden;\\n overflow: hidden;\\n text-align: center;\\n font-size: 20px;\\n z-index: 999;\\n background-color: #777;\\n color: #eee;\\n width: 50px;\\n height: 48px;\\n line-height: 48px;\\n right: 30px;\\n bottom: 30px;\\n padding-top: 2px;\\n border-radius: 10px;\\n -webkit-transition: all 0.5s ease-in-out;\\n -moz-transition: all 0.5s ease-in-out;\\n -ms-transition: all 0.5s ease-in-out;\\n -o-transition: all 0.5s ease-in-out;\\n transition: all 0.5s ease-in-out;\\n}\\n.scroll-wrapper.show {\\n visibility: visible;\\n cursor: pointer;\\n opacity: 1;\\n}\\n.scroll-wrapper.left {\\n position: fixed;\\n right: 150px;\\n}\\n.scroll-wrapper.right {\\n position: fixed;\\n right: 90px;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=style&index=0&id=391728a9&scoped=true&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=style&index=0&id=391728a9&scoped=true&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\ndiv.select-list ul[data-v-391728a9] {\\n padding-left: 0;\\n}\\ndiv.select-list li[data-v-391728a9] {\\n list-style-type: none;\\n display: flex;\\n}\\ndiv.select-list .new-item[data-v-391728a9] {\\n display: flex;\\n}\\ndiv.select-list .new-item-help[data-v-391728a9] {\\n font-weight: bold;\\n padding-top: 5px;\\n}\\ndiv.select-list input[data-v-391728a9],\\ndiv.select-list img[data-v-391728a9] {\\n display: inline-block;\\n box-sizing: border-box;\\n}\\ndiv.select-list.max-width[data-v-391728a9] {\\n max-width: 450px;\\n}\\ndiv.select-list .switch-input[data-v-391728a9] {\\n left: -8px;\\n top: 4px;\\n position: absolute;\\n z-index: 10;\\n opacity: 0.6;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\nselect.select-show {\\n display: inline-block;\\n height: 25px;\\n padding: 1px;\\n}\\n.show-selector {\\n height: 31px;\\n display: table-cell;\\n left: 20px;\\n margin-bottom: 5px;\\n}\\n@media (max-width: 767px) and (min-width: 341px) {\\n.select-show-group,\\n .select-show {\\n width: 100%;\\n}\\n}\\n@media (max-width: 340px) {\\n.select-show-group {\\n width: 100%;\\n}\\n}\\n@media (max-width: 767px) {\\n.show-selector {\\n float: left;\\n width: 100%;\\n}\\n.select-show {\\n width: 100%;\\n}\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./state-switch.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./state-switch.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-recommended.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-recommended.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=style&index=0&id=10f4092b&scoped=true&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=style&index=0&id=10f4092b&scoped=true&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\ndiv.anidb-release-group-ui-wrapper[data-v-10f4092b] {\\n clear: both;\\n margin-bottom: 20px;\\n}\\ndiv.anidb-release-group-ui-wrapper ul[data-v-10f4092b] {\\n border-style: solid;\\n border-width: thin;\\n padding: 5px 2px 2px 5px;\\n list-style: none;\\n}\\ndiv.anidb-release-group-ui-wrapper li.active[data-v-10f4092b] {\\n background-color: cornflowerblue;\\n}\\ndiv.anidb-release-group-ui-wrapper div.arrow img[data-v-10f4092b] {\\n cursor: pointer;\\n height: 32px;\\n width: 32px;\\n}\\ndiv.anidb-release-group-ui-wrapper img.deleteFromWhitelist[data-v-10f4092b],\\ndiv.anidb-release-group-ui-wrapper img.deleteFromBlacklist[data-v-10f4092b] {\\n float: right;\\n}\\ndiv.anidb-release-group-ui-wrapper #add-new-release-group p > img[data-v-10f4092b] {\\n height: 16px;\\n width: 16px;\\n background-color: rgb(204, 204, 204);\\n}\\ndiv.anidb-release-group-ui-wrapper.placeholder[data-v-10f4092b] {\\n height: 32px;\\n}\\ndiv.anidb-release-group-ui-wrapper.max-width[data-v-10f4092b] {\\n max-width: 960px;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-show-options.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-show-options.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-shows.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-shows.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.floating-badge {\\n position: absolute;\\n top: -5px;\\n right: -8px;\\n padding: 0 4px;\\n background-color: #777;\\n border: 2px solid #959595;\\n border-radius: 100px;\\n font-size: 12px;\\n font-weight: bold;\\n text-decoration: none;\\n color: white;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./backstretch.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./backstretch.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.infoTable tr td:first-child {\\n vertical-align: top;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-post-processing.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-post-processing.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=style&index=0&id=60f89f30&scoped=true&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=style&index=0&id=60f89f30&scoped=true&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.irc-frame[data-v-60f89f30] {\\n width: 100%;\\n height: 500px;\\n border: 1px #000 solid;\\n}\\n.loading-spinner[data-v-60f89f30] {\\n background-position: center center;\\n background-repeat: no-repeat;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./login.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./login.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manual-post-process.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manual-post-process.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.root-dirs-selectbox,\\n.root-dirs-selectbox select,\\n.root-dirs-controls {\\n width: 100%;\\n max-width: 430px;\\n}\\n.root-dirs-selectbox {\\n padding: 0 0 5px;\\n}\\n.root-dirs-controls {\\n text-align: center;\\n}\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./snatch-selection.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./snatch-selection.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./status.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/index.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./status.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./404.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/index.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./404.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n/* placeholder */\\n\", \"\"]);\n\n// exports\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///./src/components/anidb-release-group-ui.vue?0ea6","webpack:///src/components/anidb-release-group-ui.vue","webpack:///./src/components/anidb-release-group-ui.vue","webpack:///./src/components/anidb-release-group-ui.vue?c1d7","webpack:///src/components/add-show-options.vue","webpack:///./src/components/add-show-options.vue?75eb","webpack:///./src/components/add-show-options.vue","webpack:///./src/components/add-show-options.vue?adcc","webpack:///./src/components/app-header.vue?e200","webpack:///./src/components/app-header.vue","webpack:///./src/components/app-header.vue?2a72","webpack:///./src/components/backstretch.vue?12be","webpack:///./src/components/backstretch.vue","webpack:///./src/components/backstretch.vue?58f8","webpack:///./src/components/home.vue?3366","webpack:///./src/components/home.vue","webpack:///./src/components/manual-post-process.vue?7c6f","webpack:///./src/components/manual-post-process.vue","webpack:///./src/components/root-dirs.vue?4383","webpack:///./src/components/root-dirs.vue","webpack:///./src/components/root-dirs.vue?b188","webpack:///./src/components/show.vue?04f2","webpack:///./src/components/show.vue","webpack:///./src/components/snatch-selection.vue?a09a","webpack:///./src/components/snatch-selection.vue","webpack:///./src/components/status.vue?6c0c","webpack:///./src/components/status.vue","webpack:///./src/components/index.js","webpack:///./src/api.js","webpack:///./src/components/helpers/app-link.vue?ecce","webpack:///src/components/helpers/app-link.vue","webpack:///./src/components/helpers/app-link.vue?62b8","webpack:///./src/components/helpers/app-link.vue","webpack:///./src/components/helpers/asset.vue?3066","webpack:///src/components/helpers/asset.vue","webpack:///./src/components/helpers/asset.vue","webpack:///./src/components/helpers/asset.vue?8b94","webpack:///./src/components/helpers/config-template.vue?2b56","webpack:///src/components/helpers/config-template.vue","webpack:///./src/components/helpers/config-template.vue","webpack:///./src/components/helpers/config-template.vue?461f","webpack:///./src/components/helpers/config-textbox-number.vue?74e9","webpack:///src/components/helpers/config-textbox-number.vue","webpack:///./src/components/helpers/config-textbox-number.vue","webpack:///./src/components/helpers/config-textbox-number.vue?edd2","webpack:///./src/components/helpers/config-textbox.vue?7539","webpack:///src/components/helpers/config-textbox.vue","webpack:///./src/components/helpers/config-textbox.vue","webpack:///./src/components/helpers/config-textbox.vue?c301","webpack:///./src/components/helpers/config-toggle-slider.vue?bcb1","webpack:///src/components/helpers/config-toggle-slider.vue","webpack:///./src/components/helpers/config-toggle-slider.vue","webpack:///./src/components/helpers/config-toggle-slider.vue?a5af","webpack:///./src/components/helpers/file-browser.vue?7d64","webpack:///./src/components/helpers/file-browser.vue","webpack:///./src/components/helpers/file-browser.vue?d9c9","webpack:///./src/components/helpers/language-select.vue?ed6a","webpack:///./src/components/helpers/language-select.vue","webpack:///./src/components/helpers/language-select.vue?f23b","webpack:///./src/components/helpers/name-pattern.vue?b2bc","webpack:///./src/components/helpers/name-pattern.vue","webpack:///./src/components/helpers/name-pattern.vue?9c2d","webpack:///./src/components/helpers/plot-info.vue?9d72","webpack:///./src/components/helpers/plot-info.vue","webpack:///./src/components/helpers/plot-info.vue?508c","webpack:///src/components/helpers/quality-pill.vue","webpack:///./src/components/helpers/quality-pill.vue?cb0d","webpack:///./src/components/helpers/quality-pill.vue","webpack:///./src/components/helpers/quality-pill.vue?677b","webpack:///./src/components/helpers/scroll-buttons.vue?4a49","webpack:///./src/components/helpers/scroll-buttons.vue","webpack:///./src/components/helpers/scroll-buttons.vue?f23f","webpack:///./src/components/helpers/select-list.vue?3a99","webpack:///src/components/helpers/select-list.vue","webpack:///./src/components/helpers/select-list.vue","webpack:///./src/components/helpers/select-list.vue?b180","webpack:///src/components/helpers/show-selector.vue","webpack:///./src/components/helpers/show-selector.vue?306a","webpack:///./src/components/helpers/show-selector.vue","webpack:///./src/components/helpers/show-selector.vue?e322","webpack:///./src/components/helpers/state-switch.vue?9500","webpack:///src/components/helpers/state-switch.vue","webpack:///./src/components/helpers/state-switch.vue","webpack:///./src/components/helpers/state-switch.vue?8b88","webpack:///./src/components/helpers/index.js","webpack:///./src/utils.js","webpack:///./src/components/show-header.vue?b52c","webpack:///./src/components/show-header.vue?6f87","webpack:///./src/components/show-header.vue","webpack:///./src/router.js","webpack:///./src/components/helpers/app-link.vue?609c","webpack:///./src/components/helpers/config-textbox-number.vue?c110","webpack:///./src/components/helpers/config-textbox.vue?d09a","webpack:///./src/components/helpers/config-toggle-slider.vue?b7c8","webpack:///src/components/helpers/file-browser.vue","webpack:///./src/components/helpers/file-browser.vue?be00","webpack:///src/components/helpers/language-select.vue","webpack:///src/components/helpers/name-pattern.vue","webpack:///src/components/helpers/plot-info.vue","webpack:///./src/components/helpers/plot-info.vue?6acf","webpack:///./src/components/helpers/quality-pill.vue?c100","webpack:///src/components/helpers/scroll-buttons.vue","webpack:///./src/components/helpers/scroll-buttons.vue?9417","webpack:///./src/components/helpers/select-list.vue?00bf","webpack:///./src/components/helpers/show-selector.vue?1e83","webpack:///./src/components/anidb-release-group-ui.vue?d4c6","webpack:///src/components/app-header.vue","webpack:///./src/components/app-header.vue?a433","webpack:///src/components/backstretch.vue","webpack:///./src/components/config.vue?74a6","webpack:///src/components/config-post-processing.vue","webpack:///src/components/home.vue","webpack:///./src/components/irc.vue?d114","webpack:///src/components/manual-post-process.vue","webpack:///src/components/root-dirs.vue","webpack:///./src/components/root-dirs.vue?1571","webpack:///src/components/show.vue","webpack:///src/components/show-header.vue","webpack:///./src/components/show-header.vue?f042","webpack:///src/components/snatch-selection.vue","webpack:///src/components/status.vue","webpack:///./src/store/mutation-types.js","webpack:///./src/store/modules/auth.js","webpack:///./src/store/modules/clients.js","webpack:///./src/store/modules/config.js","webpack:///./src/store/modules/defaults.js","webpack:///./src/store/modules/metadata.js","webpack:///./src/store/modules/notifications.js","webpack:///./src/store/modules/notifiers/boxcar2.js","webpack:///./src/store/modules/notifiers/email.js","webpack:///./src/store/modules/notifiers/emby.js","webpack:///./src/store/modules/notifiers/growl.js","webpack:///./src/store/modules/notifiers/kodi.js","webpack:///./src/store/modules/notifiers/libnotify.js","webpack:///./src/store/modules/notifiers/nmj.js","webpack:///./src/store/modules/notifiers/nmjv2.js","webpack:///./src/store/modules/notifiers/plex.js","webpack:///./src/store/modules/notifiers/prowl.js","webpack:///./src/store/modules/notifiers/pushalot.js","webpack:///./src/store/modules/notifiers/pushbullet.js","webpack:///./src/store/modules/notifiers/join.js","webpack:///./src/store/modules/notifiers/pushover.js","webpack:///./src/store/modules/notifiers/py-tivo.js","webpack:///./src/store/modules/notifiers/slack.js","webpack:///./src/store/modules/notifiers/synology.js","webpack:///./src/store/modules/notifiers/synology-index.js","webpack:///./src/store/modules/notifiers/telegram.js","webpack:///./src/store/modules/notifiers/trakt.js","webpack:///./src/store/modules/notifiers/twitter.js","webpack:///./src/store/modules/notifiers/index.js","webpack:///./src/store/modules/qualities.js","webpack:///./src/store/modules/shows.js","webpack:///./src/store/modules/search.js","webpack:///./src/store/modules/socket.js","webpack:///./src/store/modules/statuses.js","webpack:///./src/store/index.js","webpack:///./src/components/irc.vue?1ae7","webpack:///src/components/irc.vue","webpack:///./src/components/irc.vue?7a24","webpack:///./src/components/irc.vue","webpack:///./src/components/add-recommended.vue?e31e","webpack:///./src/components/add-recommended.vue?2753","webpack:///src/components/add-recommended.vue","webpack:///./src/components/add-recommended.vue","webpack:///./src/components/login.vue?073b","webpack:///./src/components/login.vue?57e6","webpack:///src/components/login.vue","webpack:///./src/components/login.vue","webpack:///./src/components/add-shows.vue?c057","webpack:///./src/components/add-shows.vue?9503","webpack:///src/components/add-shows.vue","webpack:///./src/components/add-shows.vue","webpack:///./src/components/config.vue?1065","webpack:///./src/components/config.vue?df93","webpack:///src/components/config.vue","webpack:///./src/components/config.vue","webpack:///./src/components/http/404.vue?0abf","webpack:///./src/components/http/404.vue?03e7","webpack:///src/components/http/404.vue","webpack:///./src/components/http/404.vue","webpack:///./src/components/config-post-processing.vue?c03b","webpack:///./src/components/config-post-processing.vue?e020","webpack:///./src/components/config-post-processing.vue","webpack:///./src/components/helpers/app-link.vue?b485","webpack:///./src/components/helpers/app-link.vue?216d","webpack:///./src/components/helpers/config-textbox-number.vue?489b","webpack:///./src/components/helpers/config-textbox-number.vue?bd5f","webpack:///./src/components/helpers/config-textbox.vue?93d8","webpack:///./src/components/helpers/config-textbox.vue?abb5","webpack:///./src/components/helpers/config-toggle-slider.vue?2913","webpack:///./src/components/helpers/config-toggle-slider.vue?5b3d","webpack:///./src/components/helpers/file-browser.vue?bd46","webpack:///./src/components/helpers/file-browser.vue?b533","webpack:///./src/components/helpers/plot-info.vue?67cc","webpack:///./src/components/helpers/plot-info.vue?3ca4","webpack:///./src/components/helpers/quality-pill.vue?d417","webpack:///./src/components/helpers/quality-pill.vue?15d1","webpack:///./src/components/helpers/scroll-buttons.vue?4082","webpack:///./src/components/helpers/scroll-buttons.vue?4d17","webpack:///./src/components/helpers/select-list.vue?4f20","webpack:///./src/components/helpers/select-list.vue?e247","webpack:///./src/components/helpers/show-selector.vue?b49a","webpack:///./src/components/helpers/show-selector.vue?f1c0","webpack:///./src/components/anidb-release-group-ui.vue?108b","webpack:///./src/components/anidb-release-group-ui.vue?7506","webpack:///./src/components/app-header.vue?7b5a","webpack:///./src/components/app-header.vue?51b0","webpack:///./src/components/config.vue?b8d8","webpack:///./src/components/config.vue?395f","webpack:///./src/components/irc.vue?ecce","webpack:///./src/components/irc.vue?e7e0","webpack:///./src/components/root-dirs.vue?73c7","webpack:///./src/components/root-dirs.vue?3e09","webpack:///./src/components/show-header.vue?f85b","webpack:///./src/components/show-header.vue?fa1f"],"names":["components_anidb_release_group_uivue_type_script_lang_js_","name","props","blacklist","type","Array","default","whitelist","allGroups","data","index","allReleaseGroups","newGroup","mounted","this","createIndexedObjects","methods","toggleItem","release","map","x","id","toggled","releaseGroups","list","_this","_iteratorNormalCompletion","_didIteratorError","_iteratorError","undefined","_step","_loop","value","itemAsObject","Object","assign","memberOf","filter","group","length","push","_iterator","Symbol","iterator","next","done","err","return","moveToList","_this2","_iteratorNormalCompletion2","_didIteratorError2","_iteratorError2","_step2","_loop2","inList","find","releaseGroup","_iterator2","deleteFromList","computed","itemsWhitelist","itemsBlacklist","itemsReleaseGroups","showDeleteFromWhitelist","showDeleteFromBlacklist","watch","handler","$emit","deep","newValue","anidb_release_group_ui","componentNormalizer","_vm","_h","$createElement","_c","_self","staticClass","_v","attrs","src","on","click","$event","_e","_l","key","class","active","_s","directives","rawName","expression","placeholder","domProps","input","target","composing","_m","components_add_show_optionsvue_type_script_lang_js_","components","AnidbReleaseGroupUi","ConfigToggleSlider","helpers","showName","String","required","enableAnimeOptions","Boolean","saving","selectedStatus","selectedStatusAfter","quality","allowed","preferred","selectedSubtitleEnabled","selectedSeasonFoldersEnabled","selectedAnimeEnabled","selectedSceneEnabled","allgroups","defaultConfig","update","status","statusAfter","$nextTick","$watch","vm","join","getReleaseGroups","params","series_name","api","get","timeout","then","response","catch","error","$snotify","warning","concat","console","warn","_this3","subtitles","seasonFolders","anime","scene","onChangeReleaseGroupsAnime","items","item","saveDefaults","_this4","$store","config","showDefaults","combinedQualities","dispatch","section","success","message","finally","_objectSpread","vuex_esm","state","namingForceFolders","subtitlesEnabled","enabled","episodeStatuses","statuses","defaultEpisodeStatusOptions","_this$episodeStatuses","strings","values","skipped","wanted","ignored","text","utils","saveDefaultsDisabled","every","asyncComputed","result","groups","Promise","resolve","immediate","add_show_options","overall-quality","update:quality:allowed","update:quality:preferred","label","explanations","change","$$selectedVal","prototype","call","options","o","selected","_value","multiple","option","disabled","all-groups","preventDefault","for","components_app_headervue_type_script_lang_js_","app_header","role","data-toggle","data-target","toolsBadgeCount","toolsBadgeClass","href","title","staticStyle","height","alt","topMenu","aria-haspopup","data-hover","recentShows","recentShow","link","clear","linkVisible","news","unread","donationsUrl","logs","numErrors","numWarnings","warningLevel","nativeOn","confirmDialog","components_backstretchvue_type_script_lang_js_","backstretch","components_homevue_type_script_lang_js_","home","home_render","home_staticRenderFns","components_manual_post_processvue_type_script_lang_js_","manual_post_process","manual_post_process_render","manual_post_process_staticRenderFns","components_root_dirsvue_type_script_lang_js_","root_dirs","_g","_b","ref","size","selectedRootDir","$attrs","$listeners","curDir","path","_f","add","edit","remove","setDefault","components_showvue_type_script_lang_js_","show","show_render","show_staticRenderFns","components_snatch_selectionvue_type_script_lang_js_","snatch_selection","snatch_selection_render","snatch_selection_staticRenderFns","components_statusvue_type_script_lang_js_","components_status","status_render","status_staticRenderFns","__webpack_require__","d","__webpack_exports__","webRoot","apiKey","apiRoute","apiv1","axios__WEBPACK_IMPORTED_MODULE_0__","axios__WEBPACK_IMPORTED_MODULE_0___default","n","document","body","getAttribute","axios","create","baseURL","headers","Accept","Content-Type","X-Api-Key","helpers_app_linkvue_type_script_lang_js_","to","indexerId","indexerName","indexers","keys","indexer","parseInt","computedBase","querySelectorAll","computedHref","replace","isIRC","startsWith","isAbsolute","test","isExternal","base","isHashPath","anonymisedHref","anonRedirect","matchingVueRoute","normalise","str","router","routes","_ref","linkProperties","is","_typeof","$route","meta","converted","window","loadMainApp","location","hash","newHash","endsWith","substr","URL","rel","falseLink","app_link","tag","router-link","false-link","_t","helpers_assetvue_type_script_lang_js_","AppLink","showSlug","cls","asset","helpers_config_templatevue_type_script_lang_js_","labelFor","config_template","helpers_config_textbox_numbervue_type_script_lang_js_","Number","inputClass","min","max","step","localValue","updateValue","config_textbox_number","explanation","helpers_config_textboxvue_type_script_lang_js_","config_textbox","checked","isArray","_i","$$a","$$el","$$c","$$i","slice","_q","helpers_config_toggle_slidervue_type_script_lang_js_","ToggleButton","localChecked","config_toggle_slider","width","sync","model","callback","$$v","helpers_file_browservue_type_script_lang_js_","file_browser","showBrowseButton","currentPath","openDialog","display","keyup","indexOf","_k","keyCode","browse","file","mouseover","toggleFolder","mouseout","fileClicked","isFile","font-size","helpers_language_selectvue_type_script_lang_js_","language_select","helpers_name_patternvue_type_script_lang_js_","name_pattern","isEnabled","selectedNamingPattern","updatePatternSamples","preset","pattern","example","padding-top","customName","showLegend","isCustom","getDateFormat","selectedMultiEpStyle","multiEpStyle","namingExample","namingExampleMulti","animeType","colspan","helpers_plot_infovue_type_script_lang_js_","plot_info","plotInfoClass","helpers_quality_pillvue_type_script_lang_js_","validator","showTitle","override","includes","quality_pillvue_type_script_lang_js_objectSpread","qualityValues","qualities","qualityValueStrings","qualityAnySets","anySets","qualityAnySetStrings","qualityPresets","presets","qualityPresetStrings","qualityCssClassStrings","cssClass","splitQuality","curQual","setHDTV","makeQualitySet","setWEBDL","setBluRay","set720p","set1080p","setUHD4K","setUHD8K","pill","sumAllowed","isSubsetOf","anyhdtv","anywebdl","anybluray","hdbluray","fullhdbluray","uhd4kbluray","uhd8kbluray","_toConsumableArray","sort","a","b","reduce","curQuality","_len","arguments","_key","set1","set2","quality_pill","helpers_scroll_buttonsvue_type_script_lang_js_","scroll_buttons","showToTop","scrollTop","showLeftRight","scrollLeft","scrollRight","helpers_select_listvue_type_script_lang_js_","listItems","unique","csvEnabled","editItems","newItem","indexCounter","csv","csvMode","created","unwatchProp","sanitize","addItem","i","addNewItem","deleteItem","e","$refs","newItemInput","focus","removeEmpty","syncValues","split","forEach","trim","switchFields","select_list","$set","helpers_show_selectorvue_type_script_lang_js_","followSelection","selectClass","selectedShowSlug","lock","show_selectorvue_type_script_lang_js_objectSpread","shows","showLists","animeSplitHome","sortArticle","lists","sortKey","toLowerCase","showA","showB","titleA","titleB","whichList","newSlug","selectedShow","slug","showId","show_selector","hidden","curShowList","helpers_state_switchvue_type_script_lang_js_","theme","realState","charAt","toUpperCase","null","true","false","state_switch","combineQualities","humanFileSize","isDevelopment","process","allowedQualities","preferredQualities","reducer","accumulator","currentValue","bytes","useDecimal","thresh","Math","abs","units","u","toFixed","components_show_headervue_type_script_lang_js_","component","data-showname","data-indexer-name","data-series-id","season","episode","manualSearchType","seasons","cursor","toggleSpecials","displaySpecials","position","jumpToSeason","data-season","reverse","$index","queueItem","action","show-slug","rating","imdb","qtip-content","votes","style","country","margin-left","vertical-align","imdbInfo","year","runtimes","runtime","margin-top","start","trakt","showIndexerUrl","indexerConfig","icon","tvdb","dedupeGenres","genres","genre","toString","summaryFanArt","fanartBackground","padding-bottom","clamp","less","plot","toggle","getPreset","network","airs","airsFormatValid","color","defaultEpisodeStatus","location-invalid","locationValid","aliases","requiredWords","ignoredWords","preferredWords","undesiredWords","undesired","airdateOffset","getCountryISO2ToISO3","language","onError","themeName","paused","airByDate","sports","dvdOrder","showHideRows","episodeSummary","Wanted","Allowed","Preferred","Skipped","Snatched","selectEpisodesClicked","clearEpisodeSelectionClicked","changeStatusClicked","vue_router__WEBPACK_IMPORTED_MODULE_0__","header","bind","VueRouter","mode","beforeEach","from","content","module","locals","exports","includeFiles","autocomplete","localStorageKey","initialDir","files","lastPath","url","autocompleteUrl","fileBrowserDialog","localStorageSupport","localStorage","getItem","log","testLocalStorage","fileBrowser","storedPath","locationInput","event","ui","set","newPath","children","classList","$","$el","fileBrowserSearchBox","debug","dialog","_api__WEBPACK_IMPORTED_MODULE_0__","shift","openFileBrowser","fileBrowserFileList","dialogClass","my","at","of","minWidth","maxHeight","maxWidth","modal","autoOpen","removeAttribute","append","resultField","query","collision","source","request","escapeRegex","term","ajax","dataType","matcher","RegExp","grep","open","removeClass","_renderItem","ul","resultItem","fullMatch","appendTo","available","blank","flags","bfhlanguages","evt","currentTarget","val","vue_js_toggle_button__WEBPACK_IMPORTED_MODULE_1__","namingPattern","namingPresets","multiEpStyles","animeNamingType","flagLoaded","availableMultiEpStyles","lastSelectedPattern","format","date_fns_format__WEBPACK_IMPORTED_MODULE_0___default","Date","testNaming","anime_type","multi","_api__WEBPACK_IMPORTED_MODULE_2__","res","checkNaming","isMulti","custom","el","qtip","content.text","style.classes","css","updateCustomName","presetsPatterns","foundPattern","newPattern","oldPattern","hasPlot","qt","statusText","solo","adjust","y","tip","corner","method","classes","scrollTo","animate","dest","offset","top","initHorizontalScroll","scrollDiv","scrollbarVisible","scrollWidth","clientWidth","_helpers__WEBPACK_IMPORTED_MODULE_1__","vuex__WEBPACK_IMPORTED_MODULE_0__","isAuthenticated","auth","username","user","loggingLevels","notifiers","torrents","failedDownloads","postProcessing","kodi","plex","emby","server","host","manageTorrents","subtitleMissed","subtitleMissedPP","postponeIfNoSubs","mouseenter","$target","stop","delay","fadeIn","attr","mouseleave","fadeOut","navigator","maxTouchPoints","confirmButton","cancelButton","post","button","confirm","$element","opacity","_helpers__WEBPACK_IMPORTED_MODULE_2__","FileBrowser","NamePattern","SelectList","processMethods","timezoneOptions","naming","multiEp","enableCustomNamingSports","enableCustomNamingAirByDate","patternSports","patternAirByDate","enableCustomNamingAnime","patternAnime","animeMultiEp","stripYear","showDownloadDir","processAutomatically","processMethod","deleteRarContent","unpack","noDelete","reflinkAvailable","postponeIfSyncFiles","autoPostprocessorFrequency","airdateEpisodes","moveAssociatedFiles","allowedExtensions","addShowsWithoutDir","createMissingShowDirs","renameEpisodes","nfoRename","syncFiles","fileTimestampTimezone","extraScripts","extraScriptsUrl","multiEpStrings","metadataProviders","metadataProviderSelected","onChangeSyncFiles","onChangeAllowedExtensions","onChangeExtraScripts","saveNaming","configLoaded","saveNamingSports","saveNamingAbd","saveNamingAnime","save","metadata","_config$postProcessin","rest","_objectWithoutProperties","getFirstEnabledMetadataProvider","firstEnabledProvider","provider","showMetadata","episodeMetadata","multiEpStringsSelect","k","beforeMount","tabs","config.postProcessing","metadata.metadataProviders","template","_helpers__WEBPACK_IMPORTED_MODULE_3__","layout","page","initializePosterSizeSlider","posterSize","resizePosters","newSize","fontSize","logoWidth","borderRadius","borderWidth","hide","Storage","isNaN","slider","setItem","isotope","trigger","lodash_debounce__WEBPACK_IMPORTED_MODULE_1___default","sortBy","sortAscending","patch","selectedRootIndex","info","reload","imgLazyLoad","LazyLoad","threshold","addEventListener","activate","each","percentage","classToAdd","progressbar","addClass","parent","tablesorter","sortList","textExtraction","0","node","1","3","prop","4","5","6","7","8","10","widgets","sorter","2","widgetOptions","filter_columnFilters","filter_hideFilters","filter_saveFilters","filter_functions","f","pct","floor","match","parseFloat","isFinite","columnSelector_mediaquery","sortStable","sortAppend","handleScroll","imagesLoaded","itemSelector","MEDUSA","posterSortby","posterSortdir","layoutMode","masonry","isFitWidth","getSortData","itemElem","date","POSITIVE_INFINITY","progress","NEGATIVE_INFINITY","posterHoverTimer","poster","setTimeout","popup","clone","origLeft","left","origTop","margin","zIndex","newTop","newLeft","scrollBottom","innerHeight","innerWidth","clearTimeout","popover","placement","html","columnSelector","attachTo","rootDir","rootDirs","rootDirIndex","backendDirs","rootDirOptions","sortable","axis","scroll","tolerance","helper","handle","cancel","draggedItem","originalPosition","prependTo","showListOrder","toArray","once","inheritAttrs","rawRootDirs","transformRaw","paths","rd","selectedDir","newRootDir","defaultRootDir","defaultDir","filters","markDefault","saveRootDirs","nFileBrowser","found","isFirst","wasDefault","accumlator","isNewRootDir","oldDirIndex","findIndex","oldDirPath","filteredRootDirs","newSelected","defaultIndex","splice","oldValue","JSON","stringify","PlotInfo","ShowHeader","_show_header_vue__WEBPACK_IMPORTED_MODULE_3__","metaInfo","titleTemplate","showIndexer","getShowById","indexername","seriesid","getShow","setEpisodeSceneNumbering","setAbsoluteSceneNumbering","setInputValidInvalid","getSeasonSceneExceptions","commit","detailed","reflowLayout","ajaxEpSearch","colorRow","startAjaxEpisodeSubtitles","ajaxEpSubtitlesSearch","ajaxEpRedownloadSubtitle","seasCheck","seasNo","collapse","seasonIdentifier","element","lastCheck","shiftKey","check","tableRow","forSeason","forEpisode","m","onlyEpisode","sceneSeason","sceneEpisode","isValid","forAbsolute","sceneAbsolute","columnSelector_saveColumns","columnSelector_layout","columnSelector_cssChecked","exec","moveSummaryBackground","movecheckboxControlsBackground","attachImdbTooltip","seriesId","getJSON","errorMessage","alert","valid","background-color","font-weight","_api__WEBPACK_IMPORTED_MODULE_1__","setSeasonSceneExceptions","seasonExceptions","nameExceptions","foundInXem","xemNumbering","indexerSeason","xemSeason","_helpers__WEBPACK_IMPORTED_MODULE_7__","Asset","QualityPill","StateSwitch","Truncate","vue_truncate_collapsed__WEBPACK_IMPORTED_MODULE_0__","showSeason","showEpisode","vuex__WEBPACK_IMPORTED_MODULE_4__","specials","search","indexerUrl","showUrl","activeShowQueueStatuses","showQueueStatus","showGenres","summary","Unaired","Snatched (Proper)","Snatched (Best)","Unset","Archived","episodes","changeStatusOptions","defaultOptions","changeQualityOptions","_utils__WEBPACK_IMPORTED_MODULE_6__","setQuality","patchData","_api__WEBPACK_IMPORTED_MODULE_5__","epArr","whichClass","numRows","seasonNo","is_visible__WEBPACK_IMPORTED_MODULE_2__","array","Set","country_language__WEBPACK_IMPORTED_MODULE_1__","iso639_2en","vue_scrollto__WEBPACK_IMPORTED_MODULE_3__","container","easing","_show_header_vue__WEBPACK_IMPORTED_MODULE_2__","updateSpinner","showSpinner","spinner","themeSpinner","empty","checkCacheUpdates","repeat","pollInterval","checkIsTrue","urlParams","isNumeric","contentType","removeAttr","complete","timeago","fn","loadContainer","loadingTxt","errorTxt","load","forceSearch","manual_search_type","perform_search","9","11","parser","hasClass","switchClass","ADD_CONFIG","ADD_SHOW","tokens","access","refresh","mutations","_defineProperty","_mutations","getters","actions","login","context","credentials","apiLogin","logout","clients","authType","dir","highBandwidth","labelAnime","rpcUrl","seedLocation","seedTime","password","verifySSL","testStatus","nzb","nzbget","category","categoryAnime","categoryAnimeBacklog","categoryBacklog","priority","useHttps","sabnzbd","forced","modules_config","wikiUrl","localUser","locale","cacheDir","databaseVersion","major","minor","programDir","dataDir","animeSplitHomeInTabs","rpcurl","allSeasons","history","schedule","dbPath","configFile","trimZero","gitUsername","branch","commitHash","main","externalMappings","statusMap","traktIndexers","validLanguages","langabbvToId","apiParams","useZip","baseUrl","identifier","mappedTo","scene_loc","xemOrigin","tmdb","tvmaze","sourceUrl","fanartBackgroundOpacity","appArgs","comingEpsDisplayPaused","timePreset","fuzzyDating","backlogOverview","period","lastRead","latest","deleteFailed","sslVersion","pythonVersion","comingEpsSort","githubUrl","datePreset","subtitlesMulti","pid","os","logDir","config_defineProperty","getConfig","sections","setConfig","_ref2","updateConfig","_ref3","setLayout","_ref4","defaults","akas","cache","classification","requiredWordsExclude","ignoredWordsExclude","countries","certificates","countryCodes","imdbId","imdbInfoId","lastUpdate","nextAirDate","showType","metadata_defineProperty","notifications","notifications_defineProperty","notifications_mutations","enable","disable","displayNotification","boxcar2","notifyOnSnatch","notifyOnDownload","notifyOnSubtitleDownload","accessToken","email","port","tls","addressList","subject","growl","alwaysOn","libraryCleanPending","cleanLibrary","library","full","onlyFirst","libnotify","nmj","database","mount","nmjv2","dbloc","client","updateLibrary","https","token","prowl","messageTitle","pushalot","authToken","pushbullet","device","pushover","userKey","sound","py_tivo","shareName","slack","webhook","synology","synology_index","telegram","pinUrl","defaultIndexer","syncRemove","syncWatchlist","methodAdd","removeWatchlist","removeSerieslist","removeShowFromApplication","startPaused","blacklistName","twitter","dmto","prefix","directMessage","notifiers_defineProperty","modules","pyTivo","synologyIndex","qualities_defineProperty","modules_shows","currentShow","shows_defineProperty","shows_mutations","existingShow","newShow","Vue","getShowByTitle","getSeason","getEpisode","_ref5","getCurrentShow","rootState","_ref6","fetch","reject","getShows","limit","totalPages","pageRequests","newPage","all","ignoreUnknownSubs","ignoredSubsList","general","minDailySearchFrequency","minBacklogFrequency","dailySearchFrequency","checkPropersInterval","usenetRetention","maxCacheAge","backlogDays","torrentCheckerFrequency","backlogFrequency","cacheTrimming","downloadPropers","useFailedDownloads","minTorrentCheckerFrequency","removeFromClient","randomizeProviders","propersSearchDays","allowHighPriority","trackersList","search_defineProperty","socket","isConnected","messages","reconnectError","socket_defineProperty","socket_mutations","existingMessage","count","statuses_defineProperty","Store","Vuex","use","_window$location","protocol","proto","store","websocketUrl","VueNativeSock","reconnection","reconnectionAttempts","reconnectionDelay","passToStoreHandler","eventName","eventData","parse","SOCKET_ONOPEN","SOCKET_ONCLOSE","SOCKET_ONERROR","SOCKET_ONMESSAGE","SOCKET_RECONNECT","SOCKET_RECONNECT_ERROR","components_ircvue_type_script_lang_js_","frameSrc","components_add_recommendedvue_type_script_lang_js_","components_loginvue_type_script_lang_js_","components_add_showsvue_type_script_lang_js_","components_configvue_type_script_lang_js_","prettyPrintJSON","cellspacing","border","cellpadding","runsInDocker","http_404vue_type_script_lang_js_","components_config_post_processingvue_type_script_lang_js_","submit","initial-dir","modifiers","number","_n","blur","$forceUpdate","csv-enabled","list-items","naming-pattern","naming-presets","multi-ep-style","multi-ep-styles","flag-loaded","enabled-naming-custom","anime-naming-type","fanart","banner","episodeThumbnails","seasonPosters","seasonBanners","seasonAllPoster","seasonAllBanner","innerHTML","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_app_link_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_config_textbox_number_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_config_textbox_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_config_toggle_slider_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_file_browser_vue_vue_type_style_index_0_id_5a327762_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_plot_info_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_quality_pill_vue_vue_type_style_index_0_id_b683ee7a_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_scroll_buttons_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_select_list_vue_vue_type_style_index_0_id_ac609192_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_show_selector_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_anidb_release_group_ui_vue_vue_type_style_index_0_id_10f4092b_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_app_header_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_config_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_irc_vue_vue_type_style_index_0_id_60f89f30_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_root_dirs_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__","_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_show_header_vue_vue_type_style_index_0_id_e712fe74_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__"],"mappings":"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","file":"js/medusa-runtime.js","sourcesContent":["import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./anidb-release-group-ui.vue?vue&type=template&id=10f4092b&scoped=true&\"\nimport script from \"./anidb-release-group-ui.vue?vue&type=script&lang=js&\"\nexport * from \"./anidb-release-group-ui.vue?vue&type=script&lang=js&\"\nimport style0 from \"./anidb-release-group-ui.vue?vue&type=style&index=0&id=10f4092b&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"10f4092b\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"anidb-release-group-ui-wrapper top-10 max-width\"},[_c('div',{staticClass:\"row\"},[_c('div',{staticClass:\"col-sm-4 left-whitelist\"},[_c('span',[_vm._v(\"Whitelist\")]),(_vm.showDeleteFromWhitelist)?_c('img',{staticClass:\"deleteFromWhitelist\",attrs:{\"src\":\"images/no16.png\"},on:{\"click\":function($event){return _vm.deleteFromList('whitelist')}}}):_vm._e(),_vm._v(\" \"),_c('ul',[_vm._l((_vm.itemsWhitelist),function(release){return _c('li',{key:release.id,class:{active: release.toggled},on:{\"click\":function($event){release.toggled = !release.toggled}}},[_vm._v(_vm._s(release.name))])}),_vm._v(\" \"),_c('div',{staticClass:\"arrow\",on:{\"click\":function($event){return _vm.moveToList('whitelist')}}},[_c('img',{attrs:{\"src\":\"images/curved-arrow-left.png\"}})])],2)]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-4 center-available\"},[_c('span',[_vm._v(\"Release groups\")]),_vm._v(\" \"),_c('ul',[_vm._l((_vm.itemsReleaseGroups),function(release){return _c('li',{key:release.id,staticClass:\"initial\",class:{active: release.toggled},on:{\"click\":function($event){release.toggled = !release.toggled}}},[_vm._v(_vm._s(release.name))])}),_vm._v(\" \"),_c('div',{staticClass:\"arrow\",on:{\"click\":function($event){return _vm.moveToList('releasegroups')}}},[_c('img',{attrs:{\"src\":\"images/curved-arrow-left.png\"}})])],2)]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-4 right-blacklist\"},[_c('span',[_vm._v(\"Blacklist\")]),(_vm.showDeleteFromBlacklist)?_c('img',{staticClass:\"deleteFromBlacklist\",attrs:{\"src\":\"images/no16.png\"},on:{\"click\":function($event){return _vm.deleteFromList('blacklist')}}}):_vm._e(),_vm._v(\" \"),_c('ul',[_vm._l((_vm.itemsBlacklist),function(release){return _c('li',{key:release.id,class:{active: release.toggled},on:{\"click\":function($event){release.toggled = !release.toggled}}},[_vm._v(_vm._s(release.name))])}),_vm._v(\" \"),_c('div',{staticClass:\"arrow\",on:{\"click\":function($event){return _vm.moveToList('blacklist')}}},[_c('img',{attrs:{\"src\":\"images/curved-arrow-left.png\"}})])],2)])]),_vm._v(\" \"),_c('div',{staticClass:\"row\",attrs:{\"id\":\"add-new-release-group\"}},[_c('div',{staticClass:\"col-md-4\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.newGroup),expression:\"newGroup\"}],staticClass:\"form-control input-sm\",attrs:{\"type\":\"text\",\"placeholder\":\"add custom group\"},domProps:{\"value\":(_vm.newGroup)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.newGroup=$event.target.value}}})]),_vm._v(\" \"),_vm._m(0)])])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"col-md-8\"},[_c('p',[_vm._v(\"Use the input to add custom whitelist / blacklist release groups. Click on the \"),_c('img',{attrs:{\"src\":\"images/curved-arrow-left.png\"}}),_vm._v(\" to add it to the correct list.\")])])}]\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-show-options.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-show-options.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./add-show-options.vue?vue&type=template&id=36c5afdc&\"\nimport script from \"./add-show-options.vue?vue&type=script&lang=js&\"\nexport * from \"./add-show-options.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"add-show-options-content\"}},[_c('fieldset',{staticClass:\"component-group-list\"},[_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_vm._m(0),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('quality-chooser',{attrs:{\"overall-quality\":_vm.defaultConfig.quality},on:{\"update:quality:allowed\":function($event){_vm.quality.allowed = $event},\"update:quality:preferred\":function($event){_vm.quality.preferred = $event}}})],1)])]),_vm._v(\" \"),(_vm.subtitlesEnabled)?_c('div',{attrs:{\"id\":\"use-subtitles\"}},[_c('config-toggle-slider',{attrs:{\"label\":\"Subtitles\",\"id\":\"subtitles\",\"value\":_vm.selectedSubtitleEnabled,\"explanations\":['Download subtitles for this show?']},on:{\"input\":function($event){_vm.selectedSubtitleEnabled = $event}}})],1):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_vm._m(1),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.selectedStatus),expression:\"selectedStatus\"}],staticClass:\"form-control form-control-inline input-sm\",attrs:{\"id\":\"defaultStatus\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.selectedStatus=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},_vm._l((_vm.defaultEpisodeStatusOptions),function(option){return _c('option',{key:option.value,domProps:{\"value\":option.value}},[_vm._v(_vm._s(option.text))])}),0)])])]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_vm._m(2),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.selectedStatusAfter),expression:\"selectedStatusAfter\"}],staticClass:\"form-control form-control-inline input-sm\",attrs:{\"id\":\"defaultStatusAfter\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.selectedStatusAfter=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},_vm._l((_vm.defaultEpisodeStatusOptions),function(option){return _c('option',{key:option.value,domProps:{\"value\":option.value}},[_vm._v(_vm._s(option.text))])}),0)])])]),_vm._v(\" \"),_c('config-toggle-slider',{attrs:{\"label\":\"Season Folders\",\"id\":\"season_folders\",\"value\":_vm.selectedSeasonFoldersEnabled,\"disabled\":_vm.namingForceFolders,\"explanations\":['Group episodes by season folders?']},on:{\"input\":function($event){_vm.selectedSeasonFoldersEnabled = $event}}}),_vm._v(\" \"),(_vm.enableAnimeOptions)?_c('config-toggle-slider',{attrs:{\"label\":\"Anime\",\"id\":\"anime\",\"explanations\":['Is this show an Anime?'],\"value\":_vm.selectedAnimeEnabled},on:{\"input\":function($event){_vm.selectedAnimeEnabled = $event}}}):_vm._e(),_vm._v(\" \"),(_vm.enableAnimeOptions && _vm.selectedAnimeEnabled)?_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_vm._m(3),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('anidb-release-group-ui',{staticClass:\"max-width\",attrs:{\"blacklist\":_vm.release.blacklist,\"whitelist\":_vm.release.whitelist,\"all-groups\":_vm.release.allgroups},on:{\"change\":_vm.onChangeReleaseGroupsAnime}})],1)])]):_vm._e(),_vm._v(\" \"),_c('config-toggle-slider',{attrs:{\"label\":\"Scene Numbering\",\"id\":\"scene\",\"value\":_vm.selectedSceneEnabled,\"explanations\":['Is this show scene numbered?']},on:{\"input\":function($event){_vm.selectedSceneEnabled = $event}}}),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_vm._m(4),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('button',{staticClass:\"btn-medusa btn-inline\",attrs:{\"type\":\"button\",\"disabled\":_vm.saving || _vm.saveDefaultsDisabled},on:{\"click\":function($event){$event.preventDefault();return _vm.saveDefaults($event)}}},[_vm._v(\"Save Defaults\")])])])])],1)])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"customQuality\"}},[_c('span',[_vm._v(\"Quality\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"defaultStatus\"}},[_c('span',[_vm._v(\"Status for previously aired episodes\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"defaultStatusAfter\"}},[_c('span',[_vm._v(\"Status for all future episodes\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"anidbReleaseGroup\"}},[_c('span',[_vm._v(\"Release Groups\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"saveDefaultsButton\"}},[_c('span',[_vm._v(\"Use current values as the defaults\")])])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./app-header.vue?vue&type=template&id=33b81de2&\"\nimport script from \"./app-header.vue?vue&type=script&lang=js&\"\nexport * from \"./app-header.vue?vue&type=script&lang=js&\"\nimport style0 from \"./app-header.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('nav',{staticClass:\"navbar navbar-default navbar-fixed-top hidden-print\",attrs:{\"role\":\"navigation\"}},[_c('div',{staticClass:\"container-fluid\"},[_c('div',{staticClass:\"navbar-header\"},[_c('button',{staticClass:\"navbar-toggle collapsed\",attrs:{\"type\":\"button\",\"data-toggle\":\"collapse\",\"data-target\":\"#main_nav\"}},[(_vm.toolsBadgeCount > 0)?_c('span',{class:(\"floating-badge\" + _vm.toolsBadgeClass)},[_vm._v(_vm._s(_vm.toolsBadgeCount))]):_vm._e(),_vm._v(\" \"),_c('span',{staticClass:\"sr-only\"},[_vm._v(\"Toggle navigation\")]),_vm._v(\" \"),_c('span',{staticClass:\"icon-bar\"}),_vm._v(\" \"),_c('span',{staticClass:\"icon-bar\"}),_vm._v(\" \"),_c('span',{staticClass:\"icon-bar\"})]),_vm._v(\" \"),_c('app-link',{staticClass:\"navbar-brand\",attrs:{\"href\":\"home/\",\"title\":\"Medusa\"}},[_c('img',{staticClass:\"img-responsive pull-left\",staticStyle:{\"height\":\"50px\"},attrs:{\"alt\":\"Medusa\",\"src\":\"images/medusa.png\"}})])],1),_vm._v(\" \"),(_vm.isAuthenticated)?_c('div',{staticClass:\"collapse navbar-collapse\",attrs:{\"id\":\"main_nav\"}},[_c('ul',{staticClass:\"nav navbar-nav navbar-right\"},[_c('li',{staticClass:\"navbar-split dropdown\",class:{ active: _vm.topMenu === 'home' },attrs:{\"id\":\"NAVhome\"}},[_c('app-link',{staticClass:\"dropdown-toggle\",attrs:{\"href\":\"home/\",\"aria-haspopup\":\"true\",\"data-toggle\":\"dropdown\",\"data-hover\":\"dropdown\"}},[_c('span',[_vm._v(\"Shows\")]),_vm._v(\" \"),_c('b',{staticClass:\"caret\"})]),_vm._v(\" \"),_c('ul',{staticClass:\"dropdown-menu\"},[_c('li',[_c('app-link',{attrs:{\"href\":\"home/\"}},[_c('i',{staticClass:\"menu-icon-home\"}),_vm._v(\" Show List\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"addShows/\"}},[_c('i',{staticClass:\"menu-icon-addshow\"}),_vm._v(\" Add Shows\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"addRecommended/\"}},[_c('i',{staticClass:\"menu-icon-addshow\"}),_vm._v(\" Add Recommended Shows\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"home/postprocess/\"}},[_c('i',{staticClass:\"menu-icon-postprocess\"}),_vm._v(\" Manual Post-Processing\")])],1),_vm._v(\" \"),(_vm.recentShows.length > 0)?[_c('li',{staticClass:\"divider\",attrs:{\"role\":\"separator\"}}),_vm._v(\" \"),_vm._l((_vm.recentShows),function(recentShow){return _c('li',{key:recentShow.link},[_c('app-link',{attrs:{\"href\":recentShow.link}},[_c('i',{staticClass:\"menu-icon-addshow\"}),_vm._v(\" \"+_vm._s(recentShow.name)+\"\\n \")])],1)})]:_vm._e()],2),_vm._v(\" \"),_c('div',{staticStyle:{\"clear\":\"both\"}})],1),_vm._v(\" \"),_c('li',{class:{ active: _vm.topMenu === 'schedule' },attrs:{\"id\":\"NAVschedule\"}},[_c('app-link',{attrs:{\"href\":\"schedule/\"}},[_vm._v(\"Schedule\")])],1),_vm._v(\" \"),_c('li',{class:{ active: _vm.topMenu === 'history' },attrs:{\"id\":\"NAVhistory\"}},[_c('app-link',{attrs:{\"href\":\"history/\"}},[_vm._v(\"History\")])],1),_vm._v(\" \"),_c('li',{staticClass:\"navbar-split dropdown\",class:{ active: _vm.topMenu === 'manage' },attrs:{\"id\":\"NAVmanage\"}},[_c('app-link',{staticClass:\"dropdown-toggle\",attrs:{\"href\":\"manage/episodeStatuses/\",\"aria-haspopup\":\"true\",\"data-toggle\":\"dropdown\",\"data-hover\":\"dropdown\"}},[_c('span',[_vm._v(\"Manage\")]),_vm._v(\" \"),_c('b',{staticClass:\"caret\"})]),_vm._v(\" \"),_c('ul',{staticClass:\"dropdown-menu\"},[_c('li',[_c('app-link',{attrs:{\"href\":\"manage/\"}},[_c('i',{staticClass:\"menu-icon-manage\"}),_vm._v(\" Mass Update\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"manage/backlogOverview/\"}},[_c('i',{staticClass:\"menu-icon-backlog-view\"}),_vm._v(\" Backlog Overview\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"manage/manageSearches/\"}},[_c('i',{staticClass:\"menu-icon-manage-searches\"}),_vm._v(\" Manage Searches\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"manage/episodeStatuses/\"}},[_c('i',{staticClass:\"menu-icon-manage2\"}),_vm._v(\" Episode Status Management\")])],1),_vm._v(\" \"),(_vm.linkVisible.plex)?_c('li',[_c('app-link',{attrs:{\"href\":\"home/updatePLEX/\"}},[_c('i',{staticClass:\"menu-icon-plex\"}),_vm._v(\" Update PLEX\")])],1):_vm._e(),_vm._v(\" \"),(_vm.linkVisible.kodi)?_c('li',[_c('app-link',{attrs:{\"href\":\"home/updateKODI/\"}},[_c('i',{staticClass:\"menu-icon-kodi\"}),_vm._v(\" Update KODI\")])],1):_vm._e(),_vm._v(\" \"),(_vm.linkVisible.emby)?_c('li',[_c('app-link',{attrs:{\"href\":\"home/updateEMBY/\"}},[_c('i',{staticClass:\"menu-icon-emby\"}),_vm._v(\" Update Emby\")])],1):_vm._e(),_vm._v(\" \"),(_vm.linkVisible.manageTorrents)?_c('li',[_c('app-link',{attrs:{\"href\":\"manage/manageTorrents/\",\"target\":\"_blank\"}},[_c('i',{staticClass:\"menu-icon-bittorrent\"}),_vm._v(\" Manage Torrents\")])],1):_vm._e(),_vm._v(\" \"),(_vm.linkVisible.failedDownloads)?_c('li',[_c('app-link',{attrs:{\"href\":\"manage/failedDownloads/\"}},[_c('i',{staticClass:\"menu-icon-failed-download\"}),_vm._v(\" Failed Downloads\")])],1):_vm._e(),_vm._v(\" \"),(_vm.linkVisible.subtitleMissed)?_c('li',[_c('app-link',{attrs:{\"href\":\"manage/subtitleMissed/\"}},[_c('i',{staticClass:\"menu-icon-backlog\"}),_vm._v(\" Missed Subtitle Management\")])],1):_vm._e(),_vm._v(\" \"),(_vm.linkVisible.subtitleMissedPP)?_c('li',[_c('app-link',{attrs:{\"href\":\"manage/subtitleMissedPP/\"}},[_c('i',{staticClass:\"menu-icon-backlog\"}),_vm._v(\" Missed Subtitle in Post-Process folder\")])],1):_vm._e()]),_vm._v(\" \"),_c('div',{staticStyle:{\"clear\":\"both\"}})],1),_vm._v(\" \"),_c('li',{staticClass:\"navbar-split dropdown\",class:{ active: _vm.topMenu === 'config' },attrs:{\"id\":\"NAVconfig\"}},[_c('app-link',{staticClass:\"dropdown-toggle\",attrs:{\"href\":\"config/\",\"aria-haspopup\":\"true\",\"data-toggle\":\"dropdown\",\"data-hover\":\"dropdown\"}},[_c('span',{staticClass:\"visible-xs-inline\"},[_vm._v(\"Config\")]),_c('img',{staticClass:\"navbaricon hidden-xs\",attrs:{\"src\":\"images/menu/system18.png\"}}),_vm._v(\" \"),_c('b',{staticClass:\"caret\"})]),_vm._v(\" \"),_c('ul',{staticClass:\"dropdown-menu\"},[_c('li',[_c('app-link',{attrs:{\"href\":\"config/\"}},[_c('i',{staticClass:\"menu-icon-help\"}),_vm._v(\" Help & Info\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/general/\"}},[_c('i',{staticClass:\"menu-icon-config\"}),_vm._v(\" General\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/backuprestore/\"}},[_c('i',{staticClass:\"menu-icon-backup\"}),_vm._v(\" Backup & Restore\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/search/\"}},[_c('i',{staticClass:\"menu-icon-manage-searches\"}),_vm._v(\" Search Settings\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/providers/\"}},[_c('i',{staticClass:\"menu-icon-provider\"}),_vm._v(\" Search Providers\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/subtitles/\"}},[_c('i',{staticClass:\"menu-icon-backlog\"}),_vm._v(\" Subtitles Settings\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/postProcessing/\"}},[_c('i',{staticClass:\"menu-icon-postprocess\"}),_vm._v(\" Post Processing\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/notifications/\"}},[_c('i',{staticClass:\"menu-icon-notification\"}),_vm._v(\" Notifications\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"config/anime/\"}},[_c('i',{staticClass:\"menu-icon-anime\"}),_vm._v(\" Anime\")])],1)]),_vm._v(\" \"),_c('div',{staticStyle:{\"clear\":\"both\"}})],1),_vm._v(\" \"),_c('li',{staticClass:\"navbar-split dropdown\",class:{ active: _vm.topMenu === 'system' },attrs:{\"id\":\"NAVsystem\"}},[_c('app-link',{staticClass:\"padding-right-15 dropdown-toggle\",attrs:{\"href\":\"home/status/\",\"aria-haspopup\":\"true\",\"data-toggle\":\"dropdown\",\"data-hover\":\"dropdown\"}},[_c('span',{staticClass:\"visible-xs-inline\"},[_vm._v(\"Tools\")]),_c('img',{staticClass:\"navbaricon hidden-xs\",attrs:{\"src\":\"images/menu/system18-2.png\"}}),_vm._v(\" \"),(_vm.toolsBadgeCount > 0)?_c('span',{class:(\"badge\" + _vm.toolsBadgeClass)},[_vm._v(_vm._s(_vm.toolsBadgeCount))]):_vm._e(),_vm._v(\" \"),_c('b',{staticClass:\"caret\"})]),_vm._v(\" \"),_c('ul',{staticClass:\"dropdown-menu\"},[_c('li',[_c('app-link',{attrs:{\"href\":\"news/\"}},[_c('i',{staticClass:\"menu-icon-news\"}),_vm._v(\" News \"),(_vm.config.news.unread > 0)?_c('span',{staticClass:\"badge\"},[_vm._v(_vm._s(_vm.config.news.unread))]):_vm._e()])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"IRC/\"}},[_c('i',{staticClass:\"menu-icon-irc\"}),_vm._v(\" IRC\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"changes/\"}},[_c('i',{staticClass:\"menu-icon-changelog\"}),_vm._v(\" Changelog\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":_vm.config.donationsUrl}},[_c('i',{staticClass:\"menu-icon-support\"}),_vm._v(\" Support Medusa\")])],1),_vm._v(\" \"),_c('li',{staticClass:\"divider\",attrs:{\"role\":\"separator\"}}),_vm._v(\" \"),(_vm.config.logs.numErrors > 0)?_c('li',[_c('app-link',{attrs:{\"href\":\"errorlogs/\"}},[_c('i',{staticClass:\"menu-icon-error\"}),_vm._v(\" View Errors \"),_c('span',{staticClass:\"badge btn-danger\"},[_vm._v(_vm._s(_vm.config.logs.numErrors))])])],1):_vm._e(),_vm._v(\" \"),(_vm.config.logs.numWarnings > 0)?_c('li',[_c('app-link',{attrs:{\"href\":(\"errorlogs/?level=\" + _vm.warningLevel)}},[_c('i',{staticClass:\"menu-icon-viewlog-errors\"}),_vm._v(\" View Warnings \"),_c('span',{staticClass:\"badge btn-warning\"},[_vm._v(_vm._s(_vm.config.logs.numWarnings))])])],1):_vm._e(),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"errorlogs/viewlog/\"}},[_c('i',{staticClass:\"menu-icon-viewlog\"}),_vm._v(\" View Log\")])],1),_vm._v(\" \"),_c('li',{staticClass:\"divider\",attrs:{\"role\":\"separator\"}}),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":(\"home/updateCheck?pid=\" + (_vm.config.pid))}},[_c('i',{staticClass:\"menu-icon-update\"}),_vm._v(\" Check For Updates\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":(\"home/restart/?pid=\" + (_vm.config.pid))},nativeOn:{\"click\":function($event){$event.preventDefault();return _vm.confirmDialog($event, 'restart')}}},[_c('i',{staticClass:\"menu-icon-restart\"}),_vm._v(\" Restart\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":(\"home/shutdown/?pid=\" + (_vm.config.pid))},nativeOn:{\"click\":function($event){$event.preventDefault();return _vm.confirmDialog($event, 'shutdown')}}},[_c('i',{staticClass:\"menu-icon-shutdown\"}),_vm._v(\" Shutdown\")])],1),_vm._v(\" \"),(_vm.username)?_c('li',[_c('app-link',{attrs:{\"href\":\"logout\"},nativeOn:{\"click\":function($event){$event.preventDefault();return _vm.confirmDialog($event, 'logout')}}},[_c('i',{staticClass:\"menu-icon-shutdown\"}),_vm._v(\" Logout\")])],1):_vm._e(),_vm._v(\" \"),_c('li',{staticClass:\"divider\",attrs:{\"role\":\"separator\"}}),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"home/status/\"}},[_c('i',{staticClass:\"menu-icon-info\"}),_vm._v(\" Server Status\")])],1)]),_vm._v(\" \"),_c('div',{staticStyle:{\"clear\":\"both\"}})],1)])]):_vm._e()])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./backstretch.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./backstretch.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./backstretch.vue?vue&type=template&id=27a98ad8&\"\nimport script from \"./backstretch.vue?vue&type=script&lang=js&\"\nexport * from \"./backstretch.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div')}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./home.vue?vue&type=script&lang=js&\"\nexport * from \"./home.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manual-post-process.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manual-post-process.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./manual-post-process.vue?vue&type=script&lang=js&\"\nexport * from \"./manual-post-process.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./root-dirs.vue?vue&type=template&id=76f972d6&\"\nimport script from \"./root-dirs.vue?vue&type=script&lang=js&\"\nexport * from \"./root-dirs.vue?vue&type=script&lang=js&\"\nimport style0 from \"./root-dirs.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"root-dirs-wrapper\"}},[_c('div',{staticClass:\"root-dirs-selectbox\"},[_c('select',_vm._g(_vm._b({directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.selectedRootDir),expression:\"selectedRootDir\"}],ref:\"rootDirs\",attrs:{\"name\":\"rootDir\",\"id\":\"rootDirs\",\"size\":\"6\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.selectedRootDir=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},'select',_vm.$attrs,false),_vm.$listeners),_vm._l((_vm.rootDirs),function(curDir){return _c('option',{key:curDir.path,domProps:{\"value\":curDir.path}},[_vm._v(\"\\n \"+_vm._s(_vm._f(\"markDefault\")(curDir))+\"\\n \")])}),0)]),_vm._v(\" \"),_c('div',{staticClass:\"root-dirs-controls\"},[_c('button',{staticClass:\"btn-medusa\",attrs:{\"type\":\"button\"},on:{\"click\":function($event){$event.preventDefault();return _vm.add($event)}}},[_vm._v(\"New\")]),_vm._v(\" \"),_c('button',{staticClass:\"btn-medusa\",attrs:{\"type\":\"button\",\"disabled\":!_vm.selectedRootDir},on:{\"click\":function($event){$event.preventDefault();return _vm.edit($event)}}},[_vm._v(\"Edit\")]),_vm._v(\" \"),_c('button',{staticClass:\"btn-medusa\",attrs:{\"type\":\"button\",\"disabled\":!_vm.selectedRootDir},on:{\"click\":function($event){$event.preventDefault();return _vm.remove($event)}}},[_vm._v(\"Delete\")]),_vm._v(\" \"),_c('button',{staticClass:\"btn-medusa\",attrs:{\"type\":\"button\",\"disabled\":!_vm.selectedRootDir},on:{\"click\":function($event){$event.preventDefault();return _vm.setDefault($event)}}},[_vm._v(\"Set as Default *\")])])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./show.vue?vue&type=script&lang=js&\"\nexport * from \"./show.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./snatch-selection.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./snatch-selection.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./snatch-selection.vue?vue&type=script&lang=js&\"\nexport * from \"./snatch-selection.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./status.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./status.vue?vue&type=script&lang=js&\"","var render, staticRenderFns\nimport script from \"./status.vue?vue&type=script&lang=js&\"\nexport * from \"./status.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","export { default as AddRecommended } from './add-recommended.vue';\nexport { default as AddShowOptions } from './add-show-options.vue';\nexport { default as AddShows } from './add-shows.vue';\nexport { default as AnidbReleaseGroupUi } from './anidb-release-group-ui.vue';\nexport { default as AppHeader } from './app-header.vue';\nexport { default as Backstretch } from './backstretch.vue';\nexport { default as Config } from './config.vue';\nexport { default as ConfigPostProcessing } from './config-post-processing.vue';\nexport { default as Home } from './home.vue';\nexport { default as IRC } from './irc.vue';\nexport { default as Login } from './login.vue';\nexport { default as ManualPostProcess } from './manual-post-process.vue';\nexport { default as RootDirs } from './root-dirs.vue';\nexport { default as Show } from './show.vue';\nexport { default as ShowHeader } from './show-header.vue';\nexport { default as SnatchSelection } from './snatch-selection.vue';\nexport { default as Status } from './status.vue';\nexport * from './http';\nexport * from './helpers';\n","import axios from 'axios';\n\nconst webRoot = document.body.getAttribute('web-root');\nconst apiKey = document.body.getAttribute('api-key');\n\n/**\n * Api client based on the axios client, to communicate with medusa's web routes, which return json data.\n */\nconst apiRoute = axios.create({\n baseURL: webRoot + '/',\n timeout: 30000,\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json'\n }\n});\n\n/**\n * Api client based on the axios client, to communicate with medusa's api v1.\n */\nconst apiv1 = axios.create({\n baseURL: webRoot + '/api/v1/' + apiKey + '/',\n timeout: 30000,\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json'\n }\n});\n\n/**\n * Api client based on the axios client, to communicate with medusa's api v2.\n */\nconst api = axios.create({\n baseURL: webRoot + '/api/v2/',\n timeout: 30000,\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n 'X-Api-Key': apiKey\n }\n});\n\nexport {\n webRoot,\n apiKey,\n apiRoute,\n apiv1,\n api\n};\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c(_vm.linkProperties.is,{tag:\"component\",class:{ 'router-link': _vm.linkProperties.is === 'router-link' },attrs:{\"to\":_vm.linkProperties.to,\"href\":_vm.linkProperties.href,\"target\":_vm.linkProperties.target,\"rel\":_vm.linkProperties.rel,\"false-link\":_vm.linkProperties.falseLink}},[_vm._t(\"default\")],2)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./app-link.vue?vue&type=template&id=d2623cd8&\"\nimport script from \"./app-link.vue?vue&type=script&lang=js&\"\nexport * from \"./app-link.vue?vue&type=script&lang=js&\"\nimport style0 from \"./app-link.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./asset.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./asset.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./asset.vue?vue&type=template&id=8ae62598&\"\nimport script from \"./asset.vue?vue&type=script&lang=js&\"\nexport * from \"./asset.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (!_vm.link)?_c('img',{class:_vm.cls,attrs:{\"src\":_vm.src},on:{\"error\":function($event){_vm.error = true}}}):_c('app-link',{attrs:{\"href\":_vm.href}},[_c('img',{class:_vm.cls,attrs:{\"src\":_vm.src},on:{\"error\":function($event){_vm.error = true}}})])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-template.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-template.vue?vue&type=script&lang=js&\"","\n\n\n\n\n","import { render, staticRenderFns } from \"./config-template.vue?vue&type=template&id=1203ba68&\"\nimport script from \"./config-template.vue?vue&type=script&lang=js&\"\nexport * from \"./config-template.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"config-template-content\"}},[_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":_vm.labelFor}},[_c('span',[_vm._v(_vm._s(_vm.label))])]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_vm._t(\"default\")],2)])])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=script&lang=js&\"","\n\n\n\n\n","import { render, staticRenderFns } from \"./config-textbox-number.vue?vue&type=template&id=159c522c&\"\nimport script from \"./config-textbox-number.vue?vue&type=script&lang=js&\"\nexport * from \"./config-textbox-number.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-textbox-number.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"config-textbox-number-content\"}},[_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":_vm.id}},[_c('span',[_vm._v(_vm._s(_vm.label))])]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('input',_vm._b({directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.localValue),expression:\"localValue\"}],attrs:{\"type\":\"number\"},domProps:{\"value\":(_vm.localValue)},on:{\"input\":[function($event){if($event.target.composing){ return; }_vm.localValue=$event.target.value},function($event){return _vm.updateValue()}]}},'input',{min: _vm.min, max: _vm.max, step: _vm.step, id: _vm.id, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled},false)),_vm._v(\" \"),_vm._l((_vm.explanations),function(explanation,index){return _c('p',{key:index},[_vm._v(_vm._s(explanation))])}),_vm._v(\" \"),_vm._t(\"default\")],2)])])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=script&lang=js&\"","\n\n\n\n\n","import { render, staticRenderFns } from \"./config-textbox.vue?vue&type=template&id=788aa398&\"\nimport script from \"./config-textbox.vue?vue&type=script&lang=js&\"\nexport * from \"./config-textbox.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-textbox.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"config-textbox\"}},[_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":_vm.id}},[_c('span',[_vm._v(_vm._s(_vm.label))])]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[((({id: _vm.id, type: _vm.type, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled}).type)==='checkbox')?_c('input',_vm._b({directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.localValue),expression:\"localValue\"}],attrs:{\"type\":\"checkbox\"},domProps:{\"checked\":Array.isArray(_vm.localValue)?_vm._i(_vm.localValue,null)>-1:(_vm.localValue)},on:{\"input\":function($event){return _vm.updateValue()},\"change\":function($event){var $$a=_vm.localValue,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.localValue=$$a.concat([$$v]))}else{$$i>-1&&(_vm.localValue=$$a.slice(0,$$i).concat($$a.slice($$i+1)))}}else{_vm.localValue=$$c}}}},'input',{id: _vm.id, type: _vm.type, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled},false)):((({id: _vm.id, type: _vm.type, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled}).type)==='radio')?_c('input',_vm._b({directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.localValue),expression:\"localValue\"}],attrs:{\"type\":\"radio\"},domProps:{\"checked\":_vm._q(_vm.localValue,null)},on:{\"input\":function($event){return _vm.updateValue()},\"change\":function($event){_vm.localValue=null}}},'input',{id: _vm.id, type: _vm.type, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled},false)):_c('input',_vm._b({directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.localValue),expression:\"localValue\"}],attrs:{\"type\":({id: _vm.id, type: _vm.type, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled}).type},domProps:{\"value\":(_vm.localValue)},on:{\"input\":[function($event){if($event.target.composing){ return; }_vm.localValue=$event.target.value},function($event){return _vm.updateValue()}]}},'input',{id: _vm.id, type: _vm.type, name: _vm.id, class: _vm.inputClass, placeholder: _vm.placeholder, disabled: _vm.disabled},false)),_vm._v(\" \"),_vm._l((_vm.explanations),function(explanation,index){return _c('p',{key:index},[_vm._v(_vm._s(explanation))])}),_vm._v(\" \"),_vm._t(\"default\")],2)])])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=script&lang=js&\"","\n\n\n\n\n","import { render, staticRenderFns } from \"./config-toggle-slider.vue?vue&type=template&id=89c5b77c&\"\nimport script from \"./config-toggle-slider.vue?vue&type=script&lang=js&\"\nexport * from \"./config-toggle-slider.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config-toggle-slider.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"config-toggle-slider-content\"}},[_c('div',{staticClass:\"form-group\"},[_c('div',{staticClass:\"row\"},[_c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":_vm.id}},[_c('span',[_vm._v(_vm._s(_vm.label))])]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',_vm._b({attrs:{\"width\":45,\"height\":22,\"sync\":\"\"},on:{\"input\":function($event){return _vm.updateValue()}},model:{value:(_vm.localChecked),callback:function ($$v) {_vm.localChecked=$$v},expression:\"localChecked\"}},'toggle-button',{id: _vm.id, name: _vm.id, disabled: _vm.disabled},false)),_vm._v(\" \"),_vm._l((_vm.explanations),function(explanation,index){return _c('p',{key:index},[_vm._v(_vm._s(explanation))])}),_vm._v(\" \"),_vm._t(\"default\")],2)])])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./file-browser.vue?vue&type=template&id=5a327762&scoped=true&\"\nimport script from \"./file-browser.vue?vue&type=script&lang=js&\"\nexport * from \"./file-browser.vue?vue&type=script&lang=js&\"\nimport style0 from \"./file-browser.vue?vue&type=style&index=0&id=5a327762&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"5a327762\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"file-browser max-width\"},[_c('div',{class:(_vm.showBrowseButton ? 'input-group' : 'input-group-no-btn')},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.currentPath),expression:\"currentPath\"}],ref:\"locationInput\",staticClass:\"form-control input-sm fileBrowserField\",attrs:{\"name\":_vm.name,\"type\":\"text\"},domProps:{\"value\":(_vm.currentPath)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.currentPath=$event.target.value}}}),_vm._v(\" \"),(_vm.showBrowseButton)?_c('div',{staticClass:\"input-group-btn\",attrs:{\"title\":_vm.title,\"alt\":_vm.title},on:{\"click\":function($event){$event.preventDefault();return _vm.openDialog($event)}}},[_vm._m(0)]):_vm._e()]),_vm._v(\" \"),_c('div',{ref:\"fileBrowserDialog\",staticClass:\"fileBrowserDialog\",staticStyle:{\"display\":\"none\"}}),_vm._v(\" \"),_c('input',{ref:\"fileBrowserSearchBox\",staticClass:\"form-control\",staticStyle:{\"display\":\"none\"},attrs:{\"type\":\"text\"},domProps:{\"value\":_vm.currentPath},on:{\"keyup\":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,\"enter\",13,$event.key,\"Enter\")){ return null; }return _vm.browse($event.target.value)}}}),_vm._v(\" \"),_c('ul',{ref:\"fileBrowserFileList\",staticStyle:{\"display\":\"none\"}},_vm._l((_vm.files),function(file){return _c('li',{key:file.name,staticClass:\"ui-state-default ui-corner-all\"},[_c('a',{on:{\"mouseover\":function($event){return _vm.toggleFolder(file, $event)},\"mouseout\":function($event){return _vm.toggleFolder(file, $event)},\"click\":function($event){return _vm.fileClicked(file)}}},[_c('span',{class:'ui-icon ' + (file.isFile ? 'ui-icon-blank' : 'ui-icon-folder-collapsed')}),_vm._v(\" \"+_vm._s(file.name)+\"\\n \")])])}),0)])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"btn btn-default input-sm\",staticStyle:{\"font-size\":\"14px\"}},[_c('i',{staticClass:\"glyphicon glyphicon-open\"})])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./language-select.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./language-select.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./language-select.vue?vue&type=template&id=2e8dcbe5&\"\nimport script from \"./language-select.vue?vue&type=script&lang=js&\"\nexport * from \"./language-select.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('select')}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./name-pattern.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./name-pattern.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./name-pattern.vue?vue&type=template&id=b51e0a36&\"\nimport script from \"./name-pattern.vue?vue&type=script&lang=js&\"\nexport * from \"./name-pattern.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"name-pattern-wrapper\"}},[(_vm.type)?_c('div',{staticClass:\"form-group\"},[_c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"enable_naming_custom\"}},[_c('span',[_vm._v(\"Custom \"+_vm._s(_vm.type))])]),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"enable_naming_custom\",\"name\":\"enable_naming_custom\",\"sync\":\"\"},on:{\"input\":function($event){return _vm.update()}},model:{value:(_vm.isEnabled),callback:function ($$v) {_vm.isEnabled=$$v},expression:\"isEnabled\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Name \"+_vm._s(_vm.type)+\" shows differently than regular shows?\")])],1)]):_vm._e(),_vm._v(\" \"),(!_vm.type || _vm.isEnabled)?_c('div',{staticClass:\"episode-naming\"},[_c('div',{staticClass:\"form-group\"},[_vm._m(0),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.selectedNamingPattern),expression:\"selectedNamingPattern\"}],staticClass:\"form-control input-sm\",attrs:{\"id\":\"name_presets\"},on:{\"change\":[function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.selectedNamingPattern=$event.target.multiple ? $$selectedVal : $$selectedVal[0]},_vm.updatePatternSamples],\"input\":function($event){return _vm.update()}}},_vm._l((_vm.presets),function(preset){return _c('option',{key:preset.pattern,attrs:{\"id\":preset.pattern}},[_vm._v(_vm._s(preset.example))])}),0)])]),_vm._v(\" \"),_c('div',{attrs:{\"id\":\"naming_custom\"}},[(_vm.isCustom)?_c('div',{staticClass:\"form-group\",staticStyle:{\"padding-top\":\"0\"}},[_vm._m(1),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.customName),expression:\"customName\"}],staticClass:\"form-control-inline-max input-sm max-input350\",attrs:{\"type\":\"text\",\"name\":\"naming_pattern\",\"id\":\"naming_pattern\"},domProps:{\"value\":(_vm.customName)},on:{\"change\":_vm.updatePatternSamples,\"input\":[function($event){if($event.target.composing){ return; }_vm.customName=$event.target.value},function($event){return _vm.update()}]}}),_vm._v(\" \"),_c('img',{staticClass:\"legend\",attrs:{\"src\":\"images/legend16.png\",\"width\":\"16\",\"height\":\"16\",\"alt\":\"[Toggle Key]\",\"id\":\"show_naming_key\",\"title\":\"Toggle Naming Legend\"},on:{\"click\":function($event){_vm.showLegend = !_vm.showLegend}}})])]):_vm._e(),_vm._v(\" \"),(_vm.showLegend && _vm.isCustom)?_c('div',{staticClass:\"nocheck\",attrs:{\"id\":\"naming_key\"}},[_c('table',{staticClass:\"Key\"},[_vm._m(2),_vm._v(\" \"),_vm._m(3),_vm._v(\" \"),_c('tbody',[_vm._m(4),_vm._v(\" \"),_vm._m(5),_vm._v(\" \"),_vm._m(6),_vm._v(\" \"),_vm._m(7),_vm._v(\" \"),_vm._m(8),_vm._v(\" \"),_vm._m(9),_vm._v(\" \"),_vm._m(10),_vm._v(\" \"),_vm._m(11),_vm._v(\" \"),_vm._m(12),_vm._v(\" \"),_vm._m(13),_vm._v(\" \"),_vm._m(14),_vm._v(\" \"),_vm._m(15),_vm._v(\" \"),_vm._m(16),_vm._v(\" \"),_vm._m(17),_vm._v(\" \"),_vm._m(18),_vm._v(\" \"),_vm._m(19),_vm._v(\" \"),_c('tr',[_vm._m(20),_vm._v(\" \"),_c('td',[_vm._v(\"%M\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.getDateFormat('M')))])]),_vm._v(\" \"),_c('tr',{staticClass:\"even\"},[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%D\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.getDateFormat('D')))])]),_vm._v(\" \"),_c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%Y\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.getDateFormat('YY')))])]),_vm._v(\" \"),_c('tr',[_vm._m(21),_vm._v(\" \"),_c('td',[_vm._v(\"%CM\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.getDateFormat('M')))])]),_vm._v(\" \"),_c('tr',{staticClass:\"even\"},[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%CD\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.getDateFormat('D')))])]),_vm._v(\" \"),_c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%CY\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.getDateFormat('YY')))])]),_vm._v(\" \"),_vm._m(22),_vm._v(\" \"),_vm._m(23),_vm._v(\" \"),_vm._m(24),_vm._v(\" \"),_vm._m(25),_vm._v(\" \"),_vm._m(26),_vm._v(\" \"),_vm._m(27),_vm._v(\" \"),_vm._m(28),_vm._v(\" \"),_vm._m(29),_vm._v(\" \"),_vm._m(30)])])]):_vm._e()]),_vm._v(\" \"),(_vm.selectedMultiEpStyle)?_c('div',{staticClass:\"form-group\"},[_vm._m(31),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.selectedMultiEpStyle),expression:\"selectedMultiEpStyle\"}],staticClass:\"form-control input-sm\",attrs:{\"id\":\"naming_multi_ep\",\"name\":\"naming_multi_ep\"},on:{\"change\":[function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.selectedMultiEpStyle=$event.target.multiple ? $$selectedVal : $$selectedVal[0]},_vm.updatePatternSamples],\"input\":function($event){return _vm.update($event)}}},_vm._l((_vm.availableMultiEpStyles),function(multiEpStyle){return _c('option',{key:multiEpStyle.value,attrs:{\"id\":\"multiEpStyle\"},domProps:{\"value\":multiEpStyle.value}},[_vm._v(_vm._s(multiEpStyle.text))])}),0)])]):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"form-group row\"},[_c('h3',{staticClass:\"col-sm-12\"},[_vm._v(\"Single-EP Sample:\")]),_vm._v(\" \"),_c('div',{staticClass:\"example col-sm-12\"},[_c('span',{staticClass:\"jumbo\",attrs:{\"id\":\"naming_example\"}},[_vm._v(_vm._s(_vm.namingExample))])])]),_vm._v(\" \"),(_vm.isMulti)?_c('div',{staticClass:\"form-group row\"},[_c('h3',{staticClass:\"col-sm-12\"},[_vm._v(\"Multi-EP sample:\")]),_vm._v(\" \"),_c('div',{staticClass:\"example col-sm-12\"},[_c('span',{staticClass:\"jumbo\",attrs:{\"id\":\"naming_example_multi\"}},[_vm._v(_vm._s(_vm.namingExampleMulti))])])]):_vm._e(),_vm._v(\" \"),(_vm.animeType > 0)?_c('div',{staticClass:\"form-group\"},[_vm._m(32),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.animeType),expression:\"animeType\"}],attrs:{\"type\":\"radio\",\"name\":\"naming_anime\",\"id\":\"naming_anime\",\"value\":\"1\"},domProps:{\"checked\":_vm._q(_vm.animeType,\"1\")},on:{\"change\":[function($event){_vm.animeType=\"1\"},_vm.updatePatternSamples],\"input\":function($event){return _vm.update()}}}),_vm._v(\" \"),_c('span',[_vm._v(\"Add the absolute number to the season/episode format?\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Only applies to animes. (e.g. S15E45 - 310 vs S15E45)\")])])]):_vm._e(),_vm._v(\" \"),(_vm.animeType > 0)?_c('div',{staticClass:\"form-group\"},[_vm._m(33),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.animeType),expression:\"animeType\"}],attrs:{\"type\":\"radio\",\"name\":\"naming_anime\",\"id\":\"naming_anime_only\",\"value\":\"2\"},domProps:{\"checked\":_vm._q(_vm.animeType,\"2\")},on:{\"change\":[function($event){_vm.animeType=\"2\"},_vm.updatePatternSamples],\"input\":function($event){return _vm.update()}}}),_vm._v(\" \"),_c('span',[_vm._v(\"Replace season/episode format with absolute number\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Only applies to animes.\")])])]):_vm._e(),_vm._v(\" \"),(_vm.animeType > 0)?_c('div',{staticClass:\"form-group\"},[_vm._m(34),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.animeType),expression:\"animeType\"}],attrs:{\"type\":\"radio\",\"name\":\"naming_anime\",\"id\":\"naming_anime_none\",\"value\":\"3\"},domProps:{\"checked\":_vm._q(_vm.animeType,\"3\")},on:{\"change\":[function($event){_vm.animeType=\"3\"},_vm.updatePatternSamples],\"input\":function($event){return _vm.update()}}}),_vm._v(\" \"),_c('span',[_vm._v(\"Don't include the absolute number\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Only applies to animes.\")])])]):_vm._e()]):_vm._e()])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"name_presets\"}},[_c('span',[_vm._v(\"Name Pattern:\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\"},[_c('span',[_vm._v(\" \")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('thead',[_c('tr',[_c('th',{staticClass:\"align-right\"},[_vm._v(\"Meaning\")]),_vm._v(\" \"),_c('th',[_vm._v(\"Pattern\")]),_vm._v(\" \"),_c('th',{attrs:{\"width\":\"60%\"}},[_vm._v(\"Result\")])])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tfoot',[_c('tr',[_c('th',{attrs:{\"colspan\":\"3\"}},[_vm._v(\"Use lower case if you want lower case names (eg. %sn, %e.n, %q_n etc)\")])])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Show Name:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%SN\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Show Name\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%S.N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Show.Name\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%S_N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Show_Name\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Season Number:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%S\")]),_vm._v(\" \"),_c('td',[_vm._v(\"2\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%0S\")]),_vm._v(\" \"),_c('td',[_vm._v(\"02\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"XEM Season Number:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%XS\")]),_vm._v(\" \"),_c('td',[_vm._v(\"2\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%0XS\")]),_vm._v(\" \"),_c('td',[_vm._v(\"02\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Episode Number:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%E\")]),_vm._v(\" \"),_c('td',[_vm._v(\"3\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%0E\")]),_vm._v(\" \"),_c('td',[_vm._v(\"03\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"XEM Episode Number:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%XE\")]),_vm._v(\" \"),_c('td',[_vm._v(\"3\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%0XE\")]),_vm._v(\" \"),_c('td',[_vm._v(\"03\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Absolute Episode Number:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%AB\")]),_vm._v(\" \"),_c('td',[_vm._v(\"003\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Xem Absolute Episode Number:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%XAB\")]),_vm._v(\" \"),_c('td',[_vm._v(\"003\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Episode Name:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%EN\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Episode Name\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%E.N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Episode.Name\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%E_N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Episode_Name\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Air Date:\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Post-Processing Date:\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Quality:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%QN\")]),_vm._v(\" \"),_c('td',[_vm._v(\"720p BluRay\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%Q.N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"720p.BluRay\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%Q_N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"720p_BluRay\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',{staticClass:\"align-right\"},[_c('b',[_vm._v(\"Scene Quality:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%SQN\")]),_vm._v(\" \"),_c('td',[_vm._v(\"720p HDTV x264\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%SQ.N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"720p.HDTV.x264\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_vm._v(\" \"),_c('td',[_vm._v(\"%SQ_N\")]),_vm._v(\" \"),_c('td',[_vm._v(\"720p_HDTV_x264\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('i',{staticClass:\"glyphicon glyphicon-info-sign\",attrs:{\"title\":\"Multi-EP style is ignored\"}}),_vm._v(\" \"),_c('b',[_vm._v(\"Release Name:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%RN\")]),_vm._v(\" \"),_c('td',[_vm._v(\"Show.Name.S02E03.HDTV.x264-RLSGROUP\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',{staticClass:\"align-right\"},[_c('i',{staticClass:\"glyphicon glyphicon-info-sign\",attrs:{\"title\":\"UNKNOWN_RELEASE_GROUP is used in place of RLSGROUP if it could not be properly detected\"}}),_vm._v(\" \"),_c('b',[_vm._v(\"Release Group:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%RG\")]),_vm._v(\" \"),_c('td',[_vm._v(\"RLSGROUP\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"even\"},[_c('td',{staticClass:\"align-right\"},[_c('i',{staticClass:\"glyphicon glyphicon-info-sign\",attrs:{\"title\":\"If episode is proper/repack add 'proper' to name.\"}}),_vm._v(\" \"),_c('b',[_vm._v(\"Release Type:\")])]),_vm._v(\" \"),_c('td',[_vm._v(\"%RT\")]),_vm._v(\" \"),_c('td',[_vm._v(\"PROPER\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"naming_multi_ep\"}},[_c('span',[_vm._v(\"Multi-Episode Style:\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"naming_anime\"}},[_c('span',[_vm._v(\"Add Absolute Number\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"naming_anime_only\"}},[_c('span',[_vm._v(\"Only Absolute Number\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"naming_anime_none\"}},[_c('span',[_vm._v(\"No Absolute Number\")])])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./plot-info.vue?vue&type=template&id=6b17b4d1&\"\nimport script from \"./plot-info.vue?vue&type=script&lang=js&\"\nexport * from \"./plot-info.vue?vue&type=script&lang=js&\"\nimport style0 from \"./plot-info.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('img',{class:_vm.plotInfoClass,attrs:{\"src\":\"images/info32.png\",\"width\":\"16\",\"height\":\"16\",\"alt\":\"\"}})}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./quality-pill.vue?vue&type=template&id=b683ee7a&scoped=true&\"\nimport script from \"./quality-pill.vue?vue&type=script&lang=js&\"\nexport * from \"./quality-pill.vue?vue&type=script&lang=js&\"\nimport style0 from \"./quality-pill.vue?vue&type=style&index=0&id=b683ee7a&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"b683ee7a\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',{class:_vm.override.class || ['quality', _vm.pill.class],attrs:{\"title\":_vm.title}},[_vm._v(_vm._s(_vm.override.text || _vm.pill.text))])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./scroll-buttons.vue?vue&type=template&id=96ee7e7e&\"\nimport script from \"./scroll-buttons.vue?vue&type=script&lang=js&\"\nexport * from \"./scroll-buttons.vue?vue&type=script&lang=js&\"\nimport style0 from \"./scroll-buttons.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"scroll-buttons-wrapper\"}},[_c('div',{staticClass:\"scroll-wrapper top\",class:{ show: _vm.showToTop },on:{\"click\":function($event){$event.preventDefault();return _vm.scrollTop($event)}}},[_vm._m(0)]),_vm._v(\" \"),_c('div',{staticClass:\"scroll-wrapper left\",class:{ show: _vm.showLeftRight }},[_c('span',{staticClass:\"scroll-left-inner\"},[_c('i',{staticClass:\"glyphicon glyphicon-circle-arrow-left\",on:{\"click\":function($event){$event.preventDefault();return _vm.scrollLeft($event)}}})])]),_vm._v(\" \"),_c('div',{staticClass:\"scroll-wrapper right\",class:{ show: _vm.showLeftRight }},[_c('span',{staticClass:\"scroll-right-inner\"},[_c('i',{staticClass:\"glyphicon glyphicon-circle-arrow-right\",on:{\"click\":function($event){$event.preventDefault();return _vm.scrollRight($event)}}})])])])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',{staticClass:\"scroll-top-inner\"},[_c('i',{staticClass:\"glyphicon glyphicon-circle-arrow-up\"})])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./select-list.vue?vue&type=template&id=ac609192&scoped=true&\"\nimport script from \"./select-list.vue?vue&type=script&lang=js&\"\nexport * from \"./select-list.vue?vue&type=script&lang=js&\"\nimport style0 from \"./select-list.vue?vue&type=style&index=0&id=ac609192&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"ac609192\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',_vm._b({staticClass:\"select-list max-width\"},'div',{disabled: _vm.disabled},false),[_c('i',{staticClass:\"switch-input glyphicon glyphicon-refresh\",attrs:{\"title\":\"Switch between a list and comma separated values\"},on:{\"click\":function($event){return _vm.switchFields()}}}),_vm._v(\" \"),(!_vm.csvMode)?_c('ul',[_vm._l((_vm.editItems),function(item){return _c('li',{key:item.id},[_c('div',{staticClass:\"input-group\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(item.value),expression:\"item.value\"}],staticClass:\"form-control input-sm\",attrs:{\"type\":\"text\"},domProps:{\"value\":(item.value)},on:{\"input\":[function($event){if($event.target.composing){ return; }_vm.$set(item, \"value\", $event.target.value)},function($event){return _vm.removeEmpty(item)}]}}),_vm._v(\" \"),_c('div',{staticClass:\"input-group-btn\",on:{\"click\":function($event){return _vm.deleteItem(item)}}},[_vm._m(0,true)])])])}),_vm._v(\" \"),_c('div',{staticClass:\"new-item\"},[_c('div',{staticClass:\"input-group\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.newItem),expression:\"newItem\"}],ref:\"newItemInput\",staticClass:\"form-control input-sm\",attrs:{\"type\":\"text\",\"placeholder\":\"add new values per line\"},domProps:{\"value\":(_vm.newItem)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.newItem=$event.target.value}}}),_vm._v(\" \"),_c('div',{staticClass:\"input-group-btn\",on:{\"click\":function($event){return _vm.addNewItem()}}},[_vm._m(1)])])]),_vm._v(\" \"),(_vm.newItem.length > 0)?_c('div',{staticClass:\"new-item-help\"},[_vm._v(\"\\n Click \"),_c('i',{staticClass:\"glyphicon glyphicon-plus\"}),_vm._v(\" to finish adding the value.\\n \")]):_vm._e()],2):_c('div',{staticClass:\"csv\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.csv),expression:\"csv\"}],staticClass:\"form-control input-sm\",attrs:{\"type\":\"text\",\"placeholder\":\"add values comma separated\"},domProps:{\"value\":(_vm.csv)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.csv=$event.target.value}}})])])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"btn btn-default input-sm\",staticStyle:{\"font-size\":\"14px\"}},[_c('i',{staticClass:\"glyphicon glyphicon-remove\",attrs:{\"title\":\"Remove\"}})])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"btn btn-default input-sm\",staticStyle:{\"font-size\":\"14px\"}},[_c('i',{staticClass:\"glyphicon glyphicon-plus\",attrs:{\"title\":\"Add\"}})])}]\n\nexport { render, staticRenderFns }","\n\n\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./show-selector.vue?vue&type=template&id=38a86ae6&\"\nimport script from \"./show-selector.vue?vue&type=script&lang=js&\"\nexport * from \"./show-selector.vue?vue&type=script&lang=js&\"\nimport style0 from \"./show-selector.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (_vm.shows.length === 0)?_c('span',[_vm._v(\"Loading...\")]):_c('div',{staticClass:\"show-selector form-inline hidden-print\"},[_c('div',{staticClass:\"select-show-group pull-left top-5 bottom-5\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.selectedShowSlug),expression:\"selectedShowSlug\"}],class:_vm.selectClass,on:{\"change\":[function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.selectedShowSlug=$event.target.multiple ? $$selectedVal : $$selectedVal[0]},function($event){return _vm.$emit('change', _vm.selectedShowSlug)}]}},[(_vm.placeholder)?_c('option',{attrs:{\"disabled\":\"\",\"hidden\":\"\"},domProps:{\"value\":_vm.placeholder,\"selected\":!_vm.selectedShowSlug}},[_vm._v(_vm._s(_vm.placeholder))]):_vm._e(),_vm._v(\" \"),(_vm.whichList === -1)?_vm._l((_vm.showLists),function(curShowList){return _c('optgroup',{key:curShowList.type,attrs:{\"label\":curShowList.type}},_vm._l((curShowList.shows),function(show){return _c('option',{key:show.id.slug,domProps:{\"value\":show.id.slug}},[_vm._v(_vm._s(show.title))])}),0)}):_vm._l((_vm.showLists[_vm.whichList].shows),function(show){return _c('option',{key:show.id.slug,domProps:{\"value\":show.id.slug}},[_vm._v(_vm._s(show.title))])})],2)])])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./state-switch.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./state-switch.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./state-switch.vue?vue&type=template&id=4f286108&\"\nimport script from \"./state-switch.vue?vue&type=script&lang=js&\"\nexport * from \"./state-switch.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('img',_vm._b({attrs:{\"height\":\"16\",\"width\":\"16\"}},'img',{ src: _vm.src, alt: _vm.alt },false))}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","export { default as AppLink } from './app-link.vue';\nexport { default as Asset } from './asset.vue';\nexport { default as ConfigTemplate } from './config-template.vue';\nexport { default as ConfigTextboxNumber } from './config-textbox-number.vue';\nexport { default as ConfigTextbox } from './config-textbox.vue';\nexport { default as ConfigToggleSlider } from './config-toggle-slider.vue';\nexport { default as FileBrowser } from './file-browser.vue';\nexport { default as LanguageSelect } from './language-select.vue';\nexport { default as NamePattern } from './name-pattern.vue';\nexport { default as PlotInfo } from './plot-info.vue';\nexport { default as QualityPill } from './quality-pill.vue';\nexport { default as ScrollButtons } from './scroll-buttons.vue';\nexport { default as SelectList } from './select-list.vue';\nexport { default as ShowSelector } from './show-selector.vue';\nexport { default as StateSwitch } from './state-switch.vue';\n","const isDevelopment = process.env.NODE_ENV === 'development';\n\n/**\n * Calculate the combined value of the selected qualities.\n * @param {number[]} allowedQualities - Array of allowed qualities.\n * @param {number[]} preferredQualities - Array of preferred qualities.\n * @returns {number} - An unsigned integer.\n */\nconst combineQualities = (allowedQualities, preferredQualities) => {\n const reducer = (accumulator, currentValue) => accumulator | currentValue;\n const allowed = allowedQualities.reduce(reducer, 0);\n const preferred = preferredQualities.reduce(reducer, 0);\n\n return (allowed | (preferred << 16)) >>> 0; // Unsigned int\n};\n\n/**\n * Return a human readable representation of the provided size.\n * @param {number} bytes - The size in bytes to convert\n * @param {boolean} [useDecimal=false] - Use decimal instead of binary prefixes (e.g. kilo = 1000 instead of 1024)\n * @returns {string} The converted size.\n */\nconst humanFileSize = (bytes, useDecimal = false) => {\n if (bytes === undefined) {\n return;\n }\n\n const thresh = useDecimal ? 1000 : 1024;\n if (Math.abs(bytes) < thresh) {\n return bytes + ' B';\n }\n const units = ['KB', 'MB', 'GB', 'TB', 'PB'];\n let u = -1;\n do {\n bytes /= thresh;\n ++u;\n } while (Math.abs(bytes) >= thresh && u < units.length - 1);\n\n return `${bytes.toFixed(2)} ${units[u]}`;\n};\n\nexport {\n combineQualities,\n humanFileSize,\n isDevelopment\n};\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"show-header-container\"},[_c('div',{staticClass:\"row\"},[(_vm.show)?_c('div',{staticClass:\"col-lg-12\",attrs:{\"id\":\"showtitle\",\"data-showname\":_vm.show.title}},[_c('div',[_c('h1',{staticClass:\"title\",attrs:{\"data-indexer-name\":_vm.show.indexer,\"data-series-id\":_vm.show.id[_vm.show.indexer],\"id\":'scene_exception_' + _vm.show.id[_vm.show.indexer]}},[_c('app-link',{staticClass:\"snatchTitle\",attrs:{\"href\":'home/displayShow?indexername=' + _vm.show.indexer + '&seriesid=' + _vm.show.id[_vm.show.indexer]}},[_vm._v(_vm._s(_vm.show.title))])],1)]),_vm._v(\" \"),(_vm.type === 'snatch-selection')?_c('div',{staticClass:\"pull-right\",attrs:{\"id\":\"show-specials-and-seasons\"}},[_c('span',{staticClass:\"h2footer display-specials\"},[_vm._v(\"\\n Manual search for:\"),_c('br'),_vm._v(\" \"),_c('app-link',{staticClass:\"snatchTitle\",attrs:{\"href\":'home/displayShow?indexername=' + _vm.show.indexer + '&seriesid=' + _vm.show.id[_vm.show.indexer]}},[_vm._v(_vm._s(_vm.show.title))]),_vm._v(\" / Season \"+_vm._s(_vm.season)),(_vm.episode && _vm.manualSearchType !== 'season')?[_vm._v(\" Episode \"+_vm._s(_vm.episode))]:_vm._e()],2)]):_vm._e(),_vm._v(\" \"),(_vm.type !== 'snatch-selection' && _vm.show.seasons && _vm.show.seasons.length >= 1)?_c('div',{staticClass:\"pull-right\",attrs:{\"id\":\"show-specials-and-seasons\"}},[(_vm.show.seasons.find(function (season) { return function (ref) {\n\tvar season = ref.season;\n\n\treturn season === 0;\n; }\t}))?_c('span',{staticClass:\"h2footer display-specials\"},[_vm._v(\"\\n Display Specials: \"),_c('a',{staticClass:\"inner\",staticStyle:{\"cursor\":\"pointer\"},on:{\"click\":function($event){return _vm.toggleSpecials()}}},[_vm._v(_vm._s(_vm.displaySpecials ? 'Hide' : 'Show'))])]):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"h2footer display-seasons clear\"},[_c('span',[(_vm.show.seasons.length >= 15)?_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.jumpToSeason),expression:\"jumpToSeason\"}],staticClass:\"form-control input-sm\",staticStyle:{\"position\":\"relative\"},attrs:{\"id\":\"seasonJump\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.jumpToSeason=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},[_c('option',{attrs:{\"value\":\"jump\"}},[_vm._v(\"Jump to Season\")]),_vm._v(\" \"),_vm._l((_vm.show.seasons),function(season){return _c('option',{key:'jumpToSeason-' + season[0].season,attrs:{\"data-season\":season[0].season},domProps:{\"value\":'#season-' + season[0].season}},[_vm._v(\"\\n \"+_vm._s(season[0].season === 0 ? 'Specials' : 'Season ' + season[0].season)+\"\\n \")])})],2):(_vm.show.seasons.length >= 1)?[_vm._v(\"\\n Season:\\n \"),_vm._l((_vm.reverse(_vm.show.seasons)),function(season,$index){return [_c('app-link',{key:(\"jumpToSeason-\" + (season[0].season)),attrs:{\"href\":'#season-' + season[0].season}},[_vm._v(_vm._s(season[0].season === 0 ? 'Specials' : season[0].season))]),_vm._v(\" \"),_vm._t(\"default\"),_vm._v(\" \"),($index !== (_vm.show.seasons.length - 1))?_c('span',{key:(\"separator-\" + $index),staticClass:\"separator\"},[_vm._v(\"| \")]):_vm._e()]})]:_vm._e()],2)])]):_vm._e()]):_vm._e()]),_vm._v(\" \"),_vm._l((_vm.activeShowQueueStatuses),function(queueItem){return _c('div',{key:queueItem.action,staticClass:\"row\"},[_c('div',{staticClass:\"alert alert-info\"},[_vm._v(\"\\n \"+_vm._s(queueItem.message)+\"\\n \")])])}),_vm._v(\" \"),_c('div',{staticClass:\"row\",attrs:{\"id\":\"row-show-summary\"}},[_c('div',{staticClass:\"col-md-12\",attrs:{\"id\":\"col-show-summary\"}},[_c('div',{staticClass:\"show-poster-container\"},[_c('div',{staticClass:\"row\"},[_c('div',{staticClass:\"image-flex-container col-md-12\"},[_c('asset',{attrs:{\"default\":\"images/poster.png\",\"show-slug\":_vm.show.id.slug,\"type\":\"posterThumb\",\"cls\":\"show-image shadow\",\"link\":true}})],1)])]),_vm._v(\" \"),_c('div',{staticClass:\"ver-spacer\"}),_vm._v(\" \"),_c('div',{staticClass:\"show-info-container\"},[_c('div',{staticClass:\"row\"},[_c('div',{staticClass:\"pull-right col-lg-3 col-md-3 hidden-sm hidden-xs\"},[_c('asset',{attrs:{\"default\":\"images/banner.png\",\"show-slug\":_vm.show.id.slug,\"type\":\"banner\",\"cls\":\"show-banner pull-right shadow\",\"link\":true}})],1),_vm._v(\" \"),_c('div',{staticClass:\"pull-left col-lg-9 col-md-9 col-sm-12 col-xs-12\",attrs:{\"id\":\"show-rating\"}},[(_vm.show.rating.imdb && _vm.show.rating.imdb.rating)?_c('span',{staticClass:\"imdbstars\",attrs:{\"qtip-content\":_vm.show.rating.imdb.rating + ' / 10 Stars
' + _vm.show.rating.imdb.votes + ' Votes'}},[_c('span',{style:({ width: (Number(_vm.show.rating.imdb.rating) * 12) + '%' })})]):_vm._e(),_vm._v(\" \"),(!_vm.show.id.imdb)?[(_vm.show.year.start)?_c('span',[_vm._v(\"(\"+_vm._s(_vm.show.year.start)+\") - \"+_vm._s(_vm.show.runtime)+\" minutes - \")]):_vm._e()]:[_vm._l((_vm.show.countryCodes),function(country){return _c('img',{key:'flag-' + country,class:['country-flag', 'flag-' + country],staticStyle:{\"margin-left\":\"3px\",\"vertical-align\":\"middle\"},attrs:{\"src\":\"images/blank.png\",\"width\":\"16\",\"height\":\"11\"}})}),_vm._v(\" \"),(_vm.show.imdbInfo.year)?_c('span',[_vm._v(\"\\n (\"+_vm._s(_vm.show.imdbInfo.year)+\") -\\n \")]):_vm._e(),_vm._v(\" \"),_c('span',[_vm._v(\"\\n \"+_vm._s(_vm.show.imdbInfo.runtimes || _vm.show.runtime)+\" minutes\\n \")]),_vm._v(\" \"),_c('app-link',{attrs:{\"href\":'https://www.imdb.com/title/' + _vm.show.id.imdb,\"title\":'https://www.imdb.com/title/' + _vm.show.id.imdb}},[_c('img',{staticStyle:{\"margin-top\":\"-1px\",\"vertical-align\":\"middle\"},attrs:{\"alt\":\"[imdb]\",\"height\":\"16\",\"width\":\"16\",\"src\":\"images/imdb.png\"}})])],_vm._v(\" \"),(_vm.show.id.trakt)?_c('app-link',{attrs:{\"href\":'https://trakt.tv/shows/' + _vm.show.id.trakt,\"title\":'https://trakt.tv/shows/' + _vm.show.id.trakt}},[_c('img',{attrs:{\"alt\":\"[trakt]\",\"height\":\"16\",\"width\":\"16\",\"src\":\"images/trakt.png\"}})]):_vm._e(),_vm._v(\" \"),(_vm.showIndexerUrl && _vm.indexerConfig[_vm.show.indexer].icon)?_c('app-link',{attrs:{\"href\":_vm.showIndexerUrl,\"title\":_vm.showIndexerUrl}},[_c('img',{staticStyle:{\"margin-top\":\"-1px\",\"vertical-align\":\"middle\"},attrs:{\"alt\":_vm.indexerConfig[_vm.show.indexer].name,\"height\":\"16\",\"width\":\"16\",\"src\":'images/' + _vm.indexerConfig[_vm.show.indexer].icon}})]):_vm._e(),_vm._v(\" \"),(_vm.show.xemNumbering)?_c('app-link',{attrs:{\"href\":'http://thexem.de/search?q=' + _vm.show.title,\"title\":'http://thexem.de/search?q=' + _vm.show.title}},[_c('img',{staticStyle:{\"margin-top\":\"-1px\",\"vertical-align\":\"middle\"},attrs:{\"alt\":\"[xem]\",\"height\":\"16\",\"width\":\"16\",\"src\":\"images/xem.png\"}})]):_vm._e(),_vm._v(\" \"),(_vm.show.id.tvdb)?_c('app-link',{attrs:{\"href\":'https://fanart.tv/series/' + _vm.show.id.tvdb,\"title\":'https://fanart.tv/series/' + _vm.show.id[_vm.show.indexer]}},[_c('img',{staticClass:\"fanart\",attrs:{\"alt\":\"[fanart.tv]\",\"height\":\"16\",\"width\":\"16\",\"src\":\"images/fanart.tv.png\"}})]):_vm._e()],2),_vm._v(\" \"),_c('div',{staticClass:\"pull-left col-lg-9 col-md-9 col-sm-12 col-xs-12\",attrs:{\"id\":\"tags\"}},[(_vm.show.genres)?_c('ul',{staticClass:\"tags\"},_vm._l((_vm.dedupeGenres(_vm.show.genres)),function(genre){return _c('app-link',{key:genre.toString(),attrs:{\"href\":'https://trakt.tv/shows/popular/?genres=' + genre.toLowerCase().replace(' ', '-'),\"title\":'View other popular ' + genre + ' shows on trakt.tv'}},[_c('li',[_vm._v(_vm._s(genre))])])}),1):_c('ul',{staticClass:\"tags\"},_vm._l((_vm.showGenres),function(genre){return _c('app-link',{key:genre.toString(),attrs:{\"href\":'https://www.imdb.com/search/title?count=100&title_type=tv_series&genres=' + genre.toLowerCase().replace(' ', '-'),\"title\":'View other popular ' + genre + ' shows on IMDB'}},[_c('li',[_vm._v(_vm._s(genre))])])}),1)])]),_vm._v(\" \"),_c('div',{staticClass:\"row\"},[_c('div',{staticClass:\"col-md-12\",attrs:{\"id\":\"summary\"}},[_c('div',{class:[{ summaryFanArt: _vm.config.fanartBackground }, 'col-lg-9', 'col-md-8', 'col-sm-8', 'col-xs-12'],attrs:{\"id\":\"show-summary\"}},[_c('table',{staticClass:\"summaryTable pull-left\"},[(_vm.show.plot)?_c('tr',[_c('td',{staticStyle:{\"padding-bottom\":\"15px\"},attrs:{\"colspan\":\"2\"}},[_c('truncate',{attrs:{\"length\":250,\"clamp\":\"show more...\",\"less\":\"show less...\",\"text\":_vm.show.plot},on:{\"toggle\":function($event){return _vm.$emit('reflow')}}})],1)]):_vm._e(),_vm._v(\" \"),(_vm.getPreset(_vm.combineQualities(_vm.show.config.qualities.allowed)).length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Quality: \")]),_c('td',[_c('quality-pill',{attrs:{\"quality\":_vm.combineQualities(_vm.show.config.qualities.allowed)}})],1)]):_vm._e(),_vm._v(\" \"),(!_vm.getPreset(_vm.combineQualities(_vm.show.config.qualities.allowed)).length > 0 && _vm.show.config.qualities.allowed)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Quality allowed:\")]),_c('td',[_vm._l((_vm.show.config.qualities.allowed),function(curQuality,$index){return [($index > 0)?[_vm._v(\",\")]:_vm._e(),_vm._v(\" \"),_c('quality-pill',{key:'allowed-' + curQuality,attrs:{\"quality\":curQuality}})]})],2)]):_vm._e(),_vm._v(\" \"),(!_vm.getPreset(_vm.combineQualities(_vm.show.config.qualities.allowed)).length > 0 && _vm.combineQualities(_vm.show.config.qualities.preferred).length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Quality preferred:\")]),_c('td',[_vm._l((_vm.show.config.qualities.preferred),function(curQuality,$index){return [($index > 0)?[_vm._v(\",\")]:_vm._e(),_vm._v(\" \"),_c('quality-pill',{key:'preferred-' + curQuality,attrs:{\"quality\":curQuality}})]})],2)]):_vm._e(),_vm._v(\" \"),(_vm.show.network && _vm.show.airs)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Originally Airs: \")]),_c('td',[_vm._v(_vm._s(_vm.show.airs)+\" \"),(!_vm.show.airsFormatValid)?_c('font',{attrs:{\"color\":\"#FF0000\"}},[_c('b',[_vm._v(\"(invalid Timeformat)\")])]):_vm._e(),_vm._v(\" on \"+_vm._s(_vm.show.network))],1)]):(_vm.show.network)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Originally Airs: \")]),_c('td',[_vm._v(_vm._s(_vm.show.network))])]):(_vm.show.airs)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Originally Airs: \")]),_c('td',[_vm._v(_vm._s(_vm.show.airs)+\" \"),(!_vm.show.airsFormatValid)?_c('font',{attrs:{\"color\":\"#FF0000\"}},[_c('b',[_vm._v(\"(invalid Timeformat)\")])]):_vm._e()],1)]):_vm._e(),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Show Status: \")]),_c('td',[_vm._v(_vm._s(_vm.show.status))])]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Default EP Status: \")]),_c('td',[_vm._v(_vm._s(_vm.show.config.defaultEpisodeStatus))])]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_c('span',{class:{'location-invalid': !_vm.show.config.locationValid}},[_vm._v(\"Location: \")])]),_c('td',[_c('span',{class:{'location-invalid': !_vm.show.config.locationValid}},[_vm._v(_vm._s(_vm.show.config.location))]),_vm._v(_vm._s(_vm.show.config.locationValid ? '' : ' (Missing)'))])]),_vm._v(\" \"),(_vm.show.config.aliases.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\",staticStyle:{\"vertical-align\":\"top\"}},[_vm._v(\"Scene Name:\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.show.config.aliases.join(',')))])]):_vm._e(),_vm._v(\" \"),(_vm.show.config.release.requiredWords.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\",staticStyle:{\"vertical-align\":\"top\"}},[_vm._v(\"Required Words: \")]),_vm._v(\" \"),_c('td',[_c('span',{staticClass:\"break-word\",class:{required: _vm.type === 'snatch-selection'}},[_vm._v(_vm._s(_vm.show.config.release.requiredWords.join(',')))])])]):_vm._e(),_vm._v(\" \"),(_vm.show.config.release.ignoredWords.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\",staticStyle:{\"vertical-align\":\"top\"}},[_vm._v(\"Ignored Words: \")]),_vm._v(\" \"),_c('td',[_c('span',{staticClass:\"break-word\",class:{ignored: _vm.type === 'snatch-selection'}},[_vm._v(_vm._s(_vm.show.config.release.ignoredWords.join(',')))])])]):_vm._e(),_vm._v(\" \"),(_vm.preferredWords.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\",staticStyle:{\"vertical-align\":\"top\"}},[_vm._v(\"Preferred Words: \")]),_vm._v(\" \"),_c('td',[_c('span',{staticClass:\"break-word\",class:{preferred: _vm.type === 'snatch-selection'}},[_vm._v(_vm._s(_vm.preferredWords.join(',')))])])]):_vm._e(),_vm._v(\" \"),(_vm.undesiredWords.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\",staticStyle:{\"vertical-align\":\"top\"}},[_vm._v(\"Undesired Words: \")]),_vm._v(\" \"),_c('td',[_c('span',{staticClass:\"break-word\",class:{undesired: _vm.type === 'snatch-selection'}},[_vm._v(_vm._s(_vm.undesiredWords.join(',')))])])]):_vm._e(),_vm._v(\" \"),(_vm.show.config.release.whitelist && _vm.show.config.release.whitelist.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Wanted Groups:\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.show.config.release.whitelist.join(',')))])]):_vm._e(),_vm._v(\" \"),(_vm.show.config.release.blacklist && _vm.show.config.release.blacklist.length > 0)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Unwanted Groups:\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.show.config.release.blacklist.join(',')))])]):_vm._e(),_vm._v(\" \"),(_vm.show.config.airdateOffset !== 0)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Daily search offset:\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.show.config.airdateOffset)+\" hours\")])]):_vm._e(),_vm._v(\" \"),(_vm.show.config.locationValid && _vm.show.size > -1)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Size:\")]),_vm._v(\" \"),_c('td',[_vm._v(_vm._s(_vm.humanFileSize(_vm.show.size)))])]):_vm._e()])]),_vm._v(\" \"),_c('div',{staticClass:\"col-lg-3 col-md-4 col-sm-4 col-xs-12 pull-xs-left\",attrs:{\"id\":\"show-status\"}},[_c('table',{staticClass:\"pull-xs-left pull-md-right pull-sm-right pull-lg-right\"},[(_vm.show.language)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Info Language:\")]),_c('td',[_c('img',{attrs:{\"src\":'images/subtitles/flags/' + _vm.getCountryISO2ToISO3(_vm.show.language) + '.png',\"width\":\"16\",\"height\":\"11\",\"alt\":_vm.show.language,\"title\":_vm.show.language,\"onError\":\"this.onerror=null;this.src='images/flags/unknown.png';\"}})])]):_vm._e(),_vm._v(\" \"),(_vm.config.subtitles.enabled)?_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Subtitles: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.subtitlesEnabled}})],1)]):_vm._e(),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Season Folders: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.seasonFolders || _vm.config.namingForceFolders}})],1)]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Paused: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.paused}})],1)]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Air-by-Date: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.airByDate}})],1)]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Sports: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.sports}})],1)]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Anime: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.anime}})],1)]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"DVD Order: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.dvdOrder}})],1)]),_vm._v(\" \"),_c('tr',[_c('td',{staticClass:\"showLegend\"},[_vm._v(\"Scene Numbering: \")]),_c('td',[_c('state-switch',{attrs:{\"theme\":_vm.config.themeName,\"state\":_vm.show.config.scene}})],1)])])])])])])])]),_vm._v(\" \"),(_vm.show)?_c('div',{staticClass:\"row\",attrs:{\"id\":\"row-show-episodes-controls\"}},[_c('div',{staticClass:\"col-md-12\",attrs:{\"id\":\"col-show-episodes-controls\"}},[(_vm.type === 'show')?_c('div',{staticClass:\"row key\"},[_c('div',{staticClass:\"col-lg-12\",attrs:{\"id\":\"checkboxControls\"}},[_c('div',{staticClass:\"pull-left top-5\",attrs:{\"id\":\"key-padding\"}},[(_vm.show.seasons)?_c('label',{attrs:{\"for\":\"wanted\"}},[_c('span',{staticClass:\"wanted\"},[_c('input',{attrs:{\"type\":\"checkbox\",\"id\":\"wanted\",\"checked\":\"checked\"},on:{\"input\":function($event){return _vm.showHideRows('wanted')}}}),_vm._v(\" Wanted: \"),_c('b',[_vm._v(_vm._s(_vm.episodeSummary.Wanted))])])]):_vm._e(),_vm._v(\" \"),(_vm.show.seasons)?_c('label',{attrs:{\"for\":\"qual\"}},[_c('span',{staticClass:\"qual\"},[_c('input',{attrs:{\"type\":\"checkbox\",\"id\":\"qual\",\"checked\":\"checked\"},on:{\"input\":function($event){return _vm.showHideRows('qual')}}}),_vm._v(\" Allowed: \"),_c('b',[_vm._v(_vm._s(_vm.episodeSummary.Allowed))])])]):_vm._e(),_vm._v(\" \"),(_vm.show.seasons)?_c('label',{attrs:{\"for\":\"good\"}},[_c('span',{staticClass:\"good\"},[_c('input',{attrs:{\"type\":\"checkbox\",\"id\":\"good\",\"checked\":\"checked\"},on:{\"input\":function($event){return _vm.showHideRows('good')}}}),_vm._v(\" Preferred: \"),_c('b',[_vm._v(_vm._s(_vm.episodeSummary.Preferred))])])]):_vm._e(),_vm._v(\" \"),(_vm.show.seasons)?_c('label',{attrs:{\"for\":\"skipped\"}},[_c('span',{staticClass:\"skipped\"},[_c('input',{attrs:{\"type\":\"checkbox\",\"id\":\"skipped\",\"checked\":\"checked\"},on:{\"input\":function($event){return _vm.showHideRows('skipped')}}}),_vm._v(\" Skipped: \"),_c('b',[_vm._v(_vm._s(_vm.episodeSummary.Skipped))])])]):_vm._e(),_vm._v(\" \"),(_vm.show.seasons)?_c('label',{attrs:{\"for\":\"snatched\"}},[_c('span',{staticClass:\"snatched\"},[_c('input',{attrs:{\"type\":\"checkbox\",\"id\":\"snatched\",\"checked\":\"checked\"},on:{\"input\":function($event){return _vm.showHideRows('snatched')}}}),_vm._v(\" Snatched: \"),_c('b',[_vm._v(_vm._s(_vm.episodeSummary.Snatched + _vm.episodeSummary['Snatched (Proper)'] + _vm.episodeSummary['Snatched (Best)']))])])]):_vm._e(),_vm._v(\" \"),_c('button',{staticClass:\"btn-medusa seriesCheck\",on:{\"click\":_vm.selectEpisodesClicked}},[_vm._v(\"Select Episodes\")]),_vm._v(\" \"),_c('button',{staticClass:\"btn-medusa clearAll\",on:{\"click\":_vm.clearEpisodeSelectionClicked}},[_vm._v(\"Clear\")])]),_vm._v(\" \"),_c('div',{staticClass:\"pull-lg-right top-5\"},[_c('select',{staticClass:\"form-control form-control-inline input-sm-custom input-sm-smallfont\",attrs:{\"id\":\"statusSelect\"}},_vm._l((_vm.changeStatusOptions),function(option){return _c('option',{key:option.value,domProps:{\"value\":option.value}},[_vm._v(\"\\n \"+_vm._s(option.text)+\"\\n \")])}),0),_vm._v(\" \"),_c('select',{staticClass:\"form-control form-control-inline input-sm-custom input-sm-smallfont\",attrs:{\"id\":\"qualitySelect\"}},_vm._l((_vm.changeQualityOptions),function(option){return _c('option',{key:option.value,domProps:{\"value\":option.value}},[_vm._v(\"\\n \"+_vm._s(option.text)+\"\\n \")])}),0),_vm._v(\" \"),_c('input',{attrs:{\"type\":\"hidden\",\"id\":\"series-slug\"},domProps:{\"value\":_vm.show.id.slug}}),_vm._v(\" \"),_c('input',{attrs:{\"type\":\"hidden\",\"id\":\"series-id\"},domProps:{\"value\":_vm.show.id[_vm.show.indexer]}}),_vm._v(\" \"),_c('input',{attrs:{\"type\":\"hidden\",\"id\":\"indexer\"},domProps:{\"value\":_vm.show.indexer}}),_vm._v(\" \"),_c('input',{staticClass:\"btn-medusa\",attrs:{\"type\":\"button\",\"id\":\"changeStatus\",\"value\":\"Go\"},on:{\"click\":_vm.changeStatusClicked}})])])]):_c('div')])]):_vm._e()],2)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-header.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-header.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./show-header.vue?vue&type=template&id=e712fe74&scoped=true&\"\nimport script from \"./show-header.vue?vue&type=script&lang=js&\"\nexport * from \"./show-header.vue?vue&type=script&lang=js&\"\nimport style0 from \"./show-header.vue?vue&type=style&index=0&id=e712fe74&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"e712fe74\",\n null\n \n)\n\nexport default component.exports","import VueRouter from 'vue-router';\n\nconst AddRecommended = () => import('./components/add-recommended.vue');\nconst AddShows = () => import('./components/add-shows.vue');\nconst Config = () => import('./components/config.vue');\nconst ConfigPostProcessing = () => import('./components/config-post-processing.vue');\nconst IRC = () => import('./components/irc.vue');\nconst Login = () => import('./components/login.vue');\nconst NotFound = () => import('./components/http/404.vue');\n\nconst homeRoutes = [{\n path: '/home',\n name: 'home',\n meta: {\n title: 'Home',\n header: 'Show List',\n topMenu: 'home'\n }\n}, {\n path: '/home/editShow',\n name: 'editShow',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/home/displayShow',\n name: 'show',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/home/snatchSelection',\n name: 'snatchSelection',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/home/testRename',\n name: 'testRename',\n meta: {\n title: 'Preview Rename',\n header: 'Preview Rename',\n topMenu: 'home'\n }\n}, {\n path: '/home/postprocess',\n name: 'postprocess',\n meta: {\n title: 'Manual Post-Processing',\n header: 'Manual Post-Processing',\n topMenu: 'home'\n }\n}, {\n path: '/home/status',\n name: 'status',\n meta: {\n title: 'Status',\n topMenu: 'system'\n }\n}, {\n path: '/home/restart',\n name: 'restart',\n meta: {\n title: 'Restarting...',\n header: 'Performing Restart',\n topMenu: 'system'\n }\n}, {\n path: '/home/shutdown',\n name: 'shutdown',\n meta: {\n header: 'Shutting down',\n topMenu: 'system'\n }\n}, {\n path: '/home/update',\n name: 'update',\n meta: {\n topMenu: 'system'\n }\n}];\n\nconst configRoutes = [{\n path: '/config',\n name: 'config',\n meta: {\n title: 'Help & Info',\n header: 'Medusa Configuration',\n topMenu: 'config',\n converted: true\n },\n component: Config\n}, {\n path: '/config/anime',\n name: 'configAnime',\n meta: {\n title: 'Config - Anime',\n header: 'Anime',\n topMenu: 'config'\n }\n}, {\n path: '/config/backuprestore',\n name: 'configBackupRestore',\n meta: {\n title: 'Config - Backup/Restore',\n header: 'Backup/Restore',\n topMenu: 'config'\n }\n}, {\n path: '/config/general',\n name: 'configGeneral',\n meta: {\n title: 'Config - General',\n header: 'General Configuration',\n topMenu: 'config'\n }\n}, {\n path: '/config/notifications',\n name: 'configNotifications',\n meta: {\n title: 'Config - Notifications',\n header: 'Notifications',\n topMenu: 'config'\n }\n}, {\n path: '/config/postProcessing',\n name: 'configPostProcessing',\n meta: {\n title: 'Config - Post Processing',\n header: 'Post Processing',\n topMenu: 'config'\n },\n component: ConfigPostProcessing\n}, {\n path: '/config/providers',\n name: 'configSearchProviders',\n meta: {\n title: 'Config - Providers',\n header: 'Search Providers',\n topMenu: 'config'\n }\n}, {\n path: '/config/search',\n name: 'configSearchSettings',\n meta: {\n title: 'Config - Episode Search',\n header: 'Search Settings',\n topMenu: 'config'\n }\n}, {\n path: '/config/subtitles',\n name: 'configSubtitles',\n meta: {\n title: 'Config - Subtitles',\n header: 'Subtitles',\n topMenu: 'config'\n }\n}];\n\nconst addShowRoutes = [{\n path: '/addShows',\n name: 'addShows',\n meta: {\n title: 'Add Shows',\n header: 'Add Shows',\n topMenu: 'home',\n converted: true\n },\n component: AddShows\n}, {\n path: '/addShows/addExistingShows',\n name: 'addExistingShows',\n meta: {\n title: 'Add Existing Shows',\n header: 'Add Existing Shows',\n topMenu: 'home'\n }\n}, {\n path: '/addShows/newShow',\n name: 'addNewShow',\n meta: {\n title: 'Add New Show',\n header: 'Add New Show',\n topMenu: 'home'\n }\n}, {\n path: '/addShows/trendingShows',\n name: 'addTrendingShows',\n meta: {\n topMenu: 'home'\n }\n}, {\n path: '/addShows/popularShows',\n name: 'addPopularShows',\n meta: {\n title: 'Popular Shows',\n header: 'Popular Shows',\n topMenu: 'home'\n }\n}, {\n path: '/addShows/popularAnime',\n name: 'addPopularAnime',\n meta: {\n title: 'Popular Anime Shows',\n header: 'Popular Anime Shows',\n topMenu: 'home'\n }\n}];\n\nconst loginRoute = {\n path: '/login',\n name: 'login',\n meta: {\n title: 'Login'\n },\n component: Login\n};\n\nconst addRecommendedRoute = {\n path: '/addRecommended',\n name: 'addRecommended',\n meta: {\n title: 'Add Recommended Shows',\n header: 'Add Recommended Shows',\n topMenu: 'home'\n },\n component: AddRecommended\n};\n\nconst scheduleRoute = {\n path: '/schedule',\n name: 'schedule',\n meta: {\n title: 'Schedule',\n header: 'Schedule',\n topMenu: 'schedule'\n }\n};\n\nconst historyRoute = {\n path: '/history',\n name: 'history',\n meta: {\n title: 'History',\n header: 'History',\n topMenu: 'history'\n }\n};\n\nconst manageRoutes = [{\n path: '/manage',\n name: 'manage',\n meta: {\n title: 'Mass Update',\n header: 'Mass Update',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/backlogOverview',\n name: 'manageBacklogOverview',\n meta: {\n title: 'Backlog Overview',\n header: 'Backlog Overview',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/episodeStatuses',\n name: 'manageEpisodeOverview',\n meta: {\n title: 'Episode Overview',\n header: 'Episode Overview',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/failedDownloads',\n name: 'manageFailedDownloads',\n meta: {\n title: 'Failed Downloads',\n header: 'Failed Downlaods',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/manageSearches',\n name: 'manageManageSearches',\n meta: {\n title: 'Manage Searches',\n header: 'Manage Searches',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/massEdit',\n name: 'manageMassEdit',\n meta: {\n title: 'Mass Edit',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/subtitleMissed',\n name: 'manageSubtitleMissed',\n meta: {\n title: 'Missing Subtitles',\n header: 'Missing Subtitles',\n topMenu: 'manage'\n }\n}, {\n path: '/manage/subtitleMissedPP',\n name: 'manageSubtitleMissedPP',\n meta: {\n title: 'Missing Subtitles in Post-Process folder',\n header: 'Missing Subtitles in Post-Process folder',\n topMenu: 'manage'\n }\n}];\n\nconst errorLogsRoutes = [{\n path: '/errorlogs',\n name: 'errorlogs',\n meta: {\n title: 'Logs & Errors',\n topMenu: 'system'\n }\n}, {\n path: '/errorlogs/viewlog',\n name: 'viewlog',\n meta: {\n title: 'Logs',\n header: 'Log File',\n topMenu: 'system'\n }\n}];\n\nconst newsRoute = {\n path: '/news',\n name: 'news',\n meta: {\n title: 'News',\n header: 'News',\n topMenu: 'system'\n }\n};\n\nconst changesRoute = {\n path: '/changes',\n name: 'changes',\n meta: {\n title: 'Changelog',\n header: 'Changelog',\n topMenu: 'system'\n }\n};\n\nconst ircRoute = {\n path: '/IRC',\n name: 'IRC',\n meta: {\n title: 'IRC',\n topMenu: 'system'\n },\n component: IRC\n};\n\nconst notFoundRoute = {\n path: '/not-found',\n name: 'not-found',\n meta: {\n title: '404',\n header: '404 - page not found'\n },\n component: NotFound\n};\n\n// @NOTE: Redirect can only be added once all routes are vue\n/*\nconst notFoundRedirect = {\n path: '*',\n redirect: '/not-found'\n};\n*/\n\nconst routes = [\n ...homeRoutes,\n ...configRoutes,\n ...addShowRoutes,\n loginRoute,\n addRecommendedRoute,\n scheduleRoute,\n historyRoute,\n ...manageRoutes,\n ...errorLogsRoutes,\n newsRoute,\n changesRoute,\n ircRoute,\n notFoundRoute\n];\n\nconst router = new VueRouter({\n base: document.body.getAttribute('web-root') + '/',\n mode: 'history',\n routes\n});\n\nrouter.beforeEach((to, from, next) => {\n const { meta } = to;\n const { title } = meta;\n\n // If there's no title then it's not a .vue route\n // or it's handling its own title\n if (title) {\n document.title = `${title} | Medusa`;\n }\n\n // Always call next otherwise the will be empty\n next();\n});\n\nexport default router;\n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","\n\n\n\n","\n\n\n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","// style-loader: Adds some css to the DOM by adding a \n","\n\n\n","// style-loader: Adds some css to the DOM by adding a \n","\n\n\n","// style-loader: Adds some css to the DOM by adding a \n","\n \n
\n
= 1\" id=\"show-specials-and-seasons\" class=\"pull-right\">\n ({ season }) => season === 0)\">\n Display Specials: {{ displaySpecials ? 'Hide' : 'Show' }}\n \n\n
\n \n \n \n \n
\n
\n
\n \n\n
\n
\n {{ queueItem.message }}\n
\n
\n\n
\n
\n
\n
\n
\n \n
\n
\n
\n\n
\n\n
\n
\n
\n \n
\n
\n ' + show.rating.imdb.votes + ' Votes'\"\n >\n \n \n \n \n \n \"[trakt]\"\n \n \n \n \n\n \n \"[xem]\"\n \n\n \n \"[fanart.tv]\"\n \n
\n
\n
    \n
  • {{ genre }}
  • \n
\n
    \n
  • {{ genre }}
  • \n
\n
\n
\n\n
\n \n
\n
\n \n \n \n \n\n \n 0\">\n \n\n \n 0 && show.config.qualities.allowed\">\n \n\n 0 && combineQualities(show.config.qualities.preferred).length > 0\">\n \n\n \n \n \n \n \n \n\n 0\">\n \n \n \n\n 0\">\n \n \n \n 0\">\n \n \n \n\n 0\">\n \n \n \n 0\">\n \n \n \n\n 0\">\n \n \n \n\n 0\">\n \n \n \n\n \n \n \n \n -1\">\n \n \n \n
\n \n
Quality: \n \n
Quality allowed:\n \n
Quality preferred:\n \n
Originally Airs: {{ show.airs }} (invalid Timeformat) on {{ show.network }}
Originally Airs: {{ show.network }}
Originally Airs: {{ show.airs }} (invalid Timeformat)
Show Status: {{ show.status }}
Default EP Status: {{ show.config.defaultEpisodeStatus }}
Location: {{show.config.location}}{{show.config.locationValid ? '' : ' (Missing)'}}
Scene Name:{{show.config.aliases.join(',')}}
Required Words: {{show.config.release.requiredWords.join(',')}}
Ignored Words: {{show.config.release.ignoredWords.join(',')}}
Preferred Words: {{preferredWords.join(',')}}
Undesired Words: {{undesiredWords.join(',')}}
Wanted Groups:{{show.config.release.whitelist.join(',')}}
Unwanted Groups:{{show.config.release.blacklist.join(',')}}
Daily search offset:{{show.config.airdateOffset}} hours
Size:{{humanFileSize(show.size)}}
\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
Info Language:
Subtitles:
Season Folders:
Paused:
Air-by-Date:
Sports:
Anime:
DVD Order:
Scene Numbering:
\n
\n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n\n \n \n \n \n \n \n \n
\n
\n\n \n\n \n \n \n \n \n
\n
\n
\n
\n
\n
\n \n\n\n\n\n\n","// style-loader: Adds some css to the DOM by adding a \n","\n\n\n","const LOGIN_PENDING = '🔒 Logging in';\nconst LOGIN_SUCCESS = '🔒 ✅ Login Successful';\nconst LOGIN_FAILED = '🔒 ❌ Login Failed';\nconst LOGOUT = '🔒 Logout';\nconst REFRESH_TOKEN = '🔒 Refresh Token';\nconst REMOVE_AUTH_ERROR = '🔒 Remove Auth Error';\nconst SOCKET_ONOPEN = '🔗 ✅ WebSocket connected';\nconst SOCKET_ONCLOSE = '🔗 ❌ WebSocket disconnected';\nconst SOCKET_ONERROR = '🔗 ❌ WebSocket error';\nconst SOCKET_ONMESSAGE = '🔗 ✉️ 📥 WebSocket message received';\nconst SOCKET_RECONNECT = '🔗 🔃 WebSocket reconnecting';\nconst SOCKET_RECONNECT_ERROR = '🔗 🔃 ❌ WebSocket reconnection attempt failed';\nconst NOTIFICATIONS_ENABLED = '🔔 Notifications Enabled';\nconst NOTIFICATIONS_DISABLED = '🔔 Notifications Disabled';\nconst ADD_CONFIG = '⚙️ Config added to store';\nconst ADD_SHOW = '📺 Show added to store';\n\nexport {\n LOGIN_PENDING,\n LOGIN_SUCCESS,\n LOGIN_FAILED,\n LOGOUT,\n REFRESH_TOKEN,\n REMOVE_AUTH_ERROR,\n SOCKET_ONOPEN,\n SOCKET_ONCLOSE,\n SOCKET_ONERROR,\n SOCKET_ONMESSAGE,\n SOCKET_RECONNECT,\n SOCKET_RECONNECT_ERROR,\n NOTIFICATIONS_ENABLED,\n NOTIFICATIONS_DISABLED,\n ADD_CONFIG,\n ADD_SHOW\n};\n","import {\n LOGIN_PENDING,\n LOGIN_SUCCESS,\n LOGIN_FAILED,\n LOGOUT,\n REFRESH_TOKEN,\n REMOVE_AUTH_ERROR\n} from '../mutation-types';\n\nconst state = {\n isAuthenticated: false,\n user: {},\n tokens: {\n access: null,\n refresh: null\n },\n error: null\n};\n\nconst mutations = {\n [LOGIN_PENDING]() { },\n [LOGIN_SUCCESS](state, user) {\n state.user = user;\n state.isAuthenticated = true;\n state.error = null;\n },\n [LOGIN_FAILED](state, { error }) {\n state.user = {};\n state.isAuthenticated = false;\n state.error = error;\n },\n [LOGOUT](state) {\n state.user = {};\n state.isAuthenticated = false;\n state.error = null;\n },\n [REFRESH_TOKEN]() {},\n [REMOVE_AUTH_ERROR]() {}\n};\n\nconst getters = {};\n\nconst actions = {\n login(context, credentials) {\n const { commit } = context;\n commit(LOGIN_PENDING);\n\n // @TODO: Add real JWT login\n const apiLogin = credentials => Promise.resolve(credentials);\n\n apiLogin(credentials).then(user => {\n return commit(LOGIN_SUCCESS, user);\n }).catch(error => {\n commit(LOGIN_FAILED, { error, credentials });\n });\n },\n logout(context) {\n const { commit } = context;\n commit(LOGOUT);\n }\n};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { ADD_CONFIG } from '../mutation-types';\n\nconst state = {\n torrents: {\n authType: null,\n dir: null,\n enabled: null,\n highBandwidth: null,\n host: null,\n label: null,\n labelAnime: null,\n method: null,\n path: null,\n paused: null,\n rpcUrl: null,\n seedLocation: null,\n seedTime: null,\n username: null,\n password: null,\n verifySSL: null,\n testStatus: 'Click below to test'\n },\n nzb: {\n enabled: null,\n method: null,\n nzbget: {\n category: null,\n categoryAnime: null,\n categoryAnimeBacklog: null,\n categoryBacklog: null,\n host: null,\n priority: null,\n useHttps: null,\n username: null,\n password: null\n },\n sabnzbd: {\n category: null,\n forced: null,\n categoryAnime: null,\n categoryBacklog: null,\n categoryAnimeBacklog: null,\n host: null,\n username: null,\n password: null,\n apiKey: null\n }\n }\n};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'clients') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { api } from '../../api';\nimport { ADD_CONFIG } from '../mutation-types';\n\nconst state = {\n wikiUrl: null,\n donationsUrl: null,\n localUser: null,\n posterSortdir: null,\n locale: null,\n themeName: null,\n selectedRootIndex: null,\n webRoot: null,\n namingForceFolders: null,\n cacheDir: null,\n databaseVersion: {\n major: null,\n minor: null\n },\n programDir: null,\n dataDir: null,\n animeSplitHomeInTabs: null,\n torrents: {\n authType: null,\n dir: null,\n enabled: null,\n highBandwidth: null,\n host: null,\n label: null,\n labelAnime: null,\n method: null,\n path: null,\n paused: null,\n rpcurl: null,\n seedLocation: null,\n seedTime: null,\n username: null,\n verifySSL: null\n },\n layout: {\n show: {\n specials: null,\n showListOrder: [],\n allSeasons: null\n },\n home: null,\n history: null,\n schedule: null\n },\n dbPath: null,\n nzb: {\n enabled: null,\n method: null,\n nzbget: {\n category: null,\n categoryAnime: null,\n categoryAnimeBacklog: null,\n categoryBacklog: null,\n host: null,\n priority: null,\n useHttps: null,\n username: null\n },\n sabnzbd: {\n category: null,\n forced: null,\n categoryAnime: null,\n categoryBacklog: null,\n categoryAnimeBacklog: null,\n host: null,\n username: null,\n password: null,\n apiKey: null\n }\n },\n configFile: null,\n fanartBackground: null,\n trimZero: null,\n animeSplitHome: null,\n gitUsername: null,\n branch: null,\n commitHash: null,\n indexers: {\n config: {\n main: {\n externalMappings: {},\n statusMap: {},\n traktIndexers: {},\n validLanguages: [],\n langabbvToId: {}\n },\n indexers: {\n tvdb: {\n apiParams: {\n useZip: null,\n language: null\n },\n baseUrl: null,\n enabled: null,\n icon: null,\n id: null,\n identifier: null,\n mappedTo: null,\n name: null,\n scene_loc: null, // eslint-disable-line camelcase\n showUrl: null,\n xemOrigin: null\n },\n tmdb: {\n apiParams: {\n useZip: null,\n language: null\n },\n baseUrl: null,\n enabled: null,\n icon: null,\n id: null,\n identifier: null,\n mappedTo: null,\n name: null,\n scene_loc: null, // eslint-disable-line camelcase\n showUrl: null,\n xemOrigin: null\n },\n tvmaze: {\n apiParams: {\n useZip: null,\n language: null\n },\n baseUrl: null,\n enabled: null,\n icon: null,\n id: null,\n identifier: null,\n mappedTo: null,\n name: null,\n scene_loc: null, // eslint-disable-line camelcase\n showUrl: null,\n xemOrigin: null\n }\n }\n }\n },\n sourceUrl: null,\n rootDirs: [],\n fanartBackgroundOpacity: null,\n appArgs: [],\n comingEpsDisplayPaused: null,\n sortArticle: null,\n timePreset: null,\n subtitles: {\n enabled: null\n },\n fuzzyDating: null,\n backlogOverview: {\n status: null,\n period: null\n },\n posterSortby: null,\n news: {\n lastRead: null,\n latest: null,\n unread: null\n },\n logs: {\n loggingLevels: {},\n numErrors: null,\n numWarnings: null\n },\n failedDownloads: {\n enabled: null,\n deleteFailed: null\n },\n postProcessing: {\n naming: {\n pattern: null,\n multiEp: null,\n enableCustomNamingSports: null,\n enableCustomNamingAirByDate: null,\n patternSports: null,\n patternAirByDate: null,\n enableCustomNamingAnime: null,\n patternAnime: null,\n animeMultiEp: null,\n animeNamingType: null,\n stripYear: null\n },\n showDownloadDir: null,\n processAutomatically: null,\n processMethod: null,\n deleteRarContent: null,\n unpack: null,\n noDelete: null,\n reflinkAvailable: null,\n postponeIfSyncFiles: null,\n autoPostprocessorFrequency: 10,\n airdateEpisodes: null,\n moveAssociatedFiles: null,\n allowedExtensions: [],\n addShowsWithoutDir: null,\n createMissingShowDirs: null,\n renameEpisodes: null,\n postponeIfNoSubs: null,\n nfoRename: null,\n syncFiles: [],\n fileTimestampTimezone: 'local',\n extraScripts: [],\n extraScriptsUrl: null,\n multiEpStrings: {}\n },\n sslVersion: null,\n pythonVersion: null,\n comingEpsSort: null,\n githubUrl: null,\n datePreset: null,\n subtitlesMulti: null,\n pid: null,\n os: null,\n anonRedirect: null,\n logDir: null,\n recentShows: [],\n showDefaults: {\n status: null,\n statusAfter: null,\n quality: null,\n subtitles: null,\n seasonFolders: null,\n anime: null,\n scene: null\n }\n};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'main') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {\n layout: state => layout => {\n return state.layout[layout];\n }\n};\n\nconst actions = {\n getConfig(context, section) {\n const { commit } = context;\n return api.get('/config/' + (section || '')).then(res => {\n if (section) {\n const config = res.data;\n commit(ADD_CONFIG, { section, config });\n return config;\n }\n\n const sections = res.data;\n Object.keys(sections).forEach(section => {\n const config = sections[section];\n commit(ADD_CONFIG, { section, config });\n });\n return sections;\n });\n },\n setConfig(context, { section, config }) {\n if (section !== 'main') {\n return;\n }\n\n // If an empty config object was passed, use the current state config\n config = Object.keys(config).length === 0 ? context.state : config;\n\n return api.patch('config/' + section, config);\n },\n updateConfig(context, { section, config }) {\n const { commit } = context;\n return commit(ADD_CONFIG, { section, config });\n },\n setLayout(context, { page, layout }) {\n return api.patch('config/main', {\n layout: {\n [page]: layout\n }\n }).then(() => {\n setTimeout(() => {\n // For now we reload the page since the layouts use python still\n location.reload();\n }, 500);\n });\n }\n};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","const state = {\n show: {\n airs: null,\n airsFormatValid: null,\n akas: null,\n cache: null,\n classification: null,\n config: {\n airByDate: null,\n aliases: [],\n anime: null,\n defaultEpisodeStatus: null,\n dvdOrder: null,\n location: null,\n locationValid: null,\n paused: null,\n qualities: {\n allowed: [],\n preferred: []\n },\n release: {\n requiredWords: [],\n ignoredWords: [],\n blacklist: [],\n whitelist: [],\n allgroups: [],\n requiredWordsExclude: null,\n ignoredWordsExclude: null\n },\n scene: null,\n seasonFolders: null,\n sports: null,\n subtitlesEnabled: null,\n airdateOffset: null\n },\n countries: null,\n genres: [],\n id: {\n tvdb: null,\n slug: null\n },\n indexer: null,\n imdbInfo: {\n akas: null,\n certificates: null,\n countries: null,\n countryCodes: null,\n genres: null,\n imdbId: null,\n imdbInfoId: null,\n indexer: null,\n indexerId: null,\n lastUpdate: null,\n plot: null,\n rating: null,\n runtimes: null,\n title: null,\n votes: null\n },\n language: null,\n network: null,\n nextAirDate: null,\n plot: null,\n rating: {\n imdb: {\n rating: null,\n votes: null\n }\n },\n runtime: null,\n showType: null,\n status: null,\n title: null,\n type: null,\n year: {},\n size: null,\n showQueueStatus: [],\n xemNumbering: []\n }\n};\n\nconst mutations = {};\n\nconst getters = {};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { ADD_CONFIG } from '../mutation-types';\n\nconst state = {\n metadataProviders: {}\n};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'metadata') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { NOTIFICATIONS_ENABLED, NOTIFICATIONS_DISABLED } from '../mutation-types';\n\nconst state = {\n enabled: true\n};\n\nconst mutations = {\n [NOTIFICATIONS_ENABLED](state) {\n state.enabled = true;\n },\n [NOTIFICATIONS_DISABLED](state) {\n state.enabled = false;\n }\n};\n\nconst getters = {};\n\nconst actions = {\n enable(context) {\n const { commit } = context;\n commit(NOTIFICATIONS_ENABLED);\n },\n disable(context) {\n const { commit } = context;\n commit(NOTIFICATIONS_DISABLED);\n },\n test() {\n return window.displayNotification('error', 'test', 'test
hello world
  • item 1
  • item 2
', 'notification-test');\n }\n};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n accessToken: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n host: null,\n port: null,\n from: null,\n tls: null,\n username: null,\n password: null,\n addressList: [],\n subject: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n host: null,\n apiKey: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n host: null,\n password: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n alwaysOn: null,\n libraryCleanPending: null,\n cleanLibrary: null,\n host: [],\n username: null,\n password: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n update: {\n library: null,\n full: null,\n onlyFirst: null\n }\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n host: null,\n database: null,\n mount: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n host: null,\n dbloc: null,\n database: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n client: {\n host: [],\n username: null,\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null\n },\n server: {\n updateLibrary: null,\n host: [],\n enabled: null,\n https: null,\n username: null,\n password: null,\n token: null\n }\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n api: [],\n messageTitle: null,\n priority: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n authToken: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n authToken: null,\n device: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n api: null,\n device: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n apiKey: null,\n userKey: null,\n device: [],\n sound: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n host: null,\n name: null,\n shareName: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n webhook: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n api: null,\n id: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n pinUrl: null,\n username: null,\n accessToken: null,\n timeout: null,\n defaultIndexer: null,\n sync: null,\n syncRemove: null,\n syncWatchlist: null,\n methodAdd: null,\n removeWatchlist: null,\n removeSerieslist: null,\n removeShowFromApplication: null,\n startPaused: null,\n blacklistName: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","export const state = {\n enabled: null,\n notifyOnSnatch: null,\n notifyOnDownload: null,\n notifyOnSubtitleDownload: null,\n dmto: null,\n username: null,\n password: null,\n prefix: null,\n directMessage: null\n};\n\nexport const mutations = {};\n\nexport const getters = {};\n\nexport const actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { ADD_CONFIG } from '../../mutation-types';\nimport boxcar2 from './boxcar2';\nimport email from './email';\nimport emby from './emby';\nimport growl from './growl';\nimport kodi from './kodi';\nimport libnotify from './libnotify';\nimport nmj from './nmj';\nimport nmjv2 from './nmjv2';\nimport plex from './plex';\nimport prowl from './prowl';\nimport pushalot from './pushalot';\nimport pushbullet from './pushbullet';\nimport join from './join';\nimport pushover from './pushover';\nimport pyTivo from './py-tivo';\nimport slack from './slack';\nimport synology from './synology';\nimport synologyIndex from './synology-index';\nimport telegram from './telegram';\nimport trakt from './trakt';\nimport twitter from './twitter';\n\nconst state = {};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'notifiers') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {};\n\nconst actions = {};\n\nconst modules = {\n boxcar2,\n email,\n emby,\n growl,\n kodi,\n libnotify,\n nmj,\n nmjv2,\n plex,\n prowl,\n pushalot,\n pushbullet,\n join,\n pushover,\n pyTivo,\n slack,\n synology,\n synologyIndex,\n telegram,\n trakt,\n twitter\n};\n\nexport default {\n state,\n mutations,\n getters,\n actions,\n modules\n};\n","import { ADD_CONFIG } from '../mutation-types';\n\nconst state = {\n values: {},\n anySets: {},\n presets: {},\n strings: {\n values: {},\n anySets: {},\n presets: {},\n cssClass: {}\n }\n};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'qualities') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {\n getPreset: state => value => {\n return Object.keys(state.presets)\n .filter(key => {\n return state.presets[key] === value;\n })\n .map(key => {\n return {\n [key]: state.presets[key]\n };\n });\n },\n combineQualities: () => qualities => {\n const reducer = (accumulator, currentValue) => accumulator | currentValue;\n return qualities.reduce(reducer, 0);\n }\n};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import Vue from 'vue';\nimport { api } from '../../api';\nimport { ADD_SHOW } from '../mutation-types';\n\nconst state = {\n shows: [],\n currentShow: {\n indexer: null,\n id: null\n }\n};\n\nconst mutations = {\n [ADD_SHOW](state, show) {\n const existingShow = state.shows.find(({ id, indexer }) => Number(show.id[show.indexer]) === Number(id[indexer]));\n\n if (!existingShow) {\n console.debug(`Adding ${show.title || show.indexer + String(show.id)} as it wasn't found in the shows array`, show);\n state.shows.push(show);\n return;\n }\n\n // Merge new show object over old one\n // this allows detailed queries to update the record\n // without the non-detailed removing the extra data\n console.debug(`Found ${show.title || show.indexer + String(show.id)} in shows array attempting merge`);\n const newShow = {\n ...existingShow,\n ...show\n };\n\n // Update state\n Vue.set(state.shows, state.shows.indexOf(existingShow), newShow);\n console.debug(`Merged ${newShow.title || newShow.indexer + String(newShow.id)}`, newShow);\n },\n currentShow(state, { indexer, id }) {\n state.currentShow.indexer = indexer;\n state.currentShow.id = id;\n }\n};\n\nconst getters = {\n getShowById: state => ({ id, indexer }) => state.shows.find(show => Number(show.id[indexer]) === Number(id)),\n getShowByTitle: state => title => state.shows.find(show => show.title === title),\n getSeason: state => ({ id, indexer, season }) => {\n const show = state.shows.find(show => Number(show.id[indexer]) === Number(id));\n return show && show.seasons ? show.seasons[season] : undefined;\n },\n getEpisode: state => ({ id, indexer, season, episode }) => {\n const show = state.shows.find(show => Number(show.id[indexer]) === Number(id));\n return show && show.seasons && show.seasons[season] ? show.seasons[season][episode] : undefined;\n },\n getCurrentShow: (state, getters, rootState) => {\n return state.shows.find(show => Number(show.id[state.currentShow.indexer]) === Number(state.currentShow.id)) || rootState.defaults.show;\n }\n};\n\n/**\n * An object representing request parameters for getting a show from the API.\n *\n * @typedef {Object} ShowParameteres\n * @property {string} indexer - The indexer name (e.g. `tvdb`)\n * @property {string} id - The show ID on the indexer (e.g. `12345`)\n * @property {boolean} detailed - Whether to fetch detailed information (seasons & episodes)\n * @property {boolean} fetch - Whether to fetch external information (for example AniDB release groups)\n */\nconst actions = {\n /**\n * Get show from API and commit it to the store.\n *\n * @param {*} context - The store context.\n * @param {ShowParameteres} parameters - Request parameters.\n * @returns {Promise} The API response.\n */\n getShow(context, { indexer, id, detailed, fetch }) {\n return new Promise((resolve, reject) => {\n const { commit } = context;\n const params = {};\n\n if (detailed !== undefined) {\n params.detailed = Boolean(detailed);\n }\n\n if (fetch !== undefined) {\n params.fetch = Boolean(fetch);\n }\n\n api.get('/series/' + indexer + id, { params })\n .then(res => {\n commit(ADD_SHOW, res.data);\n resolve(res.data);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n /**\n * Get shows from API and commit them to the store.\n *\n * @param {*} context - The store context.\n * @param {ShowParameteres[]} shows - Shows to get. If not provided, gets the first 10k shows.\n * @returns {(undefined|Promise)} undefined if `shows` was provided or the API response if not.\n */\n getShows(context, shows) {\n const { commit, dispatch } = context;\n\n // If no shows are provided get the first 1000\n if (!shows) {\n return (() => {\n const limit = 1000;\n const page = 1;\n const params = {\n limit,\n page\n };\n\n // Get first page\n api.get('/series', { params })\n .then(response => {\n const totalPages = Number(response.headers['x-pagination-total']);\n response.data.forEach(show => {\n commit(ADD_SHOW, show);\n });\n\n // Optionally get additional pages\n const pageRequests = [];\n for (let page = 2; page <= totalPages; page++) {\n const newPage = { page };\n newPage.limit = params.limit;\n pageRequests.push(api.get('/series', { params: newPage }).then(response => {\n response.data.forEach(show => {\n commit(ADD_SHOW, show);\n });\n }));\n }\n\n return Promise.all(pageRequests);\n })\n .catch(() => {\n console.log('Could not retrieve a list of shows');\n });\n })();\n }\n\n return shows.forEach(show => dispatch('getShow', show));\n }\n};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { ADD_CONFIG } from '../mutation-types';\n\nconst state = {\n filters: {\n ignoreUnknownSubs: false,\n ignored: [\n 'german',\n 'french',\n 'core2hd',\n 'dutch',\n 'swedish',\n 'reenc',\n 'MrLss',\n 'dubbed'\n ],\n undesired: [\n 'internal',\n 'xvid'\n ],\n ignoredSubsList: [\n 'dk',\n 'fin',\n 'heb',\n 'kor',\n 'nor',\n 'nordic',\n 'pl',\n 'swe'\n ],\n required: [],\n preferred: []\n },\n general: {\n minDailySearchFrequency: 10,\n minBacklogFrequency: 720,\n dailySearchFrequency: 40,\n checkPropersInterval: '4h',\n usenetRetention: 500,\n maxCacheAge: 30,\n backlogDays: 7,\n torrentCheckerFrequency: 60,\n backlogFrequency: 720,\n cacheTrimming: false,\n deleteFailed: false,\n downloadPropers: true,\n useFailedDownloads: false,\n minTorrentCheckerFrequency: 30,\n removeFromClient: false,\n randomizeProviders: false,\n propersSearchDays: 2,\n allowHighPriority: true,\n trackersList: [\n 'udp://tracker.coppersurfer.tk:6969/announce',\n 'udp://tracker.leechers-paradise.org:6969/announce',\n 'udp://tracker.zer0day.to:1337/announce',\n 'udp://tracker.opentrackr.org:1337/announce',\n 'http://tracker.opentrackr.org:1337/announce',\n 'udp://p4p.arenabg.com:1337/announce',\n 'http://p4p.arenabg.com:1337/announce',\n 'udp://explodie.org:6969/announce',\n 'udp://9.rarbg.com:2710/announce',\n 'http://explodie.org:6969/announce',\n 'http://tracker.dler.org:6969/announce',\n 'udp://public.popcorn-tracker.org:6969/announce',\n 'udp://tracker.internetwarriors.net:1337/announce',\n 'udp://ipv4.tracker.harry.lu:80/announce',\n 'http://ipv4.tracker.harry.lu:80/announce',\n 'udp://mgtracker.org:2710/announce',\n 'http://mgtracker.org:6969/announce',\n 'udp://tracker.mg64.net:6969/announce',\n 'http://tracker.mg64.net:6881/announce',\n 'http://torrentsmd.com:8080/announce'\n ]\n }\n};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'search') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import {\n SOCKET_ONOPEN,\n SOCKET_ONCLOSE,\n SOCKET_ONERROR,\n SOCKET_ONMESSAGE,\n SOCKET_RECONNECT,\n SOCKET_RECONNECT_ERROR\n} from '../mutation-types';\n\nconst state = {\n isConnected: false,\n // Current message\n message: {},\n // Delivered messages for this session\n messages: [],\n reconnectError: false\n};\n\nconst mutations = {\n [SOCKET_ONOPEN](state) {\n state.isConnected = true;\n },\n [SOCKET_ONCLOSE](state) {\n state.isConnected = false;\n },\n [SOCKET_ONERROR](state, event) {\n console.error(state, event);\n },\n // Default handler called for all websocket methods\n [SOCKET_ONMESSAGE](state, message) {\n const { data, event } = message;\n\n // Set the current message\n state.message = message;\n\n if (event === 'notification') {\n // Save it so we can look it up later\n const existingMessage = state.messages.filter(message => message.hash === data.hash);\n if (existingMessage.length === 1) {\n state.messages[state.messages.indexOf(existingMessage)] = message;\n } else {\n state.messages.push(message);\n }\n }\n },\n // Mutations for websocket reconnect methods\n [SOCKET_RECONNECT](state, count) {\n console.info(state, count);\n },\n [SOCKET_RECONNECT_ERROR](state) {\n state.reconnectError = true;\n\n const title = 'Error connecting to websocket';\n let error = '';\n error += 'Please check your network connection. ';\n error += 'If you are using a reverse proxy, please take a look at our wiki for config examples.';\n\n window.displayNotification('notice', title, error);\n }\n};\n\nconst getters = {};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import { ADD_CONFIG } from '../mutation-types';\n\nconst state = {\n values: {},\n strings: {}\n};\n\nconst mutations = {\n [ADD_CONFIG](state, { section, config }) {\n if (section === 'statuses') {\n state = Object.assign(state, config);\n }\n }\n};\n\nconst getters = {};\n\nconst actions = {};\n\nexport default {\n state,\n mutations,\n getters,\n actions\n};\n","import Vue from 'vue';\nimport Vuex from 'vuex';\nimport VueNativeSock from 'vue-native-websocket';\nimport {\n auth,\n clients,\n config,\n defaults,\n metadata,\n notifications,\n notifiers,\n qualities,\n search,\n shows,\n socket,\n statuses\n} from './modules';\nimport {\n SOCKET_ONOPEN,\n SOCKET_ONCLOSE,\n SOCKET_ONERROR,\n SOCKET_ONMESSAGE,\n SOCKET_RECONNECT,\n SOCKET_RECONNECT_ERROR\n} from './mutation-types';\n\nconst { Store } = Vuex;\n\nVue.use(Vuex);\n\nconst store = new Store({\n modules: {\n auth,\n clients,\n config,\n defaults,\n metadata,\n notifications,\n notifiers,\n qualities,\n search,\n shows,\n socket,\n statuses\n },\n state: {},\n mutations: {},\n getters: {},\n actions: {}\n});\n\n// Keep as a non-arrow function for `this` context.\nconst passToStoreHandler = function(eventName, event, next) {\n const target = eventName.toUpperCase();\n const eventData = event.data;\n\n if (target === 'SOCKET_ONMESSAGE') {\n const message = JSON.parse(eventData);\n const { data, event } = message;\n\n // Show the notification to the user\n if (event === 'notification') {\n const { body, hash, type, title } = data;\n window.displayNotification(type, title, body, hash);\n } else if (event === 'configUpdated') {\n const { section, config } = data;\n this.store.dispatch('updateConfig', { section, config });\n } else {\n window.displayNotification('info', event, data);\n }\n }\n\n // Resume normal 'passToStore' handling\n next(eventName, event);\n};\n\nconst websocketUrl = (() => {\n const { protocol, host } = window.location;\n const proto = protocol === 'https:' ? 'wss:' : 'ws:';\n const WSMessageUrl = '/ui';\n const webRoot = document.body.getAttribute('web-root');\n return `${proto}//${host}${webRoot}/ws${WSMessageUrl}`;\n})();\n\nVue.use(VueNativeSock, websocketUrl, {\n store,\n format: 'json',\n reconnection: true, // (Boolean) whether to reconnect automatically (false)\n reconnectionAttempts: 2, // (Number) number of reconnection attempts before giving up (Infinity),\n reconnectionDelay: 1000, // (Number) how long to initially wait before attempting a new (1000)\n passToStoreHandler, // (Function|) Handler for events triggered by the WebSocket (false)\n mutations: {\n SOCKET_ONOPEN,\n SOCKET_ONCLOSE,\n SOCKET_ONERROR,\n SOCKET_ONMESSAGE,\n SOCKET_RECONNECT,\n SOCKET_RECONNECT_ERROR\n }\n});\n\nexport default store;\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('iframe',{staticClass:\"irc-frame loading-spinner\",attrs:{\"src\":_vm.frameSrc}})}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n\n\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./irc.vue?vue&type=template&id=60f89f30&scoped=true&\"\nimport script from \"./irc.vue?vue&type=script&lang=js&\"\nexport * from \"./irc.vue?vue&type=script&lang=js&\"\nimport style0 from \"./irc.vue?vue&type=style&index=0&id=60f89f30&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"60f89f30\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"addShowPortal\"}},[_c('app-link',{staticClass:\"btn-medusa btn-large\",attrs:{\"href\":\"addShows/trendingShows/?traktList=anticipated\",\"id\":\"btnNewShow\"}},[_c('div',{staticClass:\"button\"},[_c('div',{staticClass:\"add-list-icon-addtrakt\"})]),_vm._v(\" \"),_c('div',{staticClass:\"buttontext\"},[_c('h3',[_vm._v(\"Add From Trakt Lists\")]),_vm._v(\" \"),_c('p',[_vm._v(\"For shows that you haven't downloaded yet, this option lets you choose from a show from one of the Trakt lists to add to Medusa .\")])])]),_vm._v(\" \"),_c('app-link',{staticClass:\"btn-medusa btn-large\",attrs:{\"href\":\"addShows/popularShows/\",\"id\":\"btnNewShow\"}},[_c('div',{staticClass:\"button\"},[_c('div',{staticClass:\"add-list-icon-addimdb\"})]),_vm._v(\" \"),_c('div',{staticClass:\"buttontext\"},[_c('h3',[_vm._v(\"Add From IMDB's Popular Shows\")]),_vm._v(\" \"),_c('p',[_vm._v(\"View IMDB's list of the most popular shows. This feature uses IMDB's MOVIEMeter algorithm to identify popular TV Shows.\")])])]),_vm._v(\" \"),_c('app-link',{staticClass:\"btn-medusa btn-large\",attrs:{\"href\":\"addShows/popularAnime/\",\"id\":\"btnNewShow\"}},[_c('div',{staticClass:\"button\"},[_c('div',{staticClass:\"add-list-icon-addanime\"})]),_vm._v(\" \"),_c('div',{staticClass:\"buttontext\"},[_c('h3',[_vm._v(\"Add From Anidb's Hot Anime list\")]),_vm._v(\" \"),_c('p',[_vm._v(\"View Anidb's list of the most popular anime shows. Anidb provides lists for Popular Anime, using the \\\"Hot Anime\\\" list.\")])])])],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-recommended.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-recommended.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./add-recommended.vue?vue&type=template&id=b4192aae&\"\nimport script from \"./add-recommended.vue?vue&type=script&lang=js&\"\nexport * from \"./add-recommended.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _vm._m(0)}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"login\"},[_c('form',{attrs:{\"action\":\"\",\"method\":\"post\"}},[_c('h1',[_vm._v(\"Medusa\")]),_vm._v(\" \"),_c('div',{staticClass:\"ctrlHolder\"},[_c('input',{staticClass:\"inlay\",attrs:{\"name\":\"username\",\"type\":\"text\",\"placeholder\":\"Username\",\"autocomplete\":\"off\"}})]),_vm._v(\" \"),_c('div',{staticClass:\"ctrlHolder\"},[_c('input',{staticClass:\"inlay\",attrs:{\"name\":\"password\",\"type\":\"password\",\"placeholder\":\"Password\",\"autocomplete\":\"off\"}})]),_vm._v(\" \"),_c('div',{staticClass:\"ctrlHolder\"},[_c('label',{staticClass:\"remember_me\",attrs:{\"title\":\"for 30 days\"}},[_c('input',{staticClass:\"inlay\",attrs:{\"id\":\"remember_me\",\"name\":\"remember_me\",\"type\":\"checkbox\",\"value\":\"1\",\"checked\":\"checked\"}}),_vm._v(\" Remember me\")]),_vm._v(\" \"),_c('input',{staticClass:\"button\",attrs:{\"name\":\"submit\",\"type\":\"submit\",\"value\":\"Login\"}})])])])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./login.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./login.vue?vue&type=script&lang=js&\"","\n\n\n\n\n","import { render, staticRenderFns } from \"./login.vue?vue&type=template&id=1f239a7a&\"\nimport script from \"./login.vue?vue&type=script&lang=js&\"\nexport * from \"./login.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"addShowPortal\"}},[_c('app-link',{staticClass:\"btn-medusa btn-large\",attrs:{\"href\":\"addShows/newShow/\",\"id\":\"btnNewShow\"}},[_c('div',{staticClass:\"button\"},[_c('div',{staticClass:\"add-list-icon-addnewshow\"})]),_vm._v(\" \"),_c('div',{staticClass:\"buttontext\"},[_c('h3',[_vm._v(\"Add New Show\")]),_vm._v(\" \"),_c('p',[_vm._v(\"For shows that you haven't downloaded yet, this option finds a show on your preferred indexer, creates a directory for it's episodes, and adds it to Medusa.\")])])]),_vm._v(\" \"),_c('app-link',{staticClass:\"btn-medusa btn-large\",attrs:{\"href\":\"addShows/existingShows/\",\"id\":\"btnExistingShow\"}},[_c('div',{staticClass:\"button\"},[_c('div',{staticClass:\"add-list-icon-addexistingshow\"})]),_vm._v(\" \"),_c('div',{staticClass:\"buttontext\"},[_c('h3',[_vm._v(\"Add Existing Shows\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Use this option to add shows that already have a folder created on your hard drive. Medusa will scan your existing metadata/episodes and add the show accordingly.\")])])])],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-shows.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./add-shows.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./add-shows.vue?vue&type=template&id=3f2dd7ac&\"\nimport script from \"./add-shows.vue?vue&type=script&lang=js&\"\nexport * from \"./add-shows.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"config-content\"}},[_c('table',{staticClass:\"infoTable\",attrs:{\"cellspacing\":\"1\",\"border\":\"0\",\"cellpadding\":\"0\",\"width\":\"100%\"}},[_c('tr',[_vm._m(0),_vm._v(\" \"),_c('td',[_vm._v(\"\\n Branch:\\n \"),(_vm.config.branch)?_c('span',[_c('app-link',{attrs:{\"href\":_vm.config.sourceUrl + '/tree/' + _vm.config.branch}},[_vm._v(_vm._s(_vm.config.branch))])],1):_c('span',[_vm._v(\"Unknown\")]),_vm._v(\" \"),_c('br'),_vm._v(\"\\n Commit:\\n \"),(_vm.config.commitHash)?_c('span',[_c('app-link',{attrs:{\"href\":_vm.config.sourceUrl + '/commit/' + _vm.config.commitHash}},[_vm._v(_vm._s(_vm.config.commitHash))])],1):_c('span',[_vm._v(\"Unknown\")]),_vm._v(\" \"),_c('br'),_vm._v(\"\\n Version:\\n \"),(_vm.config.release)?_c('span',[_c('app-link',{attrs:{\"href\":_vm.config.sourceUrl + '/releases/tag/' + _vm.config.release}},[_vm._v(_vm._s(_vm.config.release))])],1):_c('span',[_vm._v(\"Unknown\")]),_vm._v(\" \"),_c('br'),_vm._v(\"\\n Database:\\n \"),(_vm.config.databaseVersion)?_c('span',[_vm._v(_vm._s(_vm.config.databaseVersion.major)+\".\"+_vm._s(_vm.config.databaseVersion.minor))]):_c('span',[_vm._v(\"Unknown\")])])]),_vm._v(\" \"),_c('tr',[_vm._m(1),_c('td',[_vm._v(_vm._s(_vm.config.pythonVersion))])]),_vm._v(\" \"),_c('tr',[_vm._m(2),_c('td',[_vm._v(_vm._s(_vm.config.sslVersion))])]),_vm._v(\" \"),_c('tr',[_vm._m(3),_c('td',[_vm._v(_vm._s(_vm.config.os))])]),_vm._v(\" \"),_c('tr',[_vm._m(4),_c('td',[_vm._v(_vm._s(_vm.config.locale))])]),_vm._v(\" \"),_vm._m(5),_vm._v(\" \"),_vm._m(6),_vm._v(\" \"),_c('tr',[_vm._m(7),_c('td',[_vm._v(_vm._s(_vm.config.localUser))])]),_vm._v(\" \"),_c('tr',[_vm._m(8),_c('td',[_vm._v(_vm._s(_vm.config.programDir))])]),_vm._v(\" \"),_c('tr',[_vm._m(9),_c('td',[_vm._v(_vm._s(_vm.config.configFile))])]),_vm._v(\" \"),_c('tr',[_vm._m(10),_c('td',[_vm._v(_vm._s(_vm.config.dbPath))])]),_vm._v(\" \"),_c('tr',[_vm._m(11),_c('td',[_vm._v(_vm._s(_vm.config.cacheDir))])]),_vm._v(\" \"),_c('tr',[_vm._m(12),_c('td',[_vm._v(_vm._s(_vm.config.logDir))])]),_vm._v(\" \"),(_vm.config.appArgs)?_c('tr',[_vm._m(13),_c('td',[_c('pre',[_vm._v(_vm._s(_vm._f(\"prettyPrintJSON\")(_vm.config.appArgs)))])])]):_vm._e(),_vm._v(\" \"),(_vm.config.webRoot)?_c('tr',[_vm._m(14),_c('td',[_vm._v(_vm._s(_vm.config.webRoot))])]):_vm._e(),_vm._v(\" \"),(_vm.config.runsInDocker)?_c('tr',[_vm._m(15),_c('td',[_vm._v(_vm._s(_vm.config.runsInDocker ? 'yes' : 'no'))])]):_vm._e(),_vm._v(\" \"),_vm._m(16),_vm._v(\" \"),_vm._m(17),_vm._v(\" \"),_c('tr',[_vm._m(18),_c('td',[_c('app-link',{attrs:{\"href\":_vm.config.githubUrl}},[_vm._v(_vm._s(_vm.config.githubUrl))])],1)]),_vm._v(\" \"),_c('tr',[_vm._m(19),_c('td',[_c('app-link',{attrs:{\"href\":_vm.config.wikiUrl}},[_vm._v(_vm._s(_vm.config.wikiUrl))])],1)]),_vm._v(\" \"),_c('tr',[_vm._m(20),_c('td',[_c('app-link',{attrs:{\"href\":_vm.config.sourceUrl}},[_vm._v(_vm._s(_vm.config.sourceUrl))])],1)]),_vm._v(\" \"),_c('tr',[_vm._m(21),_c('td',[_c('app-link',{attrs:{\"href\":\"irc://irc.freenode.net/#pymedusa\"}},[_c('i',[_vm._v(\"#pymedusa\")]),_vm._v(\" on \"),_c('i',[_vm._v(\"irc.freenode.net\")])])],1)])])])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-application\"}),_vm._v(\" Medusa Info:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-python\"}),_vm._v(\" Python Version:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-ssl\"}),_vm._v(\" SSL Version:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-os\"}),_vm._v(\" OS:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-locale\"}),_vm._v(\" Locale:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_c('td',[_vm._v(\" \")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"infoTableSeperator\"},[_c('td',[_vm._v(\" \")]),_c('td',[_vm._v(\" \")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-user\"}),_vm._v(\" User:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-dir\"}),_vm._v(\" Program Folder:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-config\"}),_vm._v(\" Config File:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-db\"}),_vm._v(\" Database File:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-cache\"}),_vm._v(\" Cache Folder:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-log\"}),_vm._v(\" Log Folder:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-arguments\"}),_vm._v(\" Arguments:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-dir\"}),_vm._v(\" Web Root:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-docker\"}),_vm._v(\" Runs in docker:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',[_c('td',[_vm._v(\" \")]),_c('td',[_vm._v(\" \")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('tr',{staticClass:\"infoTableSeperator\"},[_c('td',[_vm._v(\" \")]),_c('td',[_vm._v(\" \")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-web\"}),_vm._v(\" Website:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-wiki\"}),_vm._v(\" Wiki:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-github\"}),_vm._v(\" Source:\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('td',[_c('i',{staticClass:\"icon16-config-mirc\"}),_vm._v(\" IRC Chat:\")])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./config.vue?vue&type=template&id=2ad9ae57&\"\nimport script from \"./config.vue?vue&type=script&lang=js&\"\nexport * from \"./config.vue?vue&type=script&lang=js&\"\nimport style0 from \"./config.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"align-center\"},[_vm._v(\"You have reached this page by accident, please check the url.\")])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./404.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./404.vue?vue&type=script&lang=js&\"","\n\n\n","import { render, staticRenderFns } from \"./404.vue?vue&type=template&id=3cfbf450&\"\nimport script from \"./404.vue?vue&type=script&lang=js&\"\nexport * from \"./404.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"config\"}},[_c('div',{attrs:{\"id\":\"config-content\"}},[_c('form',{staticClass:\"form-horizontal\",attrs:{\"id\":\"configForm\"},on:{\"submit\":function($event){$event.preventDefault();return _vm.save()}}},[_c('div',{attrs:{\"id\":\"config-components\"}},[_c('ul',[_c('li',[_c('app-link',{attrs:{\"href\":\"#post-processing\"}},[_vm._v(\"Post Processing\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"#episode-naming\"}},[_vm._v(\"Episode Naming\")])],1),_vm._v(\" \"),_c('li',[_c('app-link',{attrs:{\"href\":\"#metadata\"}},[_vm._v(\"Metadata\")])],1)]),_vm._v(\" \"),_c('div',{attrs:{\"id\":\"post-processing\"}},[_c('div',{staticClass:\"row component-group\"},[_vm._m(0),_vm._v(\" \"),_c('div',{staticClass:\"col-xs-12 col-md-10\"},[_c('fieldset',{staticClass:\"component-group-list\"},[_c('div',{staticClass:\"form-group\"},[_vm._m(1),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"process_automatically\",\"name\":\"process_automatically\",\"sync\":\"\"},model:{value:(_vm.postProcessing.processAutomatically),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"processAutomatically\", $$v)},expression:\"postProcessing.processAutomatically\"}}),_vm._v(\" \"),_vm._m(2),_vm._v(\" \"),_vm._m(3)],1)]),_vm._v(\" \"),_c('div',{directives:[{name:\"show\",rawName:\"v-show\",value:(_vm.postProcessing.processAutomatically),expression:\"postProcessing.processAutomatically\"}],attrs:{\"id\":\"post-process-toggle-wrapper\"}},[_c('div',{staticClass:\"form-group\"},[_vm._m(4),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('file-browser',{attrs:{\"id\":\"tv_download_dir\",\"name\":\"tv_download_dir\",\"title\":\"Select series download location\",\"initial-dir\":_vm.postProcessing.showDownloadDir},on:{\"update\":function($event){_vm.postProcessing.showDownloadDir = $event}}}),_vm._v(\" \"),_c('span',{staticClass:\"clear-left\"},[_vm._v(\"The folder where your download client puts the completed TV downloads.\")]),_vm._v(\" \"),_vm._m(5)],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(6),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.postProcessing.processMethod),expression:\"postProcessing.processMethod\"}],staticClass:\"form-control input-sm\",attrs:{\"id\":\"naming_multi_ep\",\"name\":\"naming_multi_ep\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.$set(_vm.postProcessing, \"processMethod\", $event.target.multiple ? $$selectedVal : $$selectedVal[0])}}},_vm._l((_vm.processMethods),function(option){return _c('option',{key:option.value,domProps:{\"value\":option.value}},[_vm._v(_vm._s(option.text))])}),0),_vm._v(\" \"),_c('span',[_vm._v(\"What method should be used to put files into the library?\")]),_vm._v(\" \"),_vm._m(7),_vm._v(\" \"),(_vm.postProcessing.processMethod == 'reflink')?_c('p',[_vm._v(\"To use reference linking, the \"),_c('app-link',{attrs:{\"href\":\"http://www.dereferer.org/?https://pypi.python.org/pypi/reflink/0.1.4\"}},[_vm._v(\"reflink package\")]),_vm._v(\" needs to be installed.\")],1):_vm._e()])]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(8),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model.number\",value:(_vm.postProcessing.autoPostprocessorFrequency),expression:\"postProcessing.autoPostprocessorFrequency\",modifiers:{\"number\":true}}],staticClass:\"form-control input-sm input75\",attrs:{\"type\":\"number\",\"min\":\"10\",\"step\":\"1\",\"name\":\"autopostprocessor_frequency\",\"id\":\"autopostprocessor_frequency\"},domProps:{\"value\":(_vm.postProcessing.autoPostprocessorFrequency)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.$set(_vm.postProcessing, \"autoPostprocessorFrequency\", _vm._n($event.target.value))},\"blur\":function($event){return _vm.$forceUpdate()}}}),_vm._v(\" \"),_c('span',[_vm._v(\"Time in minutes to check for new files to auto post-process (min 10)\")])])])])])])]),_vm._v(\" \"),_c('div',{staticClass:\"row component-group\"},[_vm._m(9),_vm._v(\" \"),_c('div',{staticClass:\"col-xs-12 col-md-10\"},[_c('fieldset',{staticClass:\"component-group-list\"},[_c('div',{staticClass:\"form-group\"},[_vm._m(10),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"postpone_if_sync_files\",\"name\":\"postpone_if_sync_files\",\"sync\":\"\"},model:{value:(_vm.postProcessing.postponeIfSyncFiles),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"postponeIfSyncFiles\", $$v)},expression:\"postProcessing.postponeIfSyncFiles\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Wait to process a folder if sync files are present.\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(11),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select-list',{attrs:{\"name\":\"sync_files\",\"id\":\"sync_files\",\"csv-enabled\":\"\",\"list-items\":_vm.postProcessing.syncFiles},on:{\"change\":_vm.onChangeSyncFiles}}),_vm._v(\" \"),_c('span',[_vm._v(\"comma seperated list of extensions or filename globs Medusa ignores when Post Processing\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(12),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"postpone_if_no_subs\",\"name\":\"postpone_if_no_subs\",\"sync\":\"\"},model:{value:(_vm.postProcessing.postponeIfNoSubs),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"postponeIfNoSubs\", $$v)},expression:\"postProcessing.postponeIfNoSubs\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Wait to process a file until subtitles are present\")]),_c('br'),_vm._v(\" \"),_c('span',[_vm._v(\"Language names are allowed in subtitle filename (en.srt, pt-br.srt, ita.srt, etc.)\")]),_c('br'),_vm._v(\" \"),_vm._m(13),_c('br'),_vm._v(\" \"),_c('span',[_vm._v(\"If you have any active show with subtitle search disabled, you must enable Automatic post processor.\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(14),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"rename_episodes\",\"name\":\"rename_episodes\",\"sync\":\"\"},model:{value:(_vm.postProcessing.renameEpisodes),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"renameEpisodes\", $$v)},expression:\"postProcessing.renameEpisodes\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Rename episode using the Episode Naming settings?\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(15),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"create_missing_show_dirs\",\"name\":\"create_missing_show_dirs\",\"sync\":\"\"},model:{value:(_vm.postProcessing.createMissingShowDirs),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"createMissingShowDirs\", $$v)},expression:\"postProcessing.createMissingShowDirs\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Create missing show directories when they get deleted\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(16),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"add_shows_wo_dir\",\"name\":\"add_shows_wo_dir\",\"sync\":\"\"},model:{value:(_vm.postProcessing.addShowsWithoutDir),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"addShowsWithoutDir\", $$v)},expression:\"postProcessing.addShowsWithoutDir\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Add shows without creating a directory (not recommended)\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(17),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"move_associated_files\",\"name\":\"move_associated_files\",\"sync\":\"\"},model:{value:(_vm.postProcessing.moveAssociatedFiles),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"moveAssociatedFiles\", $$v)},expression:\"postProcessing.moveAssociatedFiles\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Delete srt/srr/sfv/etc files while post processing?\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(18),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select-list',{attrs:{\"name\":\"allowed_extensions\",\"id\":\"allowed_extensions\",\"csv-enabled\":\"\",\"list-items\":_vm.postProcessing.allowedExtensions},on:{\"change\":_vm.onChangeAllowedExtensions}}),_vm._v(\" \"),_c('span',[_vm._v(\"Comma seperated list of associated file extensions Medusa should keep while post processing.\")]),_c('br'),_vm._v(\" \"),_c('span',[_vm._v(\"Leaving it empty means all associated files will be deleted\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(19),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"nfo_rename\",\"name\":\"nfo_rename\",\"sync\":\"\"},model:{value:(_vm.postProcessing.nfoRename),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"nfoRename\", $$v)},expression:\"postProcessing.nfoRename\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Rename the original .nfo file to .nfo-orig to avoid conflicts?\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(20),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"airdate_episodes\",\"name\":\"airdate_episodes\",\"sync\":\"\"},model:{value:(_vm.postProcessing.airdateEpisodes),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"airdateEpisodes\", $$v)},expression:\"postProcessing.airdateEpisodes\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Set last modified filedate to the date that the episode aired?\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(21),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.postProcessing.fileTimestampTimezone),expression:\"postProcessing.fileTimestampTimezone\"}],staticClass:\"form-control input-sm\",attrs:{\"id\":\"file_timestamp_timezone\",\"name\":\"file_timestamp_timezone\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.$set(_vm.postProcessing, \"fileTimestampTimezone\", $event.target.multiple ? $$selectedVal : $$selectedVal[0])}}},_vm._l((_vm.timezoneOptions),function(option){return _c('option',{key:option.value,domProps:{\"value\":option.value}},[_vm._v(_vm._s(option.text))])}),0),_vm._v(\" \"),_c('span',[_vm._v(\"What timezone should be used to change File Date?\")])])]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(22),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"unpack\",\"name\":\"unpack\",\"sync\":\"\"},model:{value:(_vm.postProcessing.unpack),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"unpack\", $$v)},expression:\"postProcessing.unpack\"}}),_vm._v(\" \"),_vm._m(23),_c('br'),_vm._v(\" \"),_vm._m(24)],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(25),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"del_rar_contents\",\"name\":\"del_rar_contents\",\"sync\":\"\"},model:{value:(_vm.postProcessing.deleteRarContent),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"deleteRarContent\", $$v)},expression:\"postProcessing.deleteRarContent\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Delete content of RAR files, even if Process Method not set to move?\")])],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(26),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"no_delete\",\"name\":\"no_delete\",\"sync\":\"\"},model:{value:(_vm.postProcessing.noDelete),callback:function ($$v) {_vm.$set(_vm.postProcessing, \"noDelete\", $$v)},expression:\"postProcessing.noDelete\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Leave empty folders when Post Processing?\")]),_c('br'),_vm._v(\" \"),_vm._m(27)],1)]),_vm._v(\" \"),_c('div',{staticClass:\"form-group\"},[_vm._m(28),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select-list',{attrs:{\"name\":\"extra_scripts\",\"id\":\"extra_scripts\",\"csv-enabled\":\"\",\"list-items\":_vm.postProcessing.extraScripts},on:{\"change\":_vm.onChangeExtraScripts}}),_vm._v(\" \"),_c('span',[_vm._v(\"See \"),_c('app-link',{staticClass:\"wikie\",attrs:{\"href\":_vm.postProcessing.extraScriptsUrl}},[_c('strong',[_vm._v(\"Wiki\")])]),_vm._v(\" for script arguments description and usage.\")],1)],1)])]),_vm._v(\" \"),_c('input',{staticClass:\"btn-medusa config_submitter\",attrs:{\"type\":\"submit\",\"value\":\"Save Changes\"}})])])]),_vm._v(\" \"),_c('div',{attrs:{\"id\":\"episode-naming\"}},[_c('div',{staticClass:\"row component-group\"},[_vm._m(29),_vm._v(\" \"),_c('div',{staticClass:\"col-xs-12 col-md-10\"},[_c('fieldset',{staticClass:\"component-group-list\"},[_c('name-pattern',{staticClass:\"component-item\",attrs:{\"naming-pattern\":_vm.postProcessing.naming.pattern,\"naming-presets\":_vm.presets,\"multi-ep-style\":_vm.postProcessing.naming.multiEp,\"multi-ep-styles\":_vm.multiEpStringsSelect,\"flag-loaded\":_vm.configLoaded},on:{\"change\":_vm.saveNaming}}),_vm._v(\" \"),_c('name-pattern',{staticClass:\"component-item\",attrs:{\"enabled\":_vm.postProcessing.naming.enableCustomNamingSports,\"naming-pattern\":_vm.postProcessing.naming.patternSports,\"naming-presets\":_vm.presets,\"type\":\"sports\",\"enabled-naming-custom\":_vm.postProcessing.naming.enableCustomNamingSports,\"flag-loaded\":_vm.configLoaded},on:{\"change\":_vm.saveNamingSports}}),_vm._v(\" \"),_c('name-pattern',{staticClass:\"component-item\",attrs:{\"enabled\":_vm.postProcessing.naming.enableCustomNamingAirByDate,\"naming-pattern\":_vm.postProcessing.naming.patternAirByDate,\"naming-presets\":_vm.presets,\"type\":\"airs by date\",\"enabled-naming-custom\":_vm.postProcessing.naming.enableCustomNamingAirByDate,\"flag-loaded\":_vm.configLoaded},on:{\"change\":_vm.saveNamingAbd}}),_vm._v(\" \"),_c('name-pattern',{staticClass:\"component-item\",attrs:{\"enabled\":_vm.postProcessing.naming.enableCustomNamingAnime,\"naming-pattern\":_vm.postProcessing.naming.patternAnime,\"naming-presets\":_vm.presets,\"type\":\"anime\",\"multi-ep-style\":_vm.postProcessing.naming.animeMultiEp,\"multi-ep-styles\":_vm.multiEpStringsSelect,\"anime-naming-type\":_vm.postProcessing.naming.animeNamingType,\"enabled-naming-custom\":_vm.postProcessing.naming.enableCustomNamingAnime,\"flag-loaded\":_vm.configLoaded},on:{\"change\":_vm.saveNamingAnime}}),_vm._v(\" \"),_c('div',{staticClass:\"form-group component-item\"},[_vm._m(30),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('toggle-button',{attrs:{\"width\":45,\"height\":22,\"id\":\"naming_strip_year\",\"name\":\"naming_strip_year\",\"sync\":\"\"},model:{value:(_vm.postProcessing.naming.stripYear),callback:function ($$v) {_vm.$set(_vm.postProcessing.naming, \"stripYear\", $$v)},expression:\"postProcessing.naming.stripYear\"}}),_vm._v(\" \"),_c('span',[_vm._v(\"Remove the TV show's year when renaming the file?\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Only applies to shows that have year inside parentheses\")])],1)])],1)])])]),_vm._v(\" \"),_c('div',{attrs:{\"id\":\"metadata\"}},[_c('div',{staticClass:\"row component-group\"},[_vm._m(31),_vm._v(\" \"),_c('div',{staticClass:\"col-xs-12 col-md-10\"},[_c('fieldset',{staticClass:\"component-group-list\"},[_c('div',{staticClass:\"form-group\"},[_vm._m(32),_vm._v(\" \"),_c('div',{staticClass:\"col-sm-10 content\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.metadataProviderSelected),expression:\"metadataProviderSelected\"}],staticClass:\"form-control input-sm\",attrs:{\"id\":\"metadataType\",\"name\":\"metadataType\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.metadataProviderSelected=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},_vm._l((_vm.metadataProviders),function(option){return _c('option',{key:option.id,domProps:{\"value\":option.id}},[_vm._v(_vm._s(option.name))])}),0),_vm._v(\" \"),_vm._m(33)])]),_vm._v(\" \"),_vm._l((_vm.metadataProviders),function(provider){return _c('div',{directives:[{name:\"show\",rawName:\"v-show\",value:(provider.id === _vm.metadataProviderSelected),expression:\"provider.id === metadataProviderSelected\"}],key:provider.id,staticClass:\"metadataDiv\",attrs:{\"id\":\"provider.id\"}},[_c('div',{staticClass:\"metadata_options_wrapper\"},[_c('h4',[_vm._v(\"Create:\")]),_vm._v(\" \"),_c('div',{staticClass:\"metadata_options\"},[_c('label',{attrs:{\"for\":provider.id + '_show_metadata'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.showMetadata),expression:\"provider.showMetadata\"}],staticClass:\"metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_show_metadata'},domProps:{\"checked\":Array.isArray(provider.showMetadata)?_vm._i(provider.showMetadata,null)>-1:(provider.showMetadata)},on:{\"change\":function($event){var $$a=provider.showMetadata,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"showMetadata\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"showMetadata\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"showMetadata\", $$c)}}}}),_vm._v(\" Show Metadata\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_episode_metadata'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.episodeMetadata),expression:\"provider.episodeMetadata\"}],staticClass:\"metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_episode_metadata',\"disabled\":provider.example.episodeMetadata.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.episodeMetadata)?_vm._i(provider.episodeMetadata,null)>-1:(provider.episodeMetadata)},on:{\"change\":function($event){var $$a=provider.episodeMetadata,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"episodeMetadata\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"episodeMetadata\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"episodeMetadata\", $$c)}}}}),_vm._v(\" Episode Metadata\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_fanart'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.fanart),expression:\"provider.fanart\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_fanart',\"disabled\":provider.example.fanart.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.fanart)?_vm._i(provider.fanart,null)>-1:(provider.fanart)},on:{\"change\":function($event){var $$a=provider.fanart,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"fanart\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"fanart\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"fanart\", $$c)}}}}),_vm._v(\" Show Fanart\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_poster'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.poster),expression:\"provider.poster\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_poster',\"disabled\":provider.example.poster.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.poster)?_vm._i(provider.poster,null)>-1:(provider.poster)},on:{\"change\":function($event){var $$a=provider.poster,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"poster\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"poster\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"poster\", $$c)}}}}),_vm._v(\" Show Poster\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_banner'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.banner),expression:\"provider.banner\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_banner',\"disabled\":provider.example.banner.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.banner)?_vm._i(provider.banner,null)>-1:(provider.banner)},on:{\"change\":function($event){var $$a=provider.banner,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"banner\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"banner\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"banner\", $$c)}}}}),_vm._v(\" Show Banner\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_episode_thumbnails'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.episodeThumbnails),expression:\"provider.episodeThumbnails\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_episode_thumbnails',\"disabled\":provider.example.episodeThumbnails.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.episodeThumbnails)?_vm._i(provider.episodeThumbnails,null)>-1:(provider.episodeThumbnails)},on:{\"change\":function($event){var $$a=provider.episodeThumbnails,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"episodeThumbnails\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"episodeThumbnails\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"episodeThumbnails\", $$c)}}}}),_vm._v(\" Episode Thumbnails\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_posters'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.seasonPosters),expression:\"provider.seasonPosters\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_season_posters',\"disabled\":provider.example.seasonPosters.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.seasonPosters)?_vm._i(provider.seasonPosters,null)>-1:(provider.seasonPosters)},on:{\"change\":function($event){var $$a=provider.seasonPosters,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"seasonPosters\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"seasonPosters\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"seasonPosters\", $$c)}}}}),_vm._v(\" Season Posters\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_banners'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.seasonBanners),expression:\"provider.seasonBanners\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_season_banners',\"disabled\":provider.example.seasonBanners.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.seasonBanners)?_vm._i(provider.seasonBanners,null)>-1:(provider.seasonBanners)},on:{\"change\":function($event){var $$a=provider.seasonBanners,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"seasonBanners\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"seasonBanners\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"seasonBanners\", $$c)}}}}),_vm._v(\" Season Banners\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_all_poster'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.seasonAllPoster),expression:\"provider.seasonAllPoster\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_season_all_poster',\"disabled\":provider.example.seasonAllPoster.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.seasonAllPoster)?_vm._i(provider.seasonAllPoster,null)>-1:(provider.seasonAllPoster)},on:{\"change\":function($event){var $$a=provider.seasonAllPoster,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"seasonAllPoster\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"seasonAllPoster\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"seasonAllPoster\", $$c)}}}}),_vm._v(\" Season All Poster\")]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_all_banner'}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(provider.seasonAllBanner),expression:\"provider.seasonAllBanner\"}],staticClass:\"float-left metadata_checkbox\",attrs:{\"type\":\"checkbox\",\"id\":provider.id + '_season_all_banner',\"disabled\":provider.example.seasonAllBanner.includes('not supported')},domProps:{\"checked\":Array.isArray(provider.seasonAllBanner)?_vm._i(provider.seasonAllBanner,null)>-1:(provider.seasonAllBanner)},on:{\"change\":function($event){var $$a=provider.seasonAllBanner,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.$set(provider, \"seasonAllBanner\", $$a.concat([$$v])))}else{$$i>-1&&(_vm.$set(provider, \"seasonAllBanner\", $$a.slice(0,$$i).concat($$a.slice($$i+1))))}}else{_vm.$set(provider, \"seasonAllBanner\", $$c)}}}}),_vm._v(\" Season All Banner\")])])]),_vm._v(\" \"),_c('div',{staticClass:\"metadata_example_wrapper\"},[_c('h4',[_vm._v(\"Results:\")]),_vm._v(\" \"),_c('div',{staticClass:\"metadata_example\"},[_c('label',{attrs:{\"for\":provider.id + '_show_metadata'}},[_c('span',{class:{disabled: !provider.showMetadata},attrs:{\"id\":provider.id + '_eg_show_metadata'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.showMetadata + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_episode_metadata'}},[_c('span',{class:{disabled: !provider.episodeMetadata},attrs:{\"id\":provider.id + '_eg_episode_metadata'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.episodeMetadata + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_fanart'}},[_c('span',{class:{disabled: !provider.fanart},attrs:{\"id\":provider.id + '_eg_fanart'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.fanart + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_poster'}},[_c('span',{class:{disabled: !provider.poster},attrs:{\"id\":provider.id + '_eg_poster'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.poster + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_banner'}},[_c('span',{class:{disabled: !provider.banner},attrs:{\"id\":provider.id + '_eg_banner'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.banner + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_episode_thumbnails'}},[_c('span',{class:{disabled: !provider.episodeThumbnails},attrs:{\"id\":provider.id + '_eg_episode_thumbnails'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.episodeThumbnails + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_posters'}},[_c('span',{class:{disabled: !provider.seasonPosters},attrs:{\"id\":provider.id + '_eg_season_posters'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.seasonPosters + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_banners'}},[_c('span',{class:{disabled: !provider.seasonBanners},attrs:{\"id\":provider.id + '_eg_season_banners'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.seasonBanners + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_all_poster'}},[_c('span',{class:{disabled: !provider.seasonAllPoster},attrs:{\"id\":provider.id + '_eg_season_all_poster'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.seasonAllPoster + '')}})])]),_vm._v(\" \"),_c('label',{attrs:{\"for\":provider.id + '_season_all_banner'}},[_c('span',{class:{disabled: !provider.seasonAllBanner},attrs:{\"id\":provider.id + '_eg_season_all_banner'}},[_c('span',{domProps:{\"innerHTML\":_vm._s('' + provider.example.seasonAllBanner + '')}})])])])])])})],2),_vm._v(\" \"),_c('input',{staticClass:\"btn-medusa config_submitter\",attrs:{\"type\":\"submit\",\"value\":\"Save Changes\"}}),_c('br')])])]),_vm._v(\" \"),_c('h6',{staticClass:\"pull-right\"},[_c('b',[_vm._v(\"All non-absolute folder locations are relative to \"),_c('span',{staticClass:\"path\"},[_vm._v(_vm._s(_vm.config.dataDir))])])]),_vm._v(\" \"),_c('input',{staticClass:\"btn-medusa pull-left config_submitter button\",attrs:{\"type\":\"submit\",\"value\":\"Save Changes\"}})])])])])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"component-group-desc col-xs-12 col-md-2\"},[_c('h3',[_vm._v(\"Scheduled Post-Processing\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Settings that dictate how Medusa should process completed downloads.\")]),_vm._v(\" \"),_c('p',[_vm._v(\"The scheduled postprocessor will periodically scan a folder for media to process.\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"process_automatically\"}},[_c('span',[_vm._v(\"Scheduled Postprocessor\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('p',[_vm._v(\"Enable the scheduled post processor to scan and process any files in your \"),_c('i',[_vm._v(\"Post Processing Dir\")]),_vm._v(\"?\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"clear-left\"},[_c('p',[_c('b',[_vm._v(\"NOTE:\")]),_vm._v(\" Do not use if you use an external Post Processing script\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"tv_download_dir\"}},[_c('span',[_vm._v(\"Post Processing Dir\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"clear-left\"},[_c('p',[_c('b',[_vm._v(\"NOTE:\")]),_vm._v(\" Please use seperate downloading and completed folders in your download client if possible.\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"process_method\"}},[_c('span',[_vm._v(\"Processing Method\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('p',[_c('b',[_vm._v(\"NOTE:\")]),_vm._v(\" If you keep seeding torrents after they finish, please avoid the 'move' processing method to prevent errors.\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"autopostprocessor_frequency\"}},[_c('span',[_vm._v(\"Auto Post-Processing Frequency\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"component-group-desc col-xs-12 col-md-2\"},[_c('h3',[_vm._v(\"General Post-Processing\")]),_vm._v(\" \"),_c('p',[_vm._v(\"Generic postprocessing settings that apply both to the scheduled postprocessor as external scripts\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"postpone_if_sync_files\"}},[_c('span',[_vm._v(\"Postpone post processing\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"sync_files\"}},[_c('span',[_vm._v(\"Sync File Extensions\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"postpone_if_no_subs\"}},[_c('span',[_vm._v(\"Postpone if no subtitle\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',[_c('b',[_vm._v(\"NOTE:\")]),_vm._v(\" Automatic post processor should be disabled to avoid files with pending subtitles being processed over and over.\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"rename_episodes\"}},[_c('span',[_vm._v(\"Rename Episodes\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"create_missing_show_dirs\"}},[_c('span',[_vm._v(\"Create missing show directories\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"add_shows_wo_dir\"}},[_c('span',[_vm._v(\"Add shows without directory\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"move_associated_files\"}},[_c('span',[_vm._v(\"Delete associated files\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\"},[_c('span',[_vm._v(\"Keep associated file extensions\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"nfo_rename\"}},[_c('span',[_vm._v(\"Rename .nfo file\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"airdate_episodes\"}},[_c('span',[_vm._v(\"Change File Date\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"file_timestamp_timezone\"}},[_c('span',[_vm._v(\"Timezone for File Date:\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"unpack\"}},[_c('span',[_vm._v(\"Unpack\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',[_vm._v(\"Unpack any TV releases in your \"),_c('i',[_vm._v(\"TV Download Dir\")]),_vm._v(\"?\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',[_c('b',[_vm._v(\"NOTE:\")]),_vm._v(\" Only working with RAR archive\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"del_rar_contents\"}},[_c('span',[_vm._v(\"Delete RAR contents\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"no_delete\"}},[_c('span',[_vm._v(\"Don't delete empty folders\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',[_c('b',[_vm._v(\"NOTE:\")]),_vm._v(\" Can be overridden using manual Post Processing\")])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\"},[_c('span',[_vm._v(\"Extra Scripts\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"component-group-desc col-xs-12 col-md-2\"},[_c('h3',[_vm._v(\"Episode Naming\")]),_vm._v(\" \"),_c('p',[_vm._v(\"How Medusa will name and sort your episodes.\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"naming_strip_year\"}},[_c('span',[_vm._v(\"Strip Show Year\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"component-group-desc col-xs-12 col-md-2\"},[_c('h3',[_vm._v(\"Metadata\")]),_vm._v(\" \"),_c('p',[_vm._v(\"The data associated to the data. These are files associated to a TV show in the form of images and text that, when supported, will enhance the viewing experience.\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"col-sm-2 control-label\",attrs:{\"for\":\"metadataType\"}},[_c('span',[_vm._v(\"Metadata Type\")])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',{staticClass:\"d-block\"},[_vm._v(\"Toggle the metadata options that you wish to be created. \"),_c('b',[_vm._v(\"Multiple targets may be used.\")])])}]\n\nexport { render, staticRenderFns }","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-post-processing.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-post-processing.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./config-post-processing.vue?vue&type=template&id=0b3bbb62&\"\nimport script from \"./config-post-processing.vue?vue&type=script&lang=js&\"\nexport * from \"./config-post-processing.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-link.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n/*\\n@NOTE: This fixes the header blocking elements when using a hash link\\ne.g. displayShow?indexername=tvdb&seriesid=83462#season-5\\n*/\\n[false-link]::before {\\n content: '';\\n display: block;\\n position: absolute;\\n height: 100px;\\n margin-top: -100px;\\n z-index: -100;\\n}\\n.router-link,\\n.router-link-active {\\n cursor: pointer;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox-number.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.form-control {\\n color: rgb(0, 0, 0);\\n}\\n.input75 {\\n width: 75px;\\n margin-top: -4px;\\n}\\n.input250 {\\n width: 250px;\\n margin-top: -4px;\\n}\\n.input350 {\\n width: 350px;\\n margin-top: -4px;\\n}\\n.input450 {\\n width: 450px;\\n margin-top: -4px;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-textbox.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.input75 {\\n width: 75px;\\n margin-top: -4px;\\n}\\n.input250 {\\n width: 250px;\\n margin-top: -4px;\\n}\\n.input350 {\\n width: 350px;\\n margin-top: -4px;\\n}\\n.input450 {\\n width: 450px;\\n margin-top: -4px;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config-toggle-slider.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.input75 {\\n width: 75px;\\n margin-top: -4px;\\n}\\n.input250 {\\n width: 250px;\\n margin-top: -4px;\\n}\\n.input350 {\\n width: 350px;\\n margin-top: -4px;\\n}\\n.input450 {\\n width: 450px;\\n margin-top: -4px;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=style&index=0&id=5a327762&scoped=true&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./file-browser.vue?vue&type=style&index=0&id=5a327762&scoped=true&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\ndiv.file-browser.max-width[data-v-5a327762] {\\n max-width: 450px;\\n}\\ndiv.file-browser .input-group-no-btn[data-v-5a327762] {\\n display: flex;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./plot-info.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.plotInfo {\\n cursor: help;\\n float: right;\\n position: relative;\\n top: 2px;\\n}\\n.plotInfoNone {\\n cursor: help;\\n float: right;\\n position: relative;\\n top: 2px;\\n opacity: 0.4;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=style&index=0&id=b683ee7a&scoped=true&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./quality-pill.vue?vue&type=style&index=0&id=b683ee7a&scoped=true&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.quality[data-v-b683ee7a] {\\n font: 12px/13px \\\"Open Sans\\\", verdana, sans-serif;\\n background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n background-image: -o-linear-gradient(top, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.25));\\n box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), inset 0 -1px 3px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 2px rgba(0, 0, 0, 0.15);\\n text-shadow: 0 1px rgba(0, 0, 0, 0.8);\\n color: rgb(255, 255, 255);\\n display: inline-block;\\n padding: 2px 4px;\\n text-align: center;\\n vertical-align: baseline;\\n border-radius: 4px;\\n white-space: nowrap;\\n}\\n.any-hd[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n /* stylelint-disable declaration-block-no-shorthand-property-overrides */\\n background:\\n repeating-linear-gradient(\\n -45deg,\\n rgb(38, 114, 182),\\n rgb(38, 114, 182) 10px,\\n rgb(91, 153, 13) 10px,\\n rgb(91, 153, 13) 20px\\n );\\n /* stylelint-enable */\\n}\\n.Custom[data-v-b683ee7a] {\\n background-color: rgb(98, 25, 147);\\n}\\n.HD[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n}\\n.HDTV[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n}\\n.HD720p[data-v-b683ee7a] {\\n background-color: rgb(91, 153, 13);\\n}\\n.HD1080p[data-v-b683ee7a] {\\n background-color: rgb(38, 114, 182);\\n}\\n.UHD-4K[data-v-b683ee7a] {\\n background-color: rgb(117, 0, 255);\\n}\\n.UHD-8K[data-v-b683ee7a] {\\n background-color: rgb(65, 0, 119);\\n}\\n.RawHD[data-v-b683ee7a] {\\n background-color: rgb(205, 115, 0);\\n}\\n.RawHDTV[data-v-b683ee7a] {\\n background-color: rgb(205, 115, 0);\\n}\\n.SD[data-v-b683ee7a] {\\n background-color: rgb(190, 38, 37);\\n}\\n.SDTV[data-v-b683ee7a] {\\n background-color: rgb(190, 38, 37);\\n}\\n.SDDVD[data-v-b683ee7a] {\\n background-color: rgb(190, 38, 37);\\n}\\n.Any[data-v-b683ee7a] {\\n background-color: rgb(102, 102, 102);\\n}\\n.Unknown[data-v-b683ee7a] {\\n background-color: rgb(153, 153, 153);\\n}\\n.Proper[data-v-b683ee7a] {\\n background-color: rgb(63, 127, 0);\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./scroll-buttons.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.scroll-wrapper {\\n position: fixed;\\n opacity: 0;\\n visibility: hidden;\\n overflow: hidden;\\n text-align: center;\\n font-size: 20px;\\n z-index: 999;\\n background-color: #777;\\n color: #eee;\\n width: 50px;\\n height: 48px;\\n line-height: 48px;\\n right: 30px;\\n bottom: 30px;\\n padding-top: 2px;\\n border-radius: 10px;\\n -webkit-transition: all 0.5s ease-in-out;\\n -moz-transition: all 0.5s ease-in-out;\\n -ms-transition: all 0.5s ease-in-out;\\n -o-transition: all 0.5s ease-in-out;\\n transition: all 0.5s ease-in-out;\\n}\\n.scroll-wrapper.show {\\n visibility: visible;\\n cursor: pointer;\\n opacity: 1;\\n}\\n.scroll-wrapper.left {\\n position: fixed;\\n right: 150px;\\n}\\n.scroll-wrapper.right {\\n position: fixed;\\n right: 90px;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=style&index=0&id=ac609192&scoped=true&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./select-list.vue?vue&type=style&index=0&id=ac609192&scoped=true&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\ndiv.select-list ul[data-v-ac609192] {\\n padding-left: 0;\\n}\\ndiv.select-list li[data-v-ac609192] {\\n list-style-type: none;\\n display: flex;\\n}\\ndiv.select-list .new-item[data-v-ac609192] {\\n display: flex;\\n}\\ndiv.select-list .new-item-help[data-v-ac609192] {\\n font-weight: bold;\\n padding-top: 5px;\\n}\\ndiv.select-list input[data-v-ac609192],\\ndiv.select-list img[data-v-ac609192] {\\n display: inline-block;\\n box-sizing: border-box;\\n}\\ndiv.select-list.max-width[data-v-ac609192] {\\n max-width: 450px;\\n}\\ndiv.select-list .switch-input[data-v-ac609192] {\\n left: -8px;\\n top: 4px;\\n position: absolute;\\n z-index: 10;\\n opacity: 0.6;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-selector.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\nselect.select-show {\\n display: inline-block;\\n height: 25px;\\n padding: 1px;\\n}\\n.show-selector {\\n height: 31px;\\n display: table-cell;\\n left: 20px;\\n margin-bottom: 5px;\\n}\\n@media (max-width: 767px) and (min-width: 341px) {\\n.select-show-group,\\n .select-show {\\n width: 100%;\\n}\\n}\\n@media (max-width: 340px) {\\n.select-show-group {\\n width: 100%;\\n}\\n}\\n@media (max-width: 767px) {\\n.show-selector {\\n float: left;\\n width: 100%;\\n}\\n.select-show {\\n width: 100%;\\n}\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=style&index=0&id=10f4092b&scoped=true&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./anidb-release-group-ui.vue?vue&type=style&index=0&id=10f4092b&scoped=true&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\ndiv.anidb-release-group-ui-wrapper[data-v-10f4092b] {\\n clear: both;\\n margin-bottom: 20px;\\n}\\ndiv.anidb-release-group-ui-wrapper ul[data-v-10f4092b] {\\n border-style: solid;\\n border-width: thin;\\n padding: 5px 2px 2px 5px;\\n list-style: none;\\n}\\ndiv.anidb-release-group-ui-wrapper li.active[data-v-10f4092b] {\\n background-color: cornflowerblue;\\n}\\ndiv.anidb-release-group-ui-wrapper div.arrow img[data-v-10f4092b] {\\n cursor: pointer;\\n height: 32px;\\n width: 32px;\\n}\\ndiv.anidb-release-group-ui-wrapper img.deleteFromWhitelist[data-v-10f4092b],\\ndiv.anidb-release-group-ui-wrapper img.deleteFromBlacklist[data-v-10f4092b] {\\n float: right;\\n}\\ndiv.anidb-release-group-ui-wrapper #add-new-release-group p > img[data-v-10f4092b] {\\n height: 16px;\\n width: 16px;\\n background-color: rgb(204, 204, 204);\\n}\\ndiv.anidb-release-group-ui-wrapper.placeholder[data-v-10f4092b] {\\n height: 32px;\\n}\\ndiv.anidb-release-group-ui-wrapper.max-width[data-v-10f4092b] {\\n max-width: 960px;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./app-header.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.floating-badge {\\n position: absolute;\\n top: -5px;\\n right: -8px;\\n padding: 0 4px;\\n background-color: #777;\\n border: 2px solid #959595;\\n border-radius: 100px;\\n font-size: 12px;\\n font-weight: bold;\\n text-decoration: none;\\n color: white;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./config.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.infoTable tr td:first-child {\\n vertical-align: top;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=style&index=0&id=60f89f30&scoped=true&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./irc.vue?vue&type=style&index=0&id=60f89f30&scoped=true&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.irc-frame[data-v-60f89f30] {\\n width: 100%;\\n height: 500px;\\n border: 1px #000 solid;\\n}\\n.loading-spinner[data-v-60f89f30] {\\n background-position: center center;\\n background-repeat: no-repeat;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./root-dirs.vue?vue&type=style&index=0&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.root-dirs-selectbox,\\n.root-dirs-selectbox select,\\n.root-dirs-controls {\\n width: 100%;\\n max-width: 430px;\\n}\\n.root-dirs-selectbox {\\n padding: 0 0 5px;\\n}\\n.root-dirs-controls {\\n text-align: center;\\n}\\n\", \"\"]);\n\n","import mod from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-header.vue?vue&type=style&index=0&id=e712fe74&scoped=true&lang=css&\"; export default mod; export * from \"-!../../node_modules/vue-style-loader/index.js!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./show-header.vue?vue&type=style&index=0&id=e712fe74&scoped=true&lang=css&\"","exports = module.exports = require(\"../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n.summaryTable[data-v-e712fe74] {\\n overflow: hidden;\\n}\\n.summaryTable tr td[data-v-e712fe74] {\\n word-break: break-all;\\n}\\n.ver-spacer[data-v-e712fe74] {\\n width: 15px;\\n}\\n#show-specials-and-seasons[data-v-e712fe74] {\\n margin-bottom: 15px;\\n}\\nspan.required[data-v-e712fe74] {\\n color: green;\\n}\\nspan.preferred[data-v-e712fe74] {\\n color: blue;\\n}\\nspan.undesired[data-v-e712fe74] {\\n color: orange;\\n}\\nspan.ignored[data-v-e712fe74] {\\n color: red;\\n}\\ndiv#col-show-summary[data-v-e712fe74] {\\n display: table;\\n}\\n#col-show-summary img.show-image[data-v-e712fe74] {\\n max-width: 180px;\\n}\\n.show-poster-container[data-v-e712fe74] {\\n margin-right: 10px;\\n display: table-cell;\\n width: 180px;\\n}\\n.show-info-container[data-v-e712fe74] {\\n overflow: hidden;\\n display: table-cell;\\n}\\n@media (min-width: 768px) {\\n.display-specials[data-v-e712fe74],\\n .display-seasons[data-v-e712fe74] {\\n top: -60px;\\n}\\n#show-specials-and-seasons[data-v-e712fe74] {\\n bottom: 5px;\\n right: 15px;\\n position: absolute;\\n}\\n}\\n@media (max-width: 767px) {\\n.show-poster-container[data-v-e712fe74] {\\n display: inline-block;\\n width: 100%;\\n margin: 0 auto;\\n border-style: none;\\n}\\n.show-poster-container img[data-v-e712fe74] {\\n display: block;\\n margin: 0 auto;\\n max-width: 280px !important;\\n}\\n.show-info-container[data-v-e712fe74] {\\n display: block;\\n padding-top: 5px;\\n width: 100%;\\n}\\n}\\n@media (max-width: 991px) and (min-width: 768px) {\\n.show-poster-container[data-v-e712fe74] {\\n float: left;\\n display: inline-block;\\n width: 100%;\\n border-style: none;\\n}\\n.show-info-container[data-v-e712fe74] {\\n display: block;\\n width: 100%;\\n}\\n#col-show-summary img.show-image[data-v-e712fe74] {\\n max-width: 280px;\\n}\\n}\\n\", \"\"]);\n\n"],"sourceRoot":""} \ No newline at end of file diff --git a/themes/light/assets/js/notifications.js b/themes/light/assets/js/notifications.js index 4cfbe7a356..4fd70fe910 100644 --- a/themes/light/assets/js/notifications.js +++ b/themes/light/assets/js/notifications.js @@ -19,9 +19,9 @@ window.displayNotification = (type, title, message, id) => { desktop: { tag: id }, - text: String(message).replace(/]*)?>/ig, '\n') // eslint-disable-line unicorn/no-unsafe-regex - .replace(/<[/]?b(?:\s[^>]*)?>/ig, '*') // eslint-disable-line unicorn/no-unsafe-regex - .replace(/]*)?>/ig, '[').replace(/<[/]i>/ig, ']') // eslint-disable-line unicorn/no-unsafe-regex - .replace(/<(?:[/]?ul|\/li)(?:\s[^>]*)?>/ig, '').replace(/]*)?>/ig, '\n* ') // eslint-disable-line unicorn/no-unsafe-regex + text: String(message).replace(/]*)?>/ig, '\n') + .replace(/<[/]?b(?:\s[^>]*)?>/ig, '*') + .replace(/]*)?>/ig, '[').replace(/<[/]i>/ig, ']') + .replace(/<(?:[/]?ul|\/li)(?:\s[^>]*)?>/ig, '').replace(/]*)?>/ig, '\n* ') }); }; diff --git a/themes/light/assets/js/parsers.js b/themes/light/assets/js/parsers.js index 62d90ecfbe..c261159244 100644 --- a/themes/light/assets/js/parsers.js +++ b/themes/light/assets/js/parsers.js @@ -7,7 +7,7 @@ $.tablesorter.addParser({ if (s.indexOf('Loading...') === 0) { return s.replace('Loading...', '000'); } - return (MEDUSA.config.sortArticle ? (s || '') : (s || '').replace(/^(The|A|An)\s/i, '')); // eslint-disable-line no-undef + return (MEDUSA.config.sortArticle ? (s || '') : (s || '').replace(/^(The|A|An)\s/i, '')); }, type: 'text' }); diff --git a/themes/light/assets/js/trending-shows.js b/themes/light/assets/js/trending-shows.js index 21d4cdae8a..bf40428607 100644 --- a/themes/light/assets/js/trending-shows.js +++ b/themes/light/assets/js/trending-shows.js @@ -12,7 +12,7 @@ $(document).ready(() => { getSortData: { name(itemElem) { const name = $(itemElem).attr('data-name') || ''; - return (MEDUSA.config.sortArticle ? name : name.replace(/^(The|A|An)\s/i, '')).toLowerCase(); // eslint-disable-line no-undef + return (MEDUSA.config.sortArticle ? name : name.replace(/^(The|A|An)\s/i, '')).toLowerCase(); }, rating: '[data-rating] parseInt', votes: '[data-votes] parseInt' diff --git a/themes/light/assets/js/vendors.js b/themes/light/assets/js/vendors.js index 58006ece9a..19d090ed5a 100644 --- a/themes/light/assets/js/vendors.js +++ b/themes/light/assets/js/vendors.js @@ -1,4 +1,10 @@ -!function(t){function e(e){for(var r,a,s=e[0],c=e[1],l=e[2],f=0,d=[];f-1&&t.splice(n,1)}}function f(e,t){e._actions=Object.create(null),e._mutations=Object.create(null),e._wrappedGetters=Object.create(null),e._modulesNamespaceMap=Object.create(null);var n=e.state;m(e,n,[],e._modules.root,!0),p(e,n,t)}function p(e,t,n){var i=e._vm;e.getters={};var o=e._wrappedGetters,a={};r(o,function(t,n){a[n]=function(){return t(e)},Object.defineProperty(e.getters,n,{get:function(){return e._vm[n]},enumerable:!0})});var s=l.config.silent;l.config.silent=!0,e._vm=new l({data:{$$state:t},computed:a}),l.config.silent=s,e.strict&&function(e){e._vm.$watch(function(){return this._data.$$state},function(){0},{deep:!0,sync:!0})}(e),i&&(n&&e._withCommit(function(){i._data.$$state=null}),l.nextTick(function(){return i.$destroy()}))}function m(e,t,n,i,r){var o=!n.length,a=e._modules.getNamespace(n);if(i.namespaced&&(e._modulesNamespaceMap[a]=i),!o&&!r){var s=h(t,n.slice(0,-1)),u=n[n.length-1];e._withCommit(function(){l.set(s,u,i.state)})}var c=i.context=function(e,t,n){var i=""===t,r={dispatch:i?e.dispatch:function(n,i,r){var o=g(n,i,r),a=o.payload,s=o.options,l=o.type;return s&&s.root||(l=t+l),e.dispatch(l,a)},commit:i?e.commit:function(n,i,r){var o=g(n,i,r),a=o.payload,s=o.options,l=o.type;s&&s.root||(l=t+l),e.commit(l,a,s)}};return Object.defineProperties(r,{getters:{get:i?function(){return e.getters}:function(){return function(e,t){var n={},i=t.length;return Object.keys(e.getters).forEach(function(r){if(r.slice(0,i)===t){var o=r.slice(i);Object.defineProperty(n,o,{get:function(){return e.getters[r]},enumerable:!0})}}),n}(e,t)}},state:{get:function(){return h(e.state,n)}}}),r}(e,a,n);i.forEachMutation(function(t,n){!function(e,t,n,i){(e._mutations[t]||(e._mutations[t]=[])).push(function(t){n.call(e,i.state,t)})}(e,a+n,t,c)}),i.forEachAction(function(t,n){var i=t.root?n:a+n,r=t.handler||t;!function(e,t,n,i){(e._actions[t]||(e._actions[t]=[])).push(function(t,r){var o,a=n.call(e,{dispatch:i.dispatch,commit:i.commit,getters:i.getters,state:i.state,rootGetters:e.getters,rootState:e.state},t,r);return(o=a)&&"function"==typeof o.then||(a=Promise.resolve(a)),e._devtoolHook?a.catch(function(t){throw e._devtoolHook.emit("vuex:error",t),t}):a})}(e,i,r,c)}),i.forEachGetter(function(t,n){!function(e,t,n,i){if(e._wrappedGetters[t])return void 0;e._wrappedGetters[t]=function(e){return n(i.state,i.getters,e.state,e.getters)}}(e,a+n,t,c)}),i.forEachChild(function(i,o){m(e,t,n.concat(o),i,r)})}function h(e,t){return t.length?t.reduce(function(e,t){return e[t]},e):e}function g(e,t,n){var i;return null!==(i=e)&&"object"==typeof i&&e.type&&(n=t,t=e,e=e.type),{type:e,payload:t,options:n}}function v(e){l&&e===l|| +/** + * vuex v3.1.0 + * (c) 2019 Evan You + * @license MIT + */ +function(e){if(Number(e.version.split(".")[0])>=2)e.mixin({beforeCreate:n});else{var t=e.prototype._init;e.prototype._init=function(e){void 0===e&&(e={}),e.init=e.init?[n].concat(e.init):n,t.call(this,e)}}function n(){var e=this.$options;e.store?this.$store="function"==typeof e.store?e.store():e.store:e.parent&&e.parent.$store&&(this.$store=e.parent.$store)}}(l=e)}c.state.get=function(){return this._vm._data.$$state},c.state.set=function(e){0},u.prototype.commit=function(e,t,n){var i=this,r=g(e,t,n),o=r.type,a=r.payload,s=(r.options,{type:o,payload:a}),l=this._mutations[o];l&&(this._withCommit(function(){l.forEach(function(e){e(a)})}),this._subscribers.forEach(function(e){return e(s,i.state)}))},u.prototype.dispatch=function(e,t){var n=this,i=g(e,t),r=i.type,o=i.payload,a={type:r,payload:o},s=this._actions[r];if(s){try{this._actionSubscribers.filter(function(e){return e.before}).forEach(function(e){return e.before(a,n.state)})}catch(e){0}return(s.length>1?Promise.all(s.map(function(e){return e(o)})):s[0](o)).then(function(e){try{n._actionSubscribers.filter(function(e){return e.after}).forEach(function(e){return e.after(a,n.state)})}catch(e){0}return e})}},u.prototype.subscribe=function(e){return d(e,this._subscribers)},u.prototype.subscribeAction=function(e){return d("function"==typeof e?{before:e}:e,this._actionSubscribers)},u.prototype.watch=function(e,t,n){var i=this;return this._watcherVM.$watch(function(){return e(i.state,i.getters)},t,n)},u.prototype.replaceState=function(e){var t=this;this._withCommit(function(){t._vm._data.$$state=e})},u.prototype.registerModule=function(e,t,n){void 0===n&&(n={}),"string"==typeof e&&(e=[e]),this._modules.register(e,t),m(this,this.state,e,this._modules.get(e),n.preserveState),p(this,this.state)},u.prototype.unregisterModule=function(e){var t=this;"string"==typeof e&&(e=[e]),this._modules.unregister(e),this._withCommit(function(){var n=h(t.state,e.slice(0,-1));l.delete(n,e[e.length-1])}),f(this)},u.prototype.hotUpdate=function(e){this._modules.update(e),f(this,!0)},u.prototype._withCommit=function(e){var t=this._committing;this._committing=!0,e(),this._committing=t},Object.defineProperties(u.prototype,c);var y=N(function(e,t){var n={};return w(t).forEach(function(t){var i=t.key,r=t.val;n[i]=function(){var t=this.$store.state,n=this.$store.getters;if(e){var i=x(this.$store,"mapState",e);if(!i)return;t=i.context.state,n=i.context.getters}return"function"==typeof r?r.call(this,t,n):t[r]},n[i].vuex=!0}),n}),_=N(function(e,t){var n={};return w(t).forEach(function(t){var i=t.key,r=t.val;n[i]=function(){for(var t=[],n=arguments.length;n--;)t[n]=arguments[n];var i=this.$store.commit;if(e){var o=x(this.$store,"mapMutations",e);if(!o)return;i=o.context.commit}return"function"==typeof r?r.apply(this,[i].concat(t)):i.apply(this.$store,[r].concat(t))}}),n}),b=N(function(e,t){var n={};return w(t).forEach(function(t){var i=t.key,r=t.val;r=e+r,n[i]=function(){if(!e||x(this.$store,"mapGetters",e))return this.$store.getters[r]},n[i].vuex=!0}),n}),C=N(function(e,t){var n={};return w(t).forEach(function(t){var i=t.key,r=t.val;n[i]=function(){for(var t=[],n=arguments.length;n--;)t[n]=arguments[n];var i=this.$store.dispatch;if(e){var o=x(this.$store,"mapActions",e);if(!o)return;i=o.context.dispatch}return"function"==typeof r?r.apply(this,[i].concat(t)):i.apply(this.$store,[r].concat(t))}}),n});function w(e){return Array.isArray(e)?e.map(function(e){return{key:e,val:e}}):Object.keys(e).map(function(t){return{key:t,val:e[t]}})}function N(e){return function(t,n){return"string"!=typeof t?(n=t,t=""):"/"!==t.charAt(t.length-1)&&(t+="/"),e(t,n)}}function x(e,t,n){return e._modulesNamespaceMap[n]}var T={Store:u,install:v,version:"3.1.0",mapState:y,mapMutations:_,mapGetters:b,mapActions:C,createNamespacedHelpers:function(e){return{mapState:y.bind(null,e),mapGetters:b.bind(null,e),mapMutations:_.bind(null,e),mapActions:C.bind(null,e)}}};t.a=T},function(e,t,n){var i; /*! * jQuery JavaScript Library v3.3.1 * https://jquery.com/ @@ -25,7 +31,7 @@ * * Date: 2018-01-20T17:24Z */ -!function(e,n){"use strict";"object"==typeof t.exports?t.exports=e.document?n(e,!0):function(t){if(!t.document)throw new Error("jQuery requires a window with a document");return n(t)}:n(e)}("undefined"!=typeof window?window:this,function(n,o){"use strict";var i=[],a=n.document,s=Object.getPrototypeOf,c=i.slice,l=i.concat,u=i.push,f=i.indexOf,d={},p=d.toString,h=d.hasOwnProperty,g=h.toString,m=g.call(Object),v={},y=function(t){return"function"==typeof t&&"number"!=typeof t.nodeType},b=function(t){return null!=t&&t===t.window},w={type:!0,src:!0,noModule:!0};function x(t,e,n){var r,o=(e=e||a).createElement("script");if(o.text=t,n)for(r in w)n[r]&&(o[r]=n[r]);e.head.appendChild(o).parentNode.removeChild(o)}function C(t){return null==t?t+"":"object"==typeof t||"function"==typeof t?d[p.call(t)]||"object":typeof t}var _=function(t,e){return new _.fn.init(t,e)},$=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function T(t){var e=!!t&&"length"in t&&t.length,n=C(t);return!y(t)&&!b(t)&&("array"===n||0===e||"number"==typeof e&&e>0&&e-1 in t)}_.fn=_.prototype={jquery:"3.3.1",constructor:_,length:0,toArray:function(){return c.call(this)},get:function(t){return null==t?c.call(this):t<0?this[t+this.length]:this[t]},pushStack:function(t){var e=_.merge(this.constructor(),t);return e.prevObject=this,e},each:function(t){return _.each(this,t)},map:function(t){return this.pushStack(_.map(this,function(e,n){return t.call(e,n,e)}))},slice:function(){return this.pushStack(c.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(t){var e=this.length,n=+t+(t<0?e:0);return this.pushStack(n>=0&&n0&&t-1 in e)}N.fn=N.prototype={jquery:"3.3.1",constructor:N,length:0,toArray:function(){return l.call(this)},get:function(e){return null==e?l.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=N.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return N.each(this,e)},map:function(e){return this.pushStack(N.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(l.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n+~]|"+F+")"+F+"*"),U=new RegExp("="+F+"*([^\\]'\"]*?)"+F+"*\\]","g"),W=new RegExp(P),V=new RegExp("^"+L+"$"),K={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+F+"*(even|odd|(([+-]|)(\\d*)n|)"+F+"*(?:([+-]|)"+F+"*(\\d+)|))"+F+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+F+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+F+"*((?:-\\d)?\\d*)"+F+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,G=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,Q=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+F+"?|("+F+")|.)","ig"),tt=function(t,e,n){var r="0x"+e-65536;return r!=r||n?e:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},et=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,nt=function(t,e){return e?"\0"===t?"�":t.slice(0,-1)+"\\"+t.charCodeAt(t.length-1).toString(16)+" ":"\\"+t},rt=function(){d()},ot=yt(function(t){return!0===t.disabled&&("form"in t||"label"in t)},{dir:"parentNode",next:"legend"});try{j.apply(A=N.call(x.childNodes),x.childNodes),A[x.childNodes.length].nodeType}catch(t){j={apply:A.length?function(t,e){D.apply(t,N.call(e))}:function(t,e){for(var n=t.length,r=0;t[n++]=e[r++];);t.length=n-1}}}function it(t,e,r,o){var i,s,l,u,f,h,v,y=e&&e.ownerDocument,C=e?e.nodeType:9;if(r=r||[],"string"!=typeof t||!t||1!==C&&9!==C&&11!==C)return r;if(!o&&((e?e.ownerDocument||e:x)!==p&&d(e),e=e||p,g)){if(11!==C&&(f=J.exec(t)))if(i=f[1]){if(9===C){if(!(l=e.getElementById(i)))return r;if(l.id===i)return r.push(l),r}else if(y&&(l=y.getElementById(i))&&b(e,l)&&l.id===i)return r.push(l),r}else{if(f[2])return j.apply(r,e.getElementsByTagName(t)),r;if((i=f[3])&&n.getElementsByClassName&&e.getElementsByClassName)return j.apply(r,e.getElementsByClassName(i)),r}if(n.qsa&&!S[t+" "]&&(!m||!m.test(t))){if(1!==C)y=e,v=t;else if("object"!==e.nodeName.toLowerCase()){for((u=e.getAttribute("id"))?u=u.replace(et,nt):e.setAttribute("id",u=w),s=(h=a(t)).length;s--;)h[s]="#"+u+" "+vt(h[s]);v=h.join(","),y=Q.test(t)&>(e.parentNode)||e}if(v)try{return j.apply(r,y.querySelectorAll(v)),r}catch(t){}finally{u===w&&e.removeAttribute("id")}}}return c(t.replace(q,"$1"),e,r,o)}function at(){var t=[];return function e(n,o){return t.push(n+" ")>r.cacheLength&&delete e[t.shift()],e[n+" "]=o}}function st(t){return t[w]=!0,t}function ct(t){var e=p.createElement("fieldset");try{return!!t(e)}catch(t){return!1}finally{e.parentNode&&e.parentNode.removeChild(e),e=null}}function lt(t,e){for(var n=t.split("|"),o=n.length;o--;)r.attrHandle[n[o]]=e}function ut(t,e){var n=e&&t,r=n&&1===t.nodeType&&1===e.nodeType&&t.sourceIndex-e.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===e)return-1;return t?1:-1}function ft(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function dt(t){return function(e){var n=e.nodeName.toLowerCase();return("input"===n||"button"===n)&&e.type===t}}function pt(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ot(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ht(t){return st(function(e){return e=+e,st(function(n,r){for(var o,i=t([],n.length,e),a=i.length;a--;)n[o=i[a]]&&(n[o]=!(r[o]=n[o]))})})}function gt(t){return t&&void 0!==t.getElementsByTagName&&t}for(e in n=it.support={},i=it.isXML=function(t){var e=t&&(t.ownerDocument||t).documentElement;return!!e&&"HTML"!==e.nodeName},d=it.setDocument=function(t){var e,o,a=t?t.ownerDocument||t:x;return a!==p&&9===a.nodeType&&a.documentElement?(h=(p=a).documentElement,g=!i(p),x!==p&&(o=p.defaultView)&&o.top!==o&&(o.addEventListener?o.addEventListener("unload",rt,!1):o.attachEvent&&o.attachEvent("onunload",rt)),n.attributes=ct(function(t){return t.className="i",!t.getAttribute("className")}),n.getElementsByTagName=ct(function(t){return t.appendChild(p.createComment("")),!t.getElementsByTagName("*").length}),n.getElementsByClassName=G.test(p.getElementsByClassName),n.getById=ct(function(t){return h.appendChild(t).id=w,!p.getElementsByName||!p.getElementsByName(w).length}),n.getById?(r.filter.ID=function(t){var e=t.replace(Z,tt);return function(t){return t.getAttribute("id")===e}},r.find.ID=function(t,e){if(void 0!==e.getElementById&&g){var n=e.getElementById(t);return n?[n]:[]}}):(r.filter.ID=function(t){var e=t.replace(Z,tt);return function(t){var n=void 0!==t.getAttributeNode&&t.getAttributeNode("id");return n&&n.value===e}},r.find.ID=function(t,e){if(void 0!==e.getElementById&&g){var n,r,o,i=e.getElementById(t);if(i){if((n=i.getAttributeNode("id"))&&n.value===t)return[i];for(o=e.getElementsByName(t),r=0;i=o[r++];)if((n=i.getAttributeNode("id"))&&n.value===t)return[i]}return[]}}),r.find.TAG=n.getElementsByTagName?function(t,e){return void 0!==e.getElementsByTagName?e.getElementsByTagName(t):n.qsa?e.querySelectorAll(t):void 0}:function(t,e){var n,r=[],o=0,i=e.getElementsByTagName(t);if("*"===t){for(;n=i[o++];)1===n.nodeType&&r.push(n);return r}return i},r.find.CLASS=n.getElementsByClassName&&function(t,e){if(void 0!==e.getElementsByClassName&&g)return e.getElementsByClassName(t)},v=[],m=[],(n.qsa=G.test(p.querySelectorAll))&&(ct(function(t){h.appendChild(t).innerHTML="",t.querySelectorAll("[msallowcapture^='']").length&&m.push("[*^$]="+F+"*(?:''|\"\")"),t.querySelectorAll("[selected]").length||m.push("\\["+F+"*(?:value|"+R+")"),t.querySelectorAll("[id~="+w+"-]").length||m.push("~="),t.querySelectorAll(":checked").length||m.push(":checked"),t.querySelectorAll("a#"+w+"+*").length||m.push(".#.+[+~]")}),ct(function(t){t.innerHTML="";var e=p.createElement("input");e.setAttribute("type","hidden"),t.appendChild(e).setAttribute("name","D"),t.querySelectorAll("[name=d]").length&&m.push("name"+F+"*[*^$|!~]?="),2!==t.querySelectorAll(":enabled").length&&m.push(":enabled",":disabled"),h.appendChild(t).disabled=!0,2!==t.querySelectorAll(":disabled").length&&m.push(":enabled",":disabled"),t.querySelectorAll("*,:x"),m.push(",.*:")})),(n.matchesSelector=G.test(y=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ct(function(t){n.disconnectedMatch=y.call(t,"*"),y.call(t,"[s!='']:x"),v.push("!=",P)}),m=m.length&&new RegExp(m.join("|")),v=v.length&&new RegExp(v.join("|")),e=G.test(h.compareDocumentPosition),b=e||G.test(h.contains)?function(t,e){var n=9===t.nodeType?t.documentElement:t,r=e&&e.parentNode;return t===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):t.compareDocumentPosition&&16&t.compareDocumentPosition(r)))}:function(t,e){if(e)for(;e=e.parentNode;)if(e===t)return!0;return!1},k=e?function(t,e){if(t===e)return f=!0,0;var r=!t.compareDocumentPosition-!e.compareDocumentPosition;return r||(1&(r=(t.ownerDocument||t)===(e.ownerDocument||e)?t.compareDocumentPosition(e):1)||!n.sortDetached&&e.compareDocumentPosition(t)===r?t===p||t.ownerDocument===x&&b(x,t)?-1:e===p||e.ownerDocument===x&&b(x,e)?1:u?I(u,t)-I(u,e):0:4&r?-1:1)}:function(t,e){if(t===e)return f=!0,0;var n,r=0,o=t.parentNode,i=e.parentNode,a=[t],s=[e];if(!o||!i)return t===p?-1:e===p?1:o?-1:i?1:u?I(u,t)-I(u,e):0;if(o===i)return ut(t,e);for(n=t;n=n.parentNode;)a.unshift(n);for(n=e;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?ut(a[r],s[r]):a[r]===x?-1:s[r]===x?1:0},p):p},it.matches=function(t,e){return it(t,null,null,e)},it.matchesSelector=function(t,e){if((t.ownerDocument||t)!==p&&d(t),e=e.replace(U,"='$1']"),n.matchesSelector&&g&&!S[e+" "]&&(!v||!v.test(e))&&(!m||!m.test(e)))try{var r=y.call(t,e);if(r||n.disconnectedMatch||t.document&&11!==t.document.nodeType)return r}catch(t){}return it(e,p,null,[t]).length>0},it.contains=function(t,e){return(t.ownerDocument||t)!==p&&d(t),b(t,e)},it.attr=function(t,e){(t.ownerDocument||t)!==p&&d(t);var o=r.attrHandle[e.toLowerCase()],i=o&&E.call(r.attrHandle,e.toLowerCase())?o(t,e,!g):void 0;return void 0!==i?i:n.attributes||!g?t.getAttribute(e):(i=t.getAttributeNode(e))&&i.specified?i.value:null},it.escape=function(t){return(t+"").replace(et,nt)},it.error=function(t){throw new Error("Syntax error, unrecognized expression: "+t)},it.uniqueSort=function(t){var e,r=[],o=0,i=0;if(f=!n.detectDuplicates,u=!n.sortStable&&t.slice(0),t.sort(k),f){for(;e=t[i++];)e===t[i]&&(o=r.push(i));for(;o--;)t.splice(r[o],1)}return u=null,t},o=it.getText=function(t){var e,n="",r=0,i=t.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof t.textContent)return t.textContent;for(t=t.firstChild;t;t=t.nextSibling)n+=o(t)}else if(3===i||4===i)return t.nodeValue}else for(;e=t[r++];)n+=o(e);return n},(r=it.selectors={cacheLength:50,createPseudo:st,match:K,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(t){return t[1]=t[1].replace(Z,tt),t[3]=(t[3]||t[4]||t[5]||"").replace(Z,tt),"~="===t[2]&&(t[3]=" "+t[3]+" "),t.slice(0,4)},CHILD:function(t){return t[1]=t[1].toLowerCase(),"nth"===t[1].slice(0,3)?(t[3]||it.error(t[0]),t[4]=+(t[4]?t[5]+(t[6]||1):2*("even"===t[3]||"odd"===t[3])),t[5]=+(t[7]+t[8]||"odd"===t[3])):t[3]&&it.error(t[0]),t},PSEUDO:function(t){var e,n=!t[6]&&t[2];return K.CHILD.test(t[0])?null:(t[3]?t[2]=t[4]||t[5]||"":n&&W.test(n)&&(e=a(n,!0))&&(e=n.indexOf(")",n.length-e)-n.length)&&(t[0]=t[0].slice(0,e),t[2]=n.slice(0,e)),t.slice(0,3))}},filter:{TAG:function(t){var e=t.replace(Z,tt).toLowerCase();return"*"===t?function(){return!0}:function(t){return t.nodeName&&t.nodeName.toLowerCase()===e}},CLASS:function(t){var e=$[t+" "];return e||(e=new RegExp("(^|"+F+")"+t+"("+F+"|$)"))&&$(t,function(t){return e.test("string"==typeof t.className&&t.className||void 0!==t.getAttribute&&t.getAttribute("class")||"")})},ATTR:function(t,e,n){return function(r){var o=it.attr(r,t);return null==o?"!="===e:!e||(o+="","="===e?o===n:"!="===e?o!==n:"^="===e?n&&0===o.indexOf(n):"*="===e?n&&o.indexOf(n)>-1:"$="===e?n&&o.slice(-n.length)===n:"~="===e?(" "+o.replace(H," ")+" ").indexOf(n)>-1:"|="===e&&(o===n||o.slice(0,n.length+1)===n+"-"))}},CHILD:function(t,e,n,r,o){var i="nth"!==t.slice(0,3),a="last"!==t.slice(-4),s="of-type"===e;return 1===r&&0===o?function(t){return!!t.parentNode}:function(e,n,c){var l,u,f,d,p,h,g=i!==a?"nextSibling":"previousSibling",m=e.parentNode,v=s&&e.nodeName.toLowerCase(),y=!c&&!s,b=!1;if(m){if(i){for(;g;){for(d=e;d=d[g];)if(s?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;h=g="only"===t&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&y){for(b=(p=(l=(u=(f=(d=m)[w]||(d[w]={}))[d.uniqueID]||(f[d.uniqueID]={}))[t]||[])[0]===C&&l[1])&&l[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(b=p=0)||h.pop();)if(1===d.nodeType&&++b&&d===e){u[t]=[C,p,b];break}}else if(y&&(b=p=(l=(u=(f=(d=e)[w]||(d[w]={}))[d.uniqueID]||(f[d.uniqueID]={}))[t]||[])[0]===C&&l[1]),!1===b)for(;(d=++p&&d&&d[g]||(b=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++b||(y&&((u=(f=d[w]||(d[w]={}))[d.uniqueID]||(f[d.uniqueID]={}))[t]=[C,b]),d!==e)););return(b-=o)===r||b%r==0&&b/r>=0}}},PSEUDO:function(t,e){var n,o=r.pseudos[t]||r.setFilters[t.toLowerCase()]||it.error("unsupported pseudo: "+t);return o[w]?o(e):o.length>1?(n=[t,t,"",e],r.setFilters.hasOwnProperty(t.toLowerCase())?st(function(t,n){for(var r,i=o(t,e),a=i.length;a--;)t[r=I(t,i[a])]=!(n[r]=i[a])}):function(t){return o(t,0,n)}):o}},pseudos:{not:st(function(t){var e=[],n=[],r=s(t.replace(q,"$1"));return r[w]?st(function(t,e,n,o){for(var i,a=r(t,null,o,[]),s=t.length;s--;)(i=a[s])&&(t[s]=!(e[s]=i))}):function(t,o,i){return e[0]=t,r(e,null,i,n),e[0]=null,!n.pop()}}),has:st(function(t){return function(e){return it(t,e).length>0}}),contains:st(function(t){return t=t.replace(Z,tt),function(e){return(e.textContent||e.innerText||o(e)).indexOf(t)>-1}}),lang:st(function(t){return V.test(t||"")||it.error("unsupported lang: "+t),t=t.replace(Z,tt).toLowerCase(),function(e){var n;do{if(n=g?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(n=n.toLowerCase())===t||0===n.indexOf(t+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var n=t.location&&t.location.hash;return n&&n.slice(1)===e.id},root:function(t){return t===h},focus:function(t){return t===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(t.type||t.href||~t.tabIndex)},enabled:pt(!1),disabled:pt(!0),checked:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&!!t.checked||"option"===e&&!!t.selected},selected:function(t){return t.parentNode&&t.parentNode.selectedIndex,!0===t.selected},empty:function(t){for(t=t.firstChild;t;t=t.nextSibling)if(t.nodeType<6)return!1;return!0},parent:function(t){return!r.pseudos.empty(t)},header:function(t){return Y.test(t.nodeName)},input:function(t){return X.test(t.nodeName)},button:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&"button"===t.type||"button"===e},text:function(t){var e;return"input"===t.nodeName.toLowerCase()&&"text"===t.type&&(null==(e=t.getAttribute("type"))||"text"===e.toLowerCase())},first:ht(function(){return[0]}),last:ht(function(t,e){return[e-1]}),eq:ht(function(t,e,n){return[n<0?n+e:n]}),even:ht(function(t,e){for(var n=0;n=0;)t.push(r);return t}),gt:ht(function(t,e,n){for(var r=n<0?n+e:n;++r1?function(e,n,r){for(var o=t.length;o--;)if(!t[o](e,n,r))return!1;return!0}:t[0]}function wt(t,e,n,r,o){for(var i,a=[],s=0,c=t.length,l=null!=e;s-1&&(i[l]=!(a[l]=f))}}else v=wt(v===a?v.splice(h,v.length):v),o?o(null,a,v,c):j.apply(a,v)})}function Ct(t){for(var e,n,o,i=t.length,a=r.relative[t[0].type],s=a||r.relative[" "],c=a?1:0,u=yt(function(t){return t===e},s,!0),f=yt(function(t){return I(e,t)>-1},s,!0),d=[function(t,n,r){var o=!a&&(r||n!==l)||((e=n).nodeType?u(t,n,r):f(t,n,r));return e=null,o}];c1&&bt(d),c>1&&vt(t.slice(0,c-1).concat({value:" "===t[c-2].type?"*":""})).replace(q,"$1"),n,c0,o=t.length>0,i=function(i,a,s,c,u){var f,h,m,v=0,y="0",b=i&&[],w=[],x=l,_=i||o&&r.find.TAG("*",u),$=C+=null==x?1:Math.random()||.1,T=_.length;for(u&&(l=a===p||a||u);y!==T&&null!=(f=_[y]);y++){if(o&&f){for(h=0,a||f.ownerDocument===p||(d(f),s=!g);m=t[h++];)if(m(f,a||p,s)){c.push(f);break}u&&(C=$)}n&&((f=!m&&f)&&v--,i&&b.push(f))}if(v+=y,n&&y!==v){for(h=0;m=e[h++];)m(b,w,a,s);if(i){if(v>0)for(;y--;)b[y]||w[y]||(w[y]=O.call(c));w=wt(w)}j.apply(c,w),u&&!i&&w.length>0&&v+e.length>1&&it.uniqueSort(c)}return u&&(C=$,l=x),b};return n?st(i):i}(i,o))).selector=t}return s},c=it.select=function(t,e,n,o){var i,c,l,u,f,d="function"==typeof t&&t,p=!o&&a(t=d.selector||t);if(n=n||[],1===p.length){if((c=p[0]=p[0].slice(0)).length>2&&"ID"===(l=c[0]).type&&9===e.nodeType&&g&&r.relative[c[1].type]){if(!(e=(r.find.ID(l.matches[0].replace(Z,tt),e)||[])[0]))return n;d&&(e=e.parentNode),t=t.slice(c.shift().value.length)}for(i=K.needsContext.test(t)?0:c.length;i--&&(l=c[i],!r.relative[u=l.type]);)if((f=r.find[u])&&(o=f(l.matches[0].replace(Z,tt),Q.test(c[0].type)&>(e.parentNode)||e))){if(c.splice(i,1),!(t=o.length&&vt(c)))return j.apply(n,o),n;break}}return(d||s(t,p))(o,e,!g,n,!e||Q.test(t)&>(e.parentNode)||e),n},n.sortStable=w.split("").sort(k).join("")===w,n.detectDuplicates=!!f,d(),n.sortDetached=ct(function(t){return 1&t.compareDocumentPosition(p.createElement("fieldset"))}),ct(function(t){return t.innerHTML="","#"===t.firstChild.getAttribute("href")})||lt("type|href|height|width",function(t,e,n){if(!n)return t.getAttribute(e,"type"===e.toLowerCase()?1:2)}),n.attributes&&ct(function(t){return t.innerHTML="",t.firstChild.setAttribute("value",""),""===t.firstChild.getAttribute("value")})||lt("value",function(t,e,n){if(!n&&"input"===t.nodeName.toLowerCase())return t.defaultValue}),ct(function(t){return null==t.getAttribute("disabled")})||lt(R,function(t,e,n){var r;if(!n)return!0===t[e]?e.toLowerCase():(r=t.getAttributeNode(e))&&r.specified?r.value:null}),it}(n);_.find=S,_.expr=S.selectors,_.expr[":"]=_.expr.pseudos,_.uniqueSort=_.unique=S.uniqueSort,_.text=S.getText,_.isXMLDoc=S.isXML,_.contains=S.contains,_.escapeSelector=S.escape;var k=function(t,e,n){for(var r=[],o=void 0!==n;(t=t[e])&&9!==t.nodeType;)if(1===t.nodeType){if(o&&_(t).is(n))break;r.push(t)}return r},E=function(t,e){for(var n=[];t;t=t.nextSibling)1===t.nodeType&&t!==e&&n.push(t);return n},A=_.expr.match.needsContext;function O(t,e){return t.nodeName&&t.nodeName.toLowerCase()===e.toLowerCase()}var D=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(t,e,n){return y(e)?_.grep(t,function(t,r){return!!e.call(t,r,t)!==n}):e.nodeType?_.grep(t,function(t){return t===e!==n}):"string"!=typeof e?_.grep(t,function(t){return f.call(e,t)>-1!==n}):_.filter(e,t,n)}_.filter=function(t,e,n){var r=e[0];return n&&(t=":not("+t+")"),1===e.length&&1===r.nodeType?_.find.matchesSelector(r,t)?[r]:[]:_.find.matches(t,_.grep(e,function(t){return 1===t.nodeType}))},_.fn.extend({find:function(t){var e,n,r=this.length,o=this;if("string"!=typeof t)return this.pushStack(_(t).filter(function(){for(e=0;e1?_.uniqueSort(n):n},filter:function(t){return this.pushStack(j(this,t||[],!1))},not:function(t){return this.pushStack(j(this,t||[],!0))},is:function(t){return!!j(this,"string"==typeof t&&A.test(t)?_(t):t||[],!1).length}});var N,I=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(_.fn.init=function(t,e,n){var r,o;if(!t)return this;if(n=n||N,"string"==typeof t){if(!(r="<"===t[0]&&">"===t[t.length-1]&&t.length>=3?[null,t,null]:I.exec(t))||!r[1]&&e)return!e||e.jquery?(e||n).find(t):this.constructor(e).find(t);if(r[1]){if(e=e instanceof _?e[0]:e,_.merge(this,_.parseHTML(r[1],e&&e.nodeType?e.ownerDocument||e:a,!0)),D.test(r[1])&&_.isPlainObject(e))for(r in e)y(this[r])?this[r](e[r]):this.attr(r,e[r]);return this}return(o=a.getElementById(r[2]))&&(this[0]=o,this.length=1),this}return t.nodeType?(this[0]=t,this.length=1,this):y(t)?void 0!==n.ready?n.ready(t):t(_):_.makeArray(t,this)}).prototype=_.fn,N=_(a);var R=/^(?:parents|prev(?:Until|All))/,F={children:!0,contents:!0,next:!0,prev:!0};function L(t,e){for(;(t=t[e])&&1!==t.nodeType;);return t}_.fn.extend({has:function(t){var e=_(t,this),n=e.length;return this.filter(function(){for(var t=0;t-1:1===n.nodeType&&_.find.matchesSelector(n,t))){i.push(n);break}return this.pushStack(i.length>1?_.uniqueSort(i):i)},index:function(t){return t?"string"==typeof t?f.call(_(t),this[0]):f.call(this,t.jquery?t[0]:t):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(t,e){return this.pushStack(_.uniqueSort(_.merge(this.get(),_(t,e))))},addBack:function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}}),_.each({parent:function(t){var e=t.parentNode;return e&&11!==e.nodeType?e:null},parents:function(t){return k(t,"parentNode")},parentsUntil:function(t,e,n){return k(t,"parentNode",n)},next:function(t){return L(t,"nextSibling")},prev:function(t){return L(t,"previousSibling")},nextAll:function(t){return k(t,"nextSibling")},prevAll:function(t){return k(t,"previousSibling")},nextUntil:function(t,e,n){return k(t,"nextSibling",n)},prevUntil:function(t,e,n){return k(t,"previousSibling",n)},siblings:function(t){return E((t.parentNode||{}).firstChild,t)},children:function(t){return E(t.firstChild)},contents:function(t){return O(t,"iframe")?t.contentDocument:(O(t,"template")&&(t=t.content||t),_.merge([],t.childNodes))}},function(t,e){_.fn[t]=function(n,r){var o=_.map(this,e,n);return"Until"!==t.slice(-5)&&(r=n),r&&"string"==typeof r&&(o=_.filter(r,o)),this.length>1&&(F[t]||_.uniqueSort(o),R.test(t)&&o.reverse()),this.pushStack(o)}});var M=/[^\x20\t\r\n\f]+/g;function P(t){return t}function H(t){throw t}function q(t,e,n,r){var o;try{t&&y(o=t.promise)?o.call(t).done(e).fail(n):t&&y(o=t.then)?o.call(t,e,n):e.apply(void 0,[t].slice(r))}catch(t){n.apply(void 0,[t])}}_.Callbacks=function(t){t="string"==typeof t?function(t){var e={};return _.each(t.match(M)||[],function(t,n){e[n]=!0}),e}(t):_.extend({},t);var e,n,r,o,i=[],a=[],s=-1,c=function(){for(o=o||t.once,r=e=!0;a.length;s=-1)for(n=a.shift();++s-1;)i.splice(n,1),n<=s&&s--}),this},has:function(t){return t?_.inArray(t,i)>-1:i.length>0},empty:function(){return i&&(i=[]),this},disable:function(){return o=a=[],i=n="",this},disabled:function(){return!i},lock:function(){return o=a=[],n||e||(i=n=""),this},locked:function(){return!!o},fireWith:function(t,n){return o||(n=[t,(n=n||[]).slice?n.slice():n],a.push(n),e||c()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l},_.extend({Deferred:function(t){var e=[["notify","progress",_.Callbacks("memory"),_.Callbacks("memory"),2],["resolve","done",_.Callbacks("once memory"),_.Callbacks("once memory"),0,"resolved"],["reject","fail",_.Callbacks("once memory"),_.Callbacks("once memory"),1,"rejected"]],r="pending",o={state:function(){return r},always:function(){return i.done(arguments).fail(arguments),this},catch:function(t){return o.then(null,t)},pipe:function(){var t=arguments;return _.Deferred(function(n){_.each(e,function(e,r){var o=y(t[r[4]])&&t[r[4]];i[r[1]](function(){var t=o&&o.apply(this,arguments);t&&y(t.promise)?t.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[r[0]+"With"](this,o?[t]:arguments)})}),t=null}).promise()},then:function(t,r,o){var i=0;function a(t,e,r,o){return function(){var s=this,c=arguments,l=function(){var n,l;if(!(t=i&&(r!==H&&(s=void 0,c=[n]),e.rejectWith(s,c))}};t?u():(_.Deferred.getStackHook&&(u.stackTrace=_.Deferred.getStackHook()),n.setTimeout(u))}}return _.Deferred(function(n){e[0][3].add(a(0,n,y(o)?o:P,n.notifyWith)),e[1][3].add(a(0,n,y(t)?t:P)),e[2][3].add(a(0,n,y(r)?r:H))}).promise()},promise:function(t){return null!=t?_.extend(t,o):o}},i={};return _.each(e,function(t,n){var a=n[2],s=n[5];o[n[1]]=a.add,s&&a.add(function(){r=s},e[3-t][2].disable,e[3-t][3].disable,e[0][2].lock,e[0][3].lock),a.add(n[3].fire),i[n[0]]=function(){return i[n[0]+"With"](this===i?void 0:this,arguments),this},i[n[0]+"With"]=a.fireWith}),o.promise(i),t&&t.call(i,i),i},when:function(t){var e=arguments.length,n=e,r=Array(n),o=c.call(arguments),i=_.Deferred(),a=function(t){return function(n){r[t]=this,o[t]=arguments.length>1?c.call(arguments):n,--e||i.resolveWith(r,o)}};if(e<=1&&(q(t,i.done(a(n)).resolve,i.reject,!e),"pending"===i.state()||y(o[n]&&o[n].then)))return i.then();for(;n--;)q(o[n],a(n),i.reject);return i.promise()}});var z=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;_.Deferred.exceptionHook=function(t,e){n.console&&n.console.warn&&t&&z.test(t.name)&&n.console.warn("jQuery.Deferred exception: "+t.message,t.stack,e)},_.readyException=function(t){n.setTimeout(function(){throw t})};var B=_.Deferred();function U(){a.removeEventListener("DOMContentLoaded",U),n.removeEventListener("load",U),_.ready()}_.fn.ready=function(t){return B.then(t).catch(function(t){_.readyException(t)}),this},_.extend({isReady:!1,readyWait:1,ready:function(t){(!0===t?--_.readyWait:_.isReady)||(_.isReady=!0,!0!==t&&--_.readyWait>0||B.resolveWith(a,[_]))}}),_.ready.then=B.then,"complete"===a.readyState||"loading"!==a.readyState&&!a.documentElement.doScroll?n.setTimeout(_.ready):(a.addEventListener("DOMContentLoaded",U),n.addEventListener("load",U));var W=function(t,e,n,r,o,i,a){var s=0,c=t.length,l=null==n;if("object"===C(n))for(s in o=!0,n)W(t,e,s,n[s],!0,i,a);else if(void 0!==r&&(o=!0,y(r)||(a=!0),l&&(a?(e.call(t,r),e=null):(l=e,e=function(t,e,n){return l.call(_(t),n)})),e))for(;s1,null,!0)},removeData:function(t){return this.each(function(){Z.remove(this,t)})}}),_.extend({queue:function(t,e,n){var r;if(t)return e=(e||"fx")+"queue",r=Q.get(t,e),n&&(!r||Array.isArray(n)?r=Q.access(t,e,_.makeArray(n)):r.push(n)),r||[]},dequeue:function(t,e){e=e||"fx";var n=_.queue(t,e),r=n.length,o=n.shift(),i=_._queueHooks(t,e);"inprogress"===o&&(o=n.shift(),r--),o&&("fx"===e&&n.unshift("inprogress"),delete i.stop,o.call(t,function(){_.dequeue(t,e)},i)),!r&&i&&i.empty.fire()},_queueHooks:function(t,e){var n=e+"queueHooks";return Q.get(t,n)||Q.access(t,n,{empty:_.Callbacks("once memory").add(function(){Q.remove(t,[e+"queue",n])})})}}),_.fn.extend({queue:function(t,e){var n=2;return"string"!=typeof t&&(e=t,t="fx",n--),arguments.length\x20\t\r\n\f]+)/i,ht=/^$|^module$|\/(?:java|ecma)script/i,gt={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function mt(t,e){var n;return n=void 0!==t.getElementsByTagName?t.getElementsByTagName(e||"*"):void 0!==t.querySelectorAll?t.querySelectorAll(e||"*"):[],void 0===e||e&&O(t,e)?_.merge([t],n):n}function vt(t,e){for(var n=0,r=t.length;n-1)o&&o.push(i);else if(l=_.contains(i.ownerDocument,i),a=mt(f.appendChild(i),"script"),l&&vt(a),n)for(u=0;i=a[u++];)ht.test(i.type||"")&&n.push(i);return f}yt=a.createDocumentFragment().appendChild(a.createElement("div")),(bt=a.createElement("input")).setAttribute("type","radio"),bt.setAttribute("checked","checked"),bt.setAttribute("name","t"),yt.appendChild(bt),v.checkClone=yt.cloneNode(!0).cloneNode(!0).lastChild.checked,yt.innerHTML="",v.noCloneChecked=!!yt.cloneNode(!0).lastChild.defaultValue;var Ct=a.documentElement,_t=/^key/,$t=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Tt=/^([^.]*)(?:\.(.+)|)/;function St(){return!0}function kt(){return!1}function Et(){try{return a.activeElement}catch(t){}}function At(t,e,n,r,o,i){var a,s;if("object"==typeof e){for(s in"string"!=typeof n&&(r=r||n,n=void 0),e)At(t,s,n,r,e[s],i);return t}if(null==r&&null==o?(o=n,r=n=void 0):null==o&&("string"==typeof n?(o=r,r=void 0):(o=r,r=n,n=void 0)),!1===o)o=kt;else if(!o)return t;return 1===i&&(a=o,(o=function(t){return _().off(t),a.apply(this,arguments)}).guid=a.guid||(a.guid=_.guid++)),t.each(function(){_.event.add(this,e,o,r,n)})}_.event={global:{},add:function(t,e,n,r,o){var i,a,s,c,l,u,f,d,p,h,g,m=Q.get(t);if(m)for(n.handler&&(n=(i=n).handler,o=i.selector),o&&_.find.matchesSelector(Ct,o),n.guid||(n.guid=_.guid++),(c=m.events)||(c=m.events={}),(a=m.handle)||(a=m.handle=function(e){return void 0!==_&&_.event.triggered!==e.type?_.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(M)||[""]).length;l--;)p=g=(s=Tt.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),p&&(f=_.event.special[p]||{},p=(o?f.delegateType:f.bindType)||p,f=_.event.special[p]||{},u=_.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:o,needsContext:o&&_.expr.match.needsContext.test(o),namespace:h.join(".")},i),(d=c[p])||((d=c[p]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(p,a)),f.add&&(f.add.call(t,u),u.handler.guid||(u.handler.guid=n.guid)),o?d.splice(d.delegateCount++,0,u):d.push(u),_.event.global[p]=!0)},remove:function(t,e,n,r,o){var i,a,s,c,l,u,f,d,p,h,g,m=Q.hasData(t)&&Q.get(t);if(m&&(c=m.events)){for(l=(e=(e||"").match(M)||[""]).length;l--;)if(p=g=(s=Tt.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),p){for(f=_.event.special[p]||{},d=c[p=(r?f.delegateType:f.bindType)||p]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=i=d.length;i--;)u=d[i],!o&&g!==u.origType||n&&n.guid!==u.guid||s&&!s.test(u.namespace)||r&&r!==u.selector&&("**"!==r||!u.selector)||(d.splice(i,1),u.selector&&d.delegateCount--,f.remove&&f.remove.call(t,u));a&&!d.length&&(f.teardown&&!1!==f.teardown.call(t,h,m.handle)||_.removeEvent(t,p,m.handle),delete c[p])}else for(p in c)_.event.remove(t,p+e[l],n,r,!0);_.isEmptyObject(c)&&Q.remove(t,"handle events")}},dispatch:function(t){var e,n,r,o,i,a,s=_.event.fix(t),c=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],u=_.event.special[s.type]||{};for(c[0]=s,e=1;e=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==t.type||!0!==l.disabled)){for(i=[],a={},n=0;n-1:_.find(o,this,null,[l]).length),a[o]&&i.push(r);i.length&&s.push({elem:l,handlers:i})}return l=this,c\x20\t\r\n\f]*)[^>]*)\/>/gi,Dt=/\s*$/g;function It(t,e){return O(t,"table")&&O(11!==e.nodeType?e:e.firstChild,"tr")&&_(t).children("tbody")[0]||t}function Rt(t){return t.type=(null!==t.getAttribute("type"))+"/"+t.type,t}function Ft(t){return"true/"===(t.type||"").slice(0,5)?t.type=t.type.slice(5):t.removeAttribute("type"),t}function Lt(t,e){var n,r,o,i,a,s,c,l;if(1===e.nodeType){if(Q.hasData(t)&&(i=Q.access(t),a=Q.set(e,i),l=i.events))for(o in delete a.handle,a.events={},l)for(n=0,r=l[o].length;n1&&"string"==typeof h&&!v.checkClone&&jt.test(h))return t.each(function(o){var i=t.eq(o);g&&(e[0]=h.call(this,o,i.html())),Mt(i,e,n,r)});if(d&&(i=(o=xt(e,t[0].ownerDocument,!1,t,r)).firstChild,1===o.childNodes.length&&(o=i),i||r)){for(s=(a=_.map(mt(o,"script"),Rt)).length;f")},clone:function(t,e,n){var r,o,i,a,s,c,l,u=t.cloneNode(!0),f=_.contains(t.ownerDocument,t);if(!(v.noCloneChecked||1!==t.nodeType&&11!==t.nodeType||_.isXMLDoc(t)))for(a=mt(u),r=0,o=(i=mt(t)).length;r0&&vt(a,!f&&mt(t,"script")),u},cleanData:function(t){for(var e,n,r,o=_.event.special,i=0;void 0!==(n=t[i]);i++)if(G(n)){if(e=n[Q.expando]){if(e.events)for(r in e.events)o[r]?_.event.remove(n,r):_.removeEvent(n,r,e.handle);n[Q.expando]=void 0}n[Z.expando]&&(n[Z.expando]=void 0)}}}),_.fn.extend({detach:function(t){return Pt(this,t,!0)},remove:function(t){return Pt(this,t)},text:function(t){return W(this,function(t){return void 0===t?_.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=t)})},null,t,arguments.length)},append:function(){return Mt(this,arguments,function(t){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||It(this,t).appendChild(t)})},prepend:function(){return Mt(this,arguments,function(t){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var e=It(this,t);e.insertBefore(t,e.firstChild)}})},before:function(){return Mt(this,arguments,function(t){this.parentNode&&this.parentNode.insertBefore(t,this)})},after:function(){return Mt(this,arguments,function(t){this.parentNode&&this.parentNode.insertBefore(t,this.nextSibling)})},empty:function(){for(var t,e=0;null!=(t=this[e]);e++)1===t.nodeType&&(_.cleanData(mt(t,!1)),t.textContent="");return this},clone:function(t,e){return t=null!=t&&t,e=null==e?t:e,this.map(function(){return _.clone(this,t,e)})},html:function(t){return W(this,function(t){var e=this[0]||{},n=0,r=this.length;if(void 0===t&&1===e.nodeType)return e.innerHTML;if("string"==typeof t&&!Dt.test(t)&&!gt[(pt.exec(t)||["",""])[1].toLowerCase()]){t=_.htmlPrefilter(t);try{for(;n=0&&(c+=Math.max(0,Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-i-c-s-.5))),c}function te(t,e,n){var r=qt(t),o=Bt(t,e,r),i="border-box"===_.css(t,"boxSizing",!1,r),a=i;if(Ht.test(o)){if(!n)return o;o="auto"}return a=a&&(v.boxSizingReliable()||o===t.style[e]),("auto"===o||!parseFloat(o)&&"inline"===_.css(t,"display",!1,r))&&(o=t["offset"+e[0].toUpperCase()+e.slice(1)],a=!0),(o=parseFloat(o)||0)+Zt(t,e,n||(i?"border":"content"),a,r,o)+"px"}function ee(t,e,n,r,o){return new ee.prototype.init(t,e,n,r,o)}_.extend({cssHooks:{opacity:{get:function(t,e){if(e){var n=Bt(t,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(t,e,n,r){if(t&&3!==t.nodeType&&8!==t.nodeType&&t.style){var o,i,a,s=Y(e),c=Vt.test(e),l=t.style;if(c||(e=Jt(s)),a=_.cssHooks[e]||_.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(o=a.get(t,!1,r))?o:l[e];"string"===(i=typeof n)&&(o=ot.exec(n))&&o[1]&&(n=ct(t,e,o),i="number"),null!=n&&n==n&&("number"===i&&(n+=o&&o[3]||(_.cssNumber[s]?"":"px")),v.clearCloneStyle||""!==n||0!==e.indexOf("background")||(l[e]="inherit"),a&&"set"in a&&void 0===(n=a.set(t,n,r))||(c?l.setProperty(e,n):l[e]=n))}},css:function(t,e,n,r){var o,i,a,s=Y(e);return Vt.test(e)||(e=Jt(s)),(a=_.cssHooks[e]||_.cssHooks[s])&&"get"in a&&(o=a.get(t,!0,n)),void 0===o&&(o=Bt(t,e,r)),"normal"===o&&e in Xt&&(o=Xt[e]),""===n||n?(i=parseFloat(o),!0===n||isFinite(i)?i||0:o):o}}),_.each(["height","width"],function(t,e){_.cssHooks[e]={get:function(t,n,r){if(n)return!Wt.test(_.css(t,"display"))||t.getClientRects().length&&t.getBoundingClientRect().width?te(t,e,r):st(t,Kt,function(){return te(t,e,r)})},set:function(t,n,r){var o,i=qt(t),a="border-box"===_.css(t,"boxSizing",!1,i),s=r&&Zt(t,e,r,a,i);return a&&v.scrollboxSize()===i.position&&(s-=Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-parseFloat(i[e])-Zt(t,e,"border",!1,i)-.5)),s&&(o=ot.exec(n))&&"px"!==(o[3]||"px")&&(t.style[e]=n,n=_.css(t,e)),Qt(0,n,s)}}}),_.cssHooks.marginLeft=Ut(v.reliableMarginLeft,function(t,e){if(e)return(parseFloat(Bt(t,"marginLeft"))||t.getBoundingClientRect().left-st(t,{marginLeft:0},function(){return t.getBoundingClientRect().left}))+"px"}),_.each({margin:"",padding:"",border:"Width"},function(t,e){_.cssHooks[t+e]={expand:function(n){for(var r=0,o={},i="string"==typeof n?n.split(" "):[n];r<4;r++)o[t+it[r]+e]=i[r]||i[r-2]||i[0];return o}},"margin"!==t&&(_.cssHooks[t+e].set=Qt)}),_.fn.extend({css:function(t,e){return W(this,function(t,e,n){var r,o,i={},a=0;if(Array.isArray(e)){for(r=qt(t),o=e.length;a1)}}),_.Tween=ee,ee.prototype={constructor:ee,init:function(t,e,n,r,o,i){this.elem=t,this.prop=n,this.easing=o||_.easing._default,this.options=e,this.start=this.now=this.cur(),this.end=r,this.unit=i||(_.cssNumber[n]?"":"px")},cur:function(){var t=ee.propHooks[this.prop];return t&&t.get?t.get(this):ee.propHooks._default.get(this)},run:function(t){var e,n=ee.propHooks[this.prop];return this.options.duration?this.pos=e=_.easing[this.easing](t,this.options.duration*t,0,1,this.options.duration):this.pos=e=t,this.now=(this.end-this.start)*e+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):ee.propHooks._default.set(this),this}},ee.prototype.init.prototype=ee.prototype,ee.propHooks={_default:{get:function(t){var e;return 1!==t.elem.nodeType||null!=t.elem[t.prop]&&null==t.elem.style[t.prop]?t.elem[t.prop]:(e=_.css(t.elem,t.prop,""))&&"auto"!==e?e:0},set:function(t){_.fx.step[t.prop]?_.fx.step[t.prop](t):1!==t.elem.nodeType||null==t.elem.style[_.cssProps[t.prop]]&&!_.cssHooks[t.prop]?t.elem[t.prop]=t.now:_.style(t.elem,t.prop,t.now+t.unit)}}},ee.propHooks.scrollTop=ee.propHooks.scrollLeft={set:function(t){t.elem.nodeType&&t.elem.parentNode&&(t.elem[t.prop]=t.now)}},_.easing={linear:function(t){return t},swing:function(t){return.5-Math.cos(t*Math.PI)/2},_default:"swing"},_.fx=ee.prototype.init,_.fx.step={};var ne,re,oe=/^(?:toggle|show|hide)$/,ie=/queueHooks$/;function ae(){re&&(!1===a.hidden&&n.requestAnimationFrame?n.requestAnimationFrame(ae):n.setTimeout(ae,_.fx.interval),_.fx.tick())}function se(){return n.setTimeout(function(){ne=void 0}),ne=Date.now()}function ce(t,e){var n,r=0,o={height:t};for(e=e?1:0;r<4;r+=2-e)o["margin"+(n=it[r])]=o["padding"+n]=t;return e&&(o.opacity=o.width=t),o}function le(t,e,n){for(var r,o=(ue.tweeners[e]||[]).concat(ue.tweeners["*"]),i=0,a=o.length;i1)},removeAttr:function(t){return this.each(function(){_.removeAttr(this,t)})}}),_.extend({attr:function(t,e,n){var r,o,i=t.nodeType;if(3!==i&&8!==i&&2!==i)return void 0===t.getAttribute?_.prop(t,e,n):(1===i&&_.isXMLDoc(t)||(o=_.attrHooks[e.toLowerCase()]||(_.expr.match.bool.test(e)?fe:void 0)),void 0!==n?null===n?void _.removeAttr(t,e):o&&"set"in o&&void 0!==(r=o.set(t,n,e))?r:(t.setAttribute(e,n+""),n):o&&"get"in o&&null!==(r=o.get(t,e))?r:null==(r=_.find.attr(t,e))?void 0:r)},attrHooks:{type:{set:function(t,e){if(!v.radioValue&&"radio"===e&&O(t,"input")){var n=t.value;return t.setAttribute("type",e),n&&(t.value=n),e}}}},removeAttr:function(t,e){var n,r=0,o=e&&e.match(M);if(o&&1===t.nodeType)for(;n=o[r++];)t.removeAttribute(n)}}),fe={set:function(t,e,n){return!1===e?_.removeAttr(t,n):t.setAttribute(n,n),n}},_.each(_.expr.match.bool.source.match(/\w+/g),function(t,e){var n=de[e]||_.find.attr;de[e]=function(t,e,r){var o,i,a=e.toLowerCase();return r||(i=de[a],de[a]=o,o=null!=n(t,e,r)?a:null,de[a]=i),o}});var pe=/^(?:input|select|textarea|button)$/i,he=/^(?:a|area)$/i;function ge(t){return(t.match(M)||[]).join(" ")}function me(t){return t.getAttribute&&t.getAttribute("class")||""}function ve(t){return Array.isArray(t)?t:"string"==typeof t&&t.match(M)||[]}_.fn.extend({prop:function(t,e){return W(this,_.prop,t,e,arguments.length>1)},removeProp:function(t){return this.each(function(){delete this[_.propFix[t]||t]})}}),_.extend({prop:function(t,e,n){var r,o,i=t.nodeType;if(3!==i&&8!==i&&2!==i)return 1===i&&_.isXMLDoc(t)||(e=_.propFix[e]||e,o=_.propHooks[e]),void 0!==n?o&&"set"in o&&void 0!==(r=o.set(t,n,e))?r:t[e]=n:o&&"get"in o&&null!==(r=o.get(t,e))?r:t[e]},propHooks:{tabIndex:{get:function(t){var e=_.find.attr(t,"tabindex");return e?parseInt(e,10):pe.test(t.nodeName)||he.test(t.nodeName)&&t.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),v.optSelected||(_.propHooks.selected={get:function(t){var e=t.parentNode;return e&&e.parentNode&&e.parentNode.selectedIndex,null},set:function(t){var e=t.parentNode;e&&(e.selectedIndex,e.parentNode&&e.parentNode.selectedIndex)}}),_.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){_.propFix[this.toLowerCase()]=this}),_.fn.extend({addClass:function(t){var e,n,r,o,i,a,s,c=0;if(y(t))return this.each(function(e){_(this).addClass(t.call(this,e,me(this)))});if((e=ve(t)).length)for(;n=this[c++];)if(o=me(n),r=1===n.nodeType&&" "+ge(o)+" "){for(a=0;i=e[a++];)r.indexOf(" "+i+" ")<0&&(r+=i+" ");o!==(s=ge(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,o,i,a,s,c=0;if(y(t))return this.each(function(e){_(this).removeClass(t.call(this,e,me(this)))});if(!arguments.length)return this.attr("class","");if((e=ve(t)).length)for(;n=this[c++];)if(o=me(n),r=1===n.nodeType&&" "+ge(o)+" "){for(a=0;i=e[a++];)for(;r.indexOf(" "+i+" ")>-1;)r=r.replace(" "+i+" "," ");o!==(s=ge(r))&&n.setAttribute("class",s)}return this},toggleClass:function(t,e){var n=typeof t,r="string"===n||Array.isArray(t);return"boolean"==typeof e&&r?e?this.addClass(t):this.removeClass(t):y(t)?this.each(function(n){_(this).toggleClass(t.call(this,n,me(this),e),e)}):this.each(function(){var e,o,i,a;if(r)for(o=0,i=_(this),a=ve(t);e=a[o++];)i.hasClass(e)?i.removeClass(e):i.addClass(e);else void 0!==t&&"boolean"!==n||((e=me(this))&&Q.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===t?"":Q.get(this,"__className__")||""))})},hasClass:function(t){var e,n,r=0;for(e=" "+t+" ";n=this[r++];)if(1===n.nodeType&&(" "+ge(me(n))+" ").indexOf(e)>-1)return!0;return!1}});var ye=/\r/g;_.fn.extend({val:function(t){var e,n,r,o=this[0];return arguments.length?(r=y(t),this.each(function(n){var o;1===this.nodeType&&(null==(o=r?t.call(this,n,_(this).val()):t)?o="":"number"==typeof o?o+="":Array.isArray(o)&&(o=_.map(o,function(t){return null==t?"":t+""})),(e=_.valHooks[this.type]||_.valHooks[this.nodeName.toLowerCase()])&&"set"in e&&void 0!==e.set(this,o,"value")||(this.value=o))})):o?(e=_.valHooks[o.type]||_.valHooks[o.nodeName.toLowerCase()])&&"get"in e&&void 0!==(n=e.get(o,"value"))?n:"string"==typeof(n=o.value)?n.replace(ye,""):null==n?"":n:void 0}}),_.extend({valHooks:{option:{get:function(t){var e=_.find.attr(t,"value");return null!=e?e:ge(_.text(t))}},select:{get:function(t){var e,n,r,o=t.options,i=t.selectedIndex,a="select-one"===t.type,s=a?null:[],c=a?i+1:o.length;for(r=i<0?c:a?i:0;r-1)&&(n=!0);return n||(t.selectedIndex=-1),i}}}}),_.each(["radio","checkbox"],function(){_.valHooks[this]={set:function(t,e){if(Array.isArray(e))return t.checked=_.inArray(_(t).val(),e)>-1}},v.checkOn||(_.valHooks[this].get=function(t){return null===t.getAttribute("value")?"on":t.value})}),v.focusin="onfocusin"in n;var be=/^(?:focusinfocus|focusoutblur)$/,we=function(t){t.stopPropagation()};_.extend(_.event,{trigger:function(t,e,r,o){var i,s,c,l,u,f,d,p,g=[r||a],m=h.call(t,"type")?t.type:t,v=h.call(t,"namespace")?t.namespace.split("."):[];if(s=p=c=r=r||a,3!==r.nodeType&&8!==r.nodeType&&!be.test(m+_.event.triggered)&&(m.indexOf(".")>-1&&(v=m.split("."),m=v.shift(),v.sort()),u=m.indexOf(":")<0&&"on"+m,(t=t[_.expando]?t:new _.Event(m,"object"==typeof t&&t)).isTrigger=o?2:3,t.namespace=v.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+v.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=r),e=null==e?[t]:_.makeArray(e,[t]),d=_.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(r,e))){if(!o&&!d.noBubble&&!b(r)){for(l=d.delegateType||m,be.test(l+m)||(s=s.parentNode);s;s=s.parentNode)g.push(s),c=s;c===(r.ownerDocument||a)&&g.push(c.defaultView||c.parentWindow||n)}for(i=0;(s=g[i++])&&!t.isPropagationStopped();)p=s,t.type=i>1?l:d.bindType||m,(f=(Q.get(s,"events")||{})[t.type]&&Q.get(s,"handle"))&&f.apply(s,e),(f=u&&s[u])&&f.apply&&G(s)&&(t.result=f.apply(s,e),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(g.pop(),e)||!G(r)||u&&y(r[m])&&!b(r)&&((c=r[u])&&(r[u]=null),_.event.triggered=m,t.isPropagationStopped()&&p.addEventListener(m,we),r[m](),t.isPropagationStopped()&&p.removeEventListener(m,we),_.event.triggered=void 0,c&&(r[u]=c)),t.result}},simulate:function(t,e,n){var r=_.extend(new _.Event,n,{type:t,isSimulated:!0});_.event.trigger(r,null,e)}}),_.fn.extend({trigger:function(t,e){return this.each(function(){_.event.trigger(t,e,this)})},triggerHandler:function(t,e){var n=this[0];if(n)return _.event.trigger(t,e,n,!0)}}),v.focusin||_.each({focus:"focusin",blur:"focusout"},function(t,e){var n=function(t){_.event.simulate(e,t.target,_.event.fix(t))};_.event.special[e]={setup:function(){var r=this.ownerDocument||this,o=Q.access(r,e);o||r.addEventListener(t,n,!0),Q.access(r,e,(o||0)+1)},teardown:function(){var r=this.ownerDocument||this,o=Q.access(r,e)-1;o?Q.access(r,e,o):(r.removeEventListener(t,n,!0),Q.remove(r,e))}}});var xe=n.location,Ce=Date.now(),_e=/\?/;_.parseXML=function(t){var e;if(!t||"string"!=typeof t)return null;try{e=(new n.DOMParser).parseFromString(t,"text/xml")}catch(t){e=void 0}return e&&!e.getElementsByTagName("parsererror").length||_.error("Invalid XML: "+t),e};var $e=/\[\]$/,Te=/\r?\n/g,Se=/^(?:submit|button|image|reset|file)$/i,ke=/^(?:input|select|textarea|keygen)/i;function Ee(t,e,n,r){var o;if(Array.isArray(e))_.each(e,function(e,o){n||$e.test(t)?r(t,o):Ee(t+"["+("object"==typeof o&&null!=o?e:"")+"]",o,n,r)});else if(n||"object"!==C(e))r(t,e);else for(o in e)Ee(t+"["+o+"]",e[o],n,r)}_.param=function(t,e){var n,r=[],o=function(t,e){var n=y(e)?e():e;r[r.length]=encodeURIComponent(t)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(t)||t.jquery&&!_.isPlainObject(t))_.each(t,function(){o(this.name,this.value)});else for(n in t)Ee(n,t[n],e,o);return r.join("&")},_.fn.extend({serialize:function(){return _.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var t=_.prop(this,"elements");return t?_.makeArray(t):this}).filter(function(){var t=this.type;return this.name&&!_(this).is(":disabled")&&ke.test(this.nodeName)&&!Se.test(t)&&(this.checked||!dt.test(t))}).map(function(t,e){var n=_(this).val();return null==n?null:Array.isArray(n)?_.map(n,function(t){return{name:e.name,value:t.replace(Te,"\r\n")}}):{name:e.name,value:n.replace(Te,"\r\n")}}).get()}});var Ae=/%20/g,Oe=/#.*$/,De=/([?&])_=[^&]*/,je=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ne=/^(?:GET|HEAD)$/,Ie=/^\/\//,Re={},Fe={},Le="*/".concat("*"),Me=a.createElement("a");function Pe(t){return function(e,n){"string"!=typeof e&&(n=e,e="*");var r,o=0,i=e.toLowerCase().match(M)||[];if(y(n))for(;r=i[o++];)"+"===r[0]?(r=r.slice(1)||"*",(t[r]=t[r]||[]).unshift(n)):(t[r]=t[r]||[]).push(n)}}function He(t,e,n,r){var o={},i=t===Fe;function a(s){var c;return o[s]=!0,_.each(t[s]||[],function(t,s){var l=s(e,n,r);return"string"!=typeof l||i||o[l]?i?!(c=l):void 0:(e.dataTypes.unshift(l),a(l),!1)}),c}return a(e.dataTypes[0])||!o["*"]&&a("*")}function qe(t,e){var n,r,o=_.ajaxSettings.flatOptions||{};for(n in e)void 0!==e[n]&&((o[n]?t:r||(r={}))[n]=e[n]);return r&&_.extend(!0,t,r),t}Me.href=xe.href,_.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:xe.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(xe.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Le,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":_.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(t,e){return e?qe(qe(t,_.ajaxSettings),e):qe(_.ajaxSettings,t)},ajaxPrefilter:Pe(Re),ajaxTransport:Pe(Fe),ajax:function(t,e){"object"==typeof t&&(e=t,t=void 0),e=e||{};var r,o,i,s,c,l,u,f,d,p,h=_.ajaxSetup({},e),g=h.context||h,m=h.context&&(g.nodeType||g.jquery)?_(g):_.event,v=_.Deferred(),y=_.Callbacks("once memory"),b=h.statusCode||{},w={},x={},C="canceled",$={readyState:0,getResponseHeader:function(t){var e;if(u){if(!s)for(s={};e=je.exec(i);)s[e[1].toLowerCase()]=e[2];e=s[t.toLowerCase()]}return null==e?null:e},getAllResponseHeaders:function(){return u?i:null},setRequestHeader:function(t,e){return null==u&&(t=x[t.toLowerCase()]=x[t.toLowerCase()]||t,w[t]=e),this},overrideMimeType:function(t){return null==u&&(h.mimeType=t),this},statusCode:function(t){var e;if(t)if(u)$.always(t[$.status]);else for(e in t)b[e]=[b[e],t[e]];return this},abort:function(t){var e=t||C;return r&&r.abort(e),T(0,e),this}};if(v.promise($),h.url=((t||h.url||xe.href)+"").replace(Ie,xe.protocol+"//"),h.type=e.method||e.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=a.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Me.protocol+"//"+Me.host!=l.protocol+"//"+l.host}catch(t){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=_.param(h.data,h.traditional)),He(Re,h,e,$),u)return $;for(d in(f=_.event&&h.global)&&0==_.active++&&_.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Ne.test(h.type),o=h.url.replace(Oe,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(Ae,"+")):(p=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(_e.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(De,"$1"),p=(_e.test(o)?"&":"?")+"_="+Ce+++p),h.url=o+p),h.ifModified&&(_.lastModified[o]&&$.setRequestHeader("If-Modified-Since",_.lastModified[o]),_.etag[o]&&$.setRequestHeader("If-None-Match",_.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||e.contentType)&&$.setRequestHeader("Content-Type",h.contentType),$.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+Le+"; q=0.01":""):h.accepts["*"]),h.headers)$.setRequestHeader(d,h.headers[d]);if(h.beforeSend&&(!1===h.beforeSend.call(g,$,h)||u))return $.abort();if(C="abort",y.add(h.complete),$.done(h.success),$.fail(h.error),r=He(Fe,h,e,$)){if($.readyState=1,f&&m.trigger("ajaxSend",[$,h]),u)return $;h.async&&h.timeout>0&&(c=n.setTimeout(function(){$.abort("timeout")},h.timeout));try{u=!1,r.send(w,T)}catch(t){if(u)throw t;T(-1,t)}}else T(-1,"No Transport");function T(t,e,a,s){var l,d,p,w,x,C=e;u||(u=!0,c&&n.clearTimeout(c),r=void 0,i=s||"",$.readyState=t>0?4:0,l=t>=200&&t<300||304===t,a&&(w=function(t,e,n){for(var r,o,i,a,s=t.contents,c=t.dataTypes;"*"===c[0];)c.shift(),void 0===r&&(r=t.mimeType||e.getResponseHeader("Content-Type"));if(r)for(o in s)if(s[o]&&s[o].test(r)){c.unshift(o);break}if(c[0]in n)i=c[0];else{for(o in n){if(!c[0]||t.converters[o+" "+c[0]]){i=o;break}a||(a=o)}i=i||a}if(i)return i!==c[0]&&c.unshift(i),n[i]}(h,$,a)),w=function(t,e,n,r){var o,i,a,s,c,l={},u=t.dataTypes.slice();if(u[1])for(a in t.converters)l[a.toLowerCase()]=t.converters[a];for(i=u.shift();i;)if(t.responseFields[i]&&(n[t.responseFields[i]]=e),!c&&r&&t.dataFilter&&(e=t.dataFilter(e,t.dataType)),c=i,i=u.shift())if("*"===i)i=c;else if("*"!==c&&c!==i){if(!(a=l[c+" "+i]||l["* "+i]))for(o in l)if((s=o.split(" "))[1]===i&&(a=l[c+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[o]:!0!==l[o]&&(i=s[0],u.unshift(s[1]));break}if(!0!==a)if(a&&t.throws)e=a(e);else try{e=a(e)}catch(t){return{state:"parsererror",error:a?t:"No conversion from "+c+" to "+i}}}return{state:"success",data:e}}(h,w,$,l),l?(h.ifModified&&((x=$.getResponseHeader("Last-Modified"))&&(_.lastModified[o]=x),(x=$.getResponseHeader("etag"))&&(_.etag[o]=x)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=w.state,d=w.data,l=!(p=w.error))):(p=C,!t&&C||(C="error",t<0&&(t=0))),$.status=t,$.statusText=(e||C)+"",l?v.resolveWith(g,[d,C,$]):v.rejectWith(g,[$,C,p]),$.statusCode(b),b=void 0,f&&m.trigger(l?"ajaxSuccess":"ajaxError",[$,h,l?d:p]),y.fireWith(g,[$,C]),f&&(m.trigger("ajaxComplete",[$,h]),--_.active||_.event.trigger("ajaxStop")))}return $},getJSON:function(t,e,n){return _.get(t,e,n,"json")},getScript:function(t,e){return _.get(t,void 0,e,"script")}}),_.each(["get","post"],function(t,e){_[e]=function(t,n,r,o){return y(n)&&(o=o||r,r=n,n=void 0),_.ajax(_.extend({url:t,type:e,dataType:o,data:n,success:r},_.isPlainObject(t)&&t))}}),_._evalUrl=function(t){return _.ajax({url:t,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},_.fn.extend({wrapAll:function(t){var e;return this[0]&&(y(t)&&(t=t.call(this[0])),e=_(t,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&e.insertBefore(this[0]),e.map(function(){for(var t=this;t.firstElementChild;)t=t.firstElementChild;return t}).append(this)),this},wrapInner:function(t){return y(t)?this.each(function(e){_(this).wrapInner(t.call(this,e))}):this.each(function(){var e=_(this),n=e.contents();n.length?n.wrapAll(t):e.append(t)})},wrap:function(t){var e=y(t);return this.each(function(n){_(this).wrapAll(e?t.call(this,n):t)})},unwrap:function(t){return this.parent(t).not("body").each(function(){_(this).replaceWith(this.childNodes)}),this}}),_.expr.pseudos.hidden=function(t){return!_.expr.pseudos.visible(t)},_.expr.pseudos.visible=function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)},_.ajaxSettings.xhr=function(){try{return new n.XMLHttpRequest}catch(t){}};var ze={0:200,1223:204},Be=_.ajaxSettings.xhr();v.cors=!!Be&&"withCredentials"in Be,v.ajax=Be=!!Be,_.ajaxTransport(function(t){var e,r;if(v.cors||Be&&!t.crossDomain)return{send:function(o,i){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];for(a in t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||o["X-Requested-With"]||(o["X-Requested-With"]="XMLHttpRequest"),o)s.setRequestHeader(a,o[a]);e=function(t){return function(){e&&(e=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===t?s.abort():"error"===t?"number"!=typeof s.status?i(0,"error"):i(s.status,s.statusText):i(ze[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=e(),r=s.onerror=s.ontimeout=e("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&n.setTimeout(function(){e&&r()})},e=e("abort");try{s.send(t.hasContent&&t.data||null)}catch(t){if(e)throw t}},abort:function(){e&&e()}}}),_.ajaxPrefilter(function(t){t.crossDomain&&(t.contents.script=!1)}),_.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(t){return _.globalEval(t),t}}}),_.ajaxPrefilter("script",function(t){void 0===t.cache&&(t.cache=!1),t.crossDomain&&(t.type="GET")}),_.ajaxTransport("script",function(t){var e,n;if(t.crossDomain)return{send:function(r,o){e=_("\n\n\n\n\n\n// WEBPACK FOOTER //\n// Button.vue?3b36fc63","import Vue from 'vue'\nimport Button from './Button.vue'\n\nconst plugin = {\n install(Vue, options) {\n \tVue.component('ToggleButton', Button)\n }\n}\n\nexport default plugin\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js","exports = module.exports = require(\"../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".vue-js-switch[data-v-25adc6c0]{display:inline-block;position:relative;overflow:hidden;vertical-align:middle;user-select:none;font-size:10px;cursor:pointer}.vue-js-switch .v-switch-input[data-v-25adc6c0]{display:none}.vue-js-switch .v-switch-label[data-v-25adc6c0]{position:absolute;top:0;font-weight:600;color:#fff}.vue-js-switch .v-switch-label.v-left[data-v-25adc6c0]{left:10px}.vue-js-switch .v-switch-label.v-right[data-v-25adc6c0]{right:10px}.vue-js-switch .v-switch-core[data-v-25adc6c0]{display:block;position:relative;box-sizing:border-box;outline:0;margin:0;transition:border-color .3s,background-color .3s;user-select:none}.vue-js-switch .v-switch-core .v-switch-button[data-v-25adc6c0]{display:block;position:absolute;overflow:hidden;top:0;left:0;transform:translate3d(3px,3px,0);border-radius:100%;background-color:#fff}.vue-js-switch.disabled[data-v-25adc6c0]{pointer-events:none;opacity:.6}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader!./~/vue-loader/lib/style-compiler?{\"id\":\"data-v-25adc6c0\",\"scoped\":true,\"hasInlineConfig\":false}!./~/sass-loader/lib/loader.js!./~/vue-loader/lib/selector.js?type=styles&index=0!./src/Button.vue\n// module id = 4\n// module chunks = 0","/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join(\"\");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === \"string\")\r\n\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === \"number\")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader/lib/css-base.js\n// module id = 5\n// module chunks = 0","// this module is a runtime utility for cleaner component module output and will\n// be included in the final webpack user bundle\n\nmodule.exports = function normalizeComponent (\n rawScriptExports,\n compiledTemplate,\n scopeId,\n cssModules\n) {\n var esModule\n var scriptExports = rawScriptExports = rawScriptExports || {}\n\n // ES6 modules interop\n var type = typeof rawScriptExports.default\n if (type === 'object' || type === 'function') {\n esModule = rawScriptExports\n scriptExports = rawScriptExports.default\n }\n\n // Vue.extend constructor export interop\n var options = typeof scriptExports === 'function'\n ? scriptExports.options\n : scriptExports\n\n // render functions\n if (compiledTemplate) {\n options.render = compiledTemplate.render\n options.staticRenderFns = compiledTemplate.staticRenderFns\n }\n\n // scopedId\n if (scopeId) {\n options._scopeId = scopeId\n }\n\n // inject cssModules\n if (cssModules) {\n var computed = Object.create(options.computed || null)\n Object.keys(cssModules).forEach(function (key) {\n var module = cssModules[key]\n computed[key] = function () { return module }\n })\n options.computed = computed\n }\n\n return {\n esModule: esModule,\n exports: scriptExports,\n options: options\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/component-normalizer.js\n// module id = 6\n// module chunks = 0","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('label', {\n class: _vm.className,\n attrs: {\n \"role\": \"checkbox\",\n \"aria-checked\": _vm.ariaChecked\n }\n }, [_c('input', {\n staticClass: \"v-switch-input\",\n attrs: {\n \"type\": \"checkbox\",\n \"name\": _vm.name\n },\n on: {\n \"change\": function($event) {\n $event.stopPropagation();\n return _vm.toggle($event)\n }\n }\n }), _vm._v(\" \"), _c('div', {\n staticClass: \"v-switch-core\",\n style: (_vm.coreStyle)\n }, [_c('div', {\n staticClass: \"v-switch-button\",\n style: (_vm.buttonStyle)\n })]), _vm._v(\" \"), (_vm.labels) ? [(_vm.toggled) ? _c('span', {\n staticClass: \"v-switch-label v-left\",\n style: (_vm.labelStyle),\n domProps: {\n \"innerHTML\": _vm._s(_vm.labelChecked)\n }\n }) : _c('span', {\n staticClass: \"v-switch-label v-right\",\n style: (_vm.labelStyle),\n domProps: {\n \"innerHTML\": _vm._s(_vm.labelUnchecked)\n }\n })] : _vm._e()], 2)\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-25adc6c0\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/Button.vue\n// module id = 7\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a \").prop(\"disabled\",!0).appendTo(\"head\"),a.$breakpoints=h(\"\").prop(\"disabled\",!0).appendTo(\"head\"),a.isInitializing=!0,S.setUpColspan(t,o),S.setupSelector(t,o),o.columnSelector_mediaquery&&S.setupBreakpoints(t,o),a.isInitializing=!1,a.$container.length?S.updateCols(t,o):n&&console.warn(\"ColumnSelector >> container not found\"),t.$table.off(\"refreshColumnSelector\"+c).on(\"refreshColumnSelector\"+c,function(e,t,o){S.refreshColumns(this.config,t,o)}),n&&console.log(\"ColumnSelector >> Widget initialized\")):n&&console.error(\"ColumnSelector >> ERROR: Column Selector aborting, no input found in the layout! ***\")},refreshColumns:function(e,t,o){var l,a,n,c,r=e.selector,s=h.isArray(o||t),i=e.widgetOptions;if(null!=t&&r.$container.length){if(\"selectors\"===t&&(r.$container.empty(),S.setupSelector(e,i),S.setupBreakpoints(e,i),void 0===o&&null!==o&&(o=r.auto)),s)for(a=o||t,h.each(a,function(e,t){a[e]=parseInt(t,10)}),l=0;l'),o=n.selector,l=n.widgetOptions,c.find(\".tablesorter-column-selector\").html(o.$container.html()).find(\"input\").each(function(){var e=h(this).attr(\"data-column\"),t=\"auto\"===e?o.auto:o.states[e];h(this).toggleClass(l.columnSelector_cssChecked,t).prop(\"checked\",t)}),o.$popup=c.on(\"change\",\"input\",function(){if(!o.isInitializing){if(!S.checkChange(n,this.checked))return this.checked=!this.checked,!1;a=h(this).toggleClass(l.columnSelector_cssChecked,this.checked).attr(\"data-column\"),o.$container.find('input[data-column=\"'+a+'\"]').prop(\"checked\",this.checked).trigger(\"change\")}}))}};f.window_resize=function(){f.timer_resize&&clearTimeout(f.timer_resize),f.timer_resize=setTimeout(function(){h(window).trigger(\"resizeEnd\")},250)},f.addWidget({id:\"columnSelector\",priority:10,options:{columnSelector_container:null,columnSelector_columns:{},columnSelector_saveColumns:!0,columnSelector_layout:'',columnSelector_layoutCustomizer:null,columnSelector_name:\"data-selector-name\",columnSelector_mediaquery:!0,columnSelector_mediaqueryName:\"Auto: \",columnSelector_mediaqueryState:!0,columnSelector_mediaqueryHidden:!1,columnSelector_maxVisible:null,columnSelector_minVisible:null,columnSelector_breakpoints:[\"20em\",\"30em\",\"40em\",\"50em\",\"60em\",\"70em\"],columnSelector_maxPriorities:6,columnSelector_priority:\"data-priority\",columnSelector_cssChecked:\"checked\",columnSelector_classHasSpan:\"hasSpan\",columnSelector_updated:\"columnUpdate\"},init:function(e,t,o,l){S.init(e,o,l)},remove:function(e,t,o,l){var a=t.selector;!l&&a&&(a&&a.$container.empty(),a.$popup&&a.$popup.empty(),a.$style.remove(),a.$breakpoints.remove(),h(t.namespace+\"columnselector\"+o.columnSelector_classHasSpan).removeClass(o.filter_filteredRow||\"filtered\"),t.$table.find(\"[data-col-span]\").each(function(e,t){var o=h(t);o.attr(\"colspan\",o.attr(\"data-col-span\"))}),t.$table.off(\"updateAll\"+c+\" update\"+c))}})}(jQuery);return jQuery;}));\n","(function(factory){if (typeof define === 'function' && define.amd){define(['jquery'], factory);} else if (typeof module === 'object' && typeof module.exports === 'object'){module.exports = factory(require('jquery'));} else {factory(jQuery);}}(function(jQuery){\n\n/*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) */\n!function(T,w){\"use strict\";var S=T.tablesorter||{};function x(e,s){var t=isNaN(s.stickyHeaders_offset)?T(s.stickyHeaders_offset):[];return t.length?t.height()||0:parseInt(s.stickyHeaders_offset,10)||0}T.extend(S.css,{sticky:\"tablesorter-stickyHeader\",stickyVis:\"tablesorter-sticky-visible\",stickyHide:\"tablesorter-sticky-hidden\",stickyWrap:\"tablesorter-sticky-wrapper\"}),S.addHeaderResizeEvent=function(e,s,t){if((e=T(e)[0]).config){var i=T.extend({},{timer:250},t),c=e.config,l=c.widgetOptions,r=function(e){var s,t,i,r,a,d,n=c.$headers.length;for(l.resize_flag=!0,t=[],s=0;s'),v=o.parent().addClass(S.css.stickyHide).css({position:g.length?\"absolute\":\"fixed\",padding:parseInt(o.parent().parent().css(\"padding-left\"),10),top:l+_,left:0,visibility:\"hidden\",zIndex:y.stickyHeaders_zIndex||2}),p=o.children(\"thead:first\"),m=\"\",f=function(e,s){var t,i,r,a,d,n=e.filter(\":visible\"),c=n.length;for(t=0;tt.top&&c thead:gt(0), tr.sticky-false\").hide(),o.find(\"> tbody, > tfoot\").remove(),o.find(\"caption\").toggle(y.stickyHeaders_includeCaption),a=p.children().children(),o.css({height:0,width:0,margin:0}),a.find(\".\"+S.css.resizer).remove(),k.addClass(\"hasStickyHeaders\").bind(\"pagerComplete\"+d,function(){C()}),S.bindEvents(e,p.children().children(\".\"+S.css.header)),y.stickyHeaders_appendTo?T(y.stickyHeaders_appendTo).append(v):k.after(v),t.onRenderHeader)for(i=(r=p.children(\"tr\").children()).length,s=0;s> Saving last sort: \"+t.sortList+v.benchmark(a))):(e.addClass(\"hasSaveSort\"),n=\"\",v.storage&&(n=g(t),l&&console.log('saveSort >> Last sort loaded: \"'+n+'\"'+v.benchmark(a)),e.bind(\"saveSortReset\",function(t){t.stopPropagation(),v.storage(s,\"tablesorter-savesort\",\"\")})),r&&n&&0=]/g,query:\"(q|query)\",wild01:/\\?/g,wild0More:/\\*/g,quote:/\\\"/g,isNeg1:/(>=?\\s*-\\d)/,isNeg2:/(<=?\\s*\\d)/},types:{or:function(e,t,r){if(!D.orTest.test(t.iFilter)&&!D.orSplit.test(t.filter)||D.regex.test(t.filter))return null;var i,l,a,n=M.extend({},t),s=t.filter.split(D.orSplit),o=t.iFilter.split(D.orSplit),c=s.length;for(i=0;i]=?/,gtTest:/>/,gteTest:/>=/,ltTest:/'+(l.data(\"placeholder\")||l.attr(\"data-placeholder\")||f.filter_placeholder.select||\"\")+\"\":\"\",0<=(i=n=t).indexOf(f.filter_selectSourceSeparator)&&(i=(n=t.split(f.filter_selectSourceSeparator))[1],n=n[0]),e+=\"\");c.$table.find(\"thead\").find(\"select.\"+_.filter+'[data-column=\"'+a+'\"]').append(e),(s=\"function\"==typeof(i=f.filter_selectSource)||z.getColumnData(r,i,a))&&I.buildSelect(c.table,a,\"\",!0,l.hasClass(f.filter_onlyAvail))}I.buildDefault(r,!0),I.bindSearch(r,c.$table.find(\".\"+_.filter),!0),f.filter_external&&I.bindSearch(r,f.filter_external),f.filter_hideFilters&&I.hideFilters(c),c.showProcessing&&(i=\"filterStart filterEnd \".split(\" \").join(c.namespace+\"filter-sp \"),c.$table.unbind(i.replace(z.regex.spaces,\" \")).bind(i,function(e,t){l=t?c.$table.find(\".\"+_.header).filter(\"[data-column]\").filter(function(){return\"\"!==t[M(this).data(\"column\")]}):\"\",z.isProcessing(r,\"filterStart\"===e.type,t?l:\"\")})),c.filteredRows=c.totalRows,i=\"tablesorter-initialized pagerBeforeInitialized \".split(\" \").join(c.namespace+\"filter \"),c.$table.unbind(i.replace(z.regex.spaces,\" \")).bind(i,function(){I.completeInit(this)}),c.pager&&c.pager.initialized&&!f.filter_initialized?(c.$table.triggerHandler(\"filterFomatterUpdate\"),setTimeout(function(){I.filterInitComplete(c)},100)):f.filter_initialized||I.completeInit(r)},completeInit:function(e){var t=e.config,r=t.widgetOptions,i=I.setDefaults(e,t,r)||[];i.length&&(t.delayInit&&\"\"===i.join(\"\")||z.setFilters(e,i,!0)),t.$table.triggerHandler(\"filterFomatterUpdate\"),setTimeout(function(){r.filter_initialized||I.filterInitComplete(t)},100)},formatterUpdated:function(e,t){var r=e&&e.closest(\"table\"),i=r.length&&r[0].config,l=i&&i.widgetOptions;l&&!l.filter_initialized&&(l.filter_formatterInit[t]=1)},filterInitComplete:function(e){var t,r,i=e.widgetOptions,l=0,a=function(){i.filter_initialized=!0,e.lastSearch=e.$table.data(\"lastSearch\"),e.$table.triggerHandler(\"filterInit\",e),I.findRows(e.table,e.lastSearch||[]),z.debug(e,\"filter\")&&console.log(\"Filter >> Widget initialized\")};if(M.isEmptyObject(i.filter_formatter))a();else{for(r=i.filter_formatterInit.length,t=0;t';for(a=0;a\");for(t.$filters=M(g+=\"\").appendTo(t.$table.children(\"thead\").eq(0)).children(\"td\"),a=0;a\").appendTo(i):((f=z.getColumnData(e,r.filter_formatter,a))?(r.filter_formatterCount++,(g=f(i,a))&&0===g.length&&(g=i.children(\"input\")),g&&(0===g.parent().length||g.parent().length&&g.parent()[0]!==i[0])&&i.append(g)):g=M('').appendTo(i),g&&(d=n.data(\"placeholder\")||n.attr(\"data-placeholder\")||r.filter_placeholder.search||\"\",g.attr(\"placeholder\",d))),g&&(c=(M.isArray(r.filter_cssFilter)?void 0!==r.filter_cssFilter[a]&&r.filter_cssFilter[a]||\"\":r.filter_cssFilter)||\"\",g.addClass(_.filter+\" \"+c),(d=(c=r.filter_filterLabel).match(/{{([^}]+?)}}/g))||(d=[\"{{label}}\"]),M.each(d,function(e,t){var r=new RegExp(t,\"g\"),i=n.attr(\"data-\"+t.replace(/{{|}}/g,\"\")),l=void 0===i?n.text():i;c=c.replace(r,M.trim(l))}),g.attr({\"data-column\":i.attr(\"data-column\"),\"aria-label\":c}),o&&(g.attr(\"placeholder\",\"\").addClass(_.filterDisabled)[0].disabled=!0)))},bindSearch:function(l,e,t){if(l=M(l)[0],(e=M(e)).length){var r,a=l.config,n=a.widgetOptions,i=a.namespace+\"filter\",s=n.filter_$externalFilters;!0!==t&&(r=n.filter_anyColumnSelector+\",\"+n.filter_multipleColumnSelector,n.filter_$anyMatch=e.filter(r),s&&s.length?n.filter_$externalFilters=n.filter_$externalFilters.add(e):n.filter_$externalFilters=e,z.setFilters(l,a.$table.data(\"lastSearch\")||[],!1===t)),r=\"keypress keyup keydown search change input \".split(\" \").join(i+\" \"),e.attr(\"data-lastSearchTime\",(new Date).getTime()).unbind(r.replace(z.regex.spaces,\" \")).bind(\"keydown\"+i,function(e){if(e.which===o.escape&&!l.config.widgetOptions.filter_resetOnEsc)return!1}).bind(\"keyup\"+i,function(e){n=l.config.widgetOptions;var t=parseInt(M(this).attr(\"data-column\"),10),r=\"boolean\"==typeof n.filter_liveSearch?n.filter_liveSearch:z.getColumnData(l,n.filter_liveSearch,t);if(void 0===r&&(r=n.filter_liveSearch.fallback||!1),M(this).attr(\"data-lastSearchTime\",(new Date).getTime()),e.which===o.escape)this.value=n.filter_resetOnEsc?\"\":a.lastSearch[t];else{if(\"\"!==this.value&&(\"number\"==typeof r&&this.value.length=o.left&&e.which<=o.down)))return;if(!1===r&&\"\"!==this.value&&e.which!==o.enter)return}I.searching(l,!0,!0,t)}).bind(\"search change keypress input blur \".split(\" \").join(i+\" \"),function(e){var t=parseInt(M(this).attr(\"data-column\"),10),r=e.type,i=\"boolean\"==typeof n.filter_liveSearch?n.filter_liveSearch:z.getColumnData(l,n.filter_liveSearch,t);!l.config.widgetOptions.filter_initialized||e.which!==o.enter&&\"search\"!==r&&\"blur\"!==r&&(\"change\"!==r&&\"input\"!==r||!0!==i&&(!0===i||\"INPUT\"===e.target.nodeName)||this.value===a.lastSearch[t])||(e.preventDefault(),M(this).attr(\"data-lastSearchTime\",(new Date).getTime()),I.searching(l,\"keypress\"!==r,!0,t))})}},searching:function(e,t,r,i){var l,a=e.config.widgetOptions;void 0===i?l=!1:void 0===(l=\"boolean\"==typeof a.filter_liveSearch?a.filter_liveSearch:z.getColumnData(e,a.filter_liveSearch,i))&&(l=a.filter_liveSearch.fallback||!1),clearTimeout(a.filter_searchTimer),void 0===t||!0===t?a.filter_searchTimer=setTimeout(function(){I.checkFilters(e,t,r)},l?a.filter_searchDelay:10):I.checkFilters(e,t,r)},equalFilters:function(e,t,r){var i,l=[],a=[],n=e.columns+1;for(t=M.isArray(t)?t:[],r=M.isArray(r)?r:[],i=0;i=e.columns&&(s=e.columns-1);n<=s;n++)u[u.length]=n;t=t.replace(l[f],\"\")}if(!r&&/,/.test(t))for(d=(o=t.split(/\\s*,\\s*/)).length,c=0;c> Starting filter widget search\",r),m=new Date),R.filteredRows=0,t=S||[],c=R.totalRows=0;c> Searching through \"+(w&&F> Completed search\"+z.benchmark(m)),T.filter_initialized&&(R.$table.triggerHandler(\"filterBeforeEnd\",R),R.$table.triggerHandler(\"filterEnd\",R)),setTimeout(function(){z.applyWidget(R.table)},0)}},getOptionSource:function(e,t,r){var i=(e=M(e)[0]).config,l=!1,a=i.widgetOptions.filter_selectSource,n=i.$table.data(\"lastSearch\")||[],s=\"function\"==typeof a||z.getColumnData(e,a,t);if(r&&\"\"!==n[t]&&(r=!1),!0===s)l=a(e,t,r);else{if(s instanceof M||\"string\"===M.type(s)&&0<=s.indexOf(\"\"))return s;if(M.isArray(s))l=s;else if(\"object\"===M.type(a)&&s&&null===(l=s(e,t,r)))return null}return!1===l&&(l=I.getOptions(e,t,r)),I.processOptions(e,t,l)},processOptions:function(l,a,r){if(!M.isArray(r))return!1;var n,e,t,i,s,o,c=(l=M(l)[0]).config,f=null!=a&&0<=a&&a'+(p.data(\"placeholder\")||p.attr(\"data-placeholder\")||h.filter_placeholder.select||\"\")+\"\",m=u.$table.find(\"thead\").find(\"select.\"+_.filter+'[data-column=\"'+t+'\"]').val();if(void 0!==r&&\"\"!==r||null!==(r=I.getOptionSource(e,t,l))){if(M.isArray(r)){for(a=0;a\"+d.text.replace(D.quote,\""\")+\"\"}else\"\"+d!=\"[object Object]\"&&(0<=(n=s=d=(\"\"+d).replace(D.quote,\""\")).indexOf(h.filter_selectSourceSeparator)&&(n=(o=s.split(h.filter_selectSourceSeparator))[0],s=o[1]),g+=\"\"!==d?\"\":\"\");r=[]}c=(u.$filters?u.$filters:u.$table.children(\"thead\")).find(\".\"+_.filter),h.filter_$externalFilters&&(c=c&&c.length?c.add(h.filter_$externalFilters):h.filter_$externalFilters),(f=c.filter('select[data-column=\"'+t+'\"]')).length&&(f[i?\"html\":\"append\"](g),M.isArray(r)||f.append(r).val(m),f.val(m))}}},buildDefault:function(e,t){var r,i,l,a=e.config,n=a.widgetOptions,s=a.columns;for(r=0;r= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// setimmediate attaches itself to the global object\nrequire(\"setimmediate\");\n// On some exotic environments, it's not clear which object `setimmediate` was\n// able to install onto. Search each possibility in the same order as the\n// `setimmediate` library.\nexports.setImmediate = (typeof self !== \"undefined\" && self.setImmediate) ||\n (typeof global !== \"undefined\" && global.setImmediate) ||\n (this && this.setImmediate);\nexports.clearImmediate = (typeof self !== \"undefined\" && self.clearImmediate) ||\n (typeof global !== \"undefined\" && global.clearImmediate) ||\n (this && this.clearImmediate);\n","(function (global, undefined) {\n \"use strict\";\n\n if (global.setImmediate) {\n return;\n }\n\n var nextHandle = 1; // Spec says greater than zero\n var tasksByHandle = {};\n var currentlyRunningATask = false;\n var doc = global.document;\n var registerImmediate;\n\n function setImmediate(callback) {\n // Callback can either be a function or a string\n if (typeof callback !== \"function\") {\n callback = new Function(\"\" + callback);\n }\n // Copy function arguments\n var args = new Array(arguments.length - 1);\n for (var i = 0; i < args.length; i++) {\n args[i] = arguments[i + 1];\n }\n // Store and register the task\n var task = { callback: callback, args: args };\n tasksByHandle[nextHandle] = task;\n registerImmediate(nextHandle);\n return nextHandle++;\n }\n\n function clearImmediate(handle) {\n delete tasksByHandle[handle];\n }\n\n function run(task) {\n var callback = task.callback;\n var args = task.args;\n switch (args.length) {\n case 0:\n callback();\n break;\n case 1:\n callback(args[0]);\n break;\n case 2:\n callback(args[0], args[1]);\n break;\n case 3:\n callback(args[0], args[1], args[2]);\n break;\n default:\n callback.apply(undefined, args);\n break;\n }\n }\n\n function runIfPresent(handle) {\n // From the spec: \"Wait until any invocations of this algorithm started before this one have completed.\"\n // So if we're currently running a task, we'll need to delay this invocation.\n if (currentlyRunningATask) {\n // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a\n // \"too much recursion\" error.\n setTimeout(runIfPresent, 0, handle);\n } else {\n var task = tasksByHandle[handle];\n if (task) {\n currentlyRunningATask = true;\n try {\n run(task);\n } finally {\n clearImmediate(handle);\n currentlyRunningATask = false;\n }\n }\n }\n }\n\n function installNextTickImplementation() {\n registerImmediate = function(handle) {\n process.nextTick(function () { runIfPresent(handle); });\n };\n }\n\n function canUsePostMessage() {\n // The test against `importScripts` prevents this implementation from being installed inside a web worker,\n // where `global.postMessage` means something completely different and can't be used for this purpose.\n if (global.postMessage && !global.importScripts) {\n var postMessageIsAsynchronous = true;\n var oldOnMessage = global.onmessage;\n global.onmessage = function() {\n postMessageIsAsynchronous = false;\n };\n global.postMessage(\"\", \"*\");\n global.onmessage = oldOnMessage;\n return postMessageIsAsynchronous;\n }\n }\n\n function installPostMessageImplementation() {\n // Installs an event handler on `global` for the `message` event: see\n // * https://developer.mozilla.org/en/DOM/window.postMessage\n // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages\n\n var messagePrefix = \"setImmediate$\" + Math.random() + \"$\";\n var onGlobalMessage = function(event) {\n if (event.source === global &&\n typeof event.data === \"string\" &&\n event.data.indexOf(messagePrefix) === 0) {\n runIfPresent(+event.data.slice(messagePrefix.length));\n }\n };\n\n if (global.addEventListener) {\n global.addEventListener(\"message\", onGlobalMessage, false);\n } else {\n global.attachEvent(\"onmessage\", onGlobalMessage);\n }\n\n registerImmediate = function(handle) {\n global.postMessage(messagePrefix + handle, \"*\");\n };\n }\n\n function installMessageChannelImplementation() {\n var channel = new MessageChannel();\n channel.port1.onmessage = function(event) {\n var handle = event.data;\n runIfPresent(handle);\n };\n\n registerImmediate = function(handle) {\n channel.port2.postMessage(handle);\n };\n }\n\n function installReadyStateChangeImplementation() {\n var html = doc.documentElement;\n registerImmediate = function(handle) {\n // Create a \n\n\n\n\n\n// WEBPACK FOOTER //\n// Button.vue?4bb6d3a8","import ToggleButton from './Button.vue'\n\nlet installed = false\n\nexport default {\n install(Vue) {\n if (installed) {\n return\n }\n \n Vue.component('ToggleButton', ToggleButton)\n installed = true\n }\n}\n\nexport {\n ToggleButton\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js","exports = module.exports = require(\"../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".vue-js-switch[data-v-25adc6c0]{display:inline-block;position:relative;vertical-align:middle;user-select:none;font-size:10px;cursor:pointer}.vue-js-switch .v-switch-input[data-v-25adc6c0]{opacity:0;position:absolute;width:1px;height:1px}.vue-js-switch .v-switch-label[data-v-25adc6c0]{position:absolute;top:0;font-weight:600;color:#fff;z-index:1}.vue-js-switch .v-switch-label.v-left[data-v-25adc6c0]{left:10px}.vue-js-switch .v-switch-label.v-right[data-v-25adc6c0]{right:10px}.vue-js-switch .v-switch-core[data-v-25adc6c0]{display:block;position:relative;box-sizing:border-box;outline:0;margin:0;transition:border-color .3s,background-color .3s;user-select:none}.vue-js-switch .v-switch-core .v-switch-button[data-v-25adc6c0]{display:block;position:absolute;overflow:hidden;top:0;left:0;border-radius:100%;background-color:#fff;z-index:2}.vue-js-switch.disabled[data-v-25adc6c0]{pointer-events:none;opacity:.6}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader!./~/vue-loader/lib/style-compiler?{\"id\":\"data-v-25adc6c0\",\"scoped\":true,\"hasInlineConfig\":false}!./~/sass-loader/lib/loader.js!./~/vue-loader/lib/selector.js?type=styles&index=0!./src/Button.vue\n// module id = 3\n// module chunks = 0","/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join(\"\");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === \"string\")\r\n\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === \"number\")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader/lib/css-base.js\n// module id = 4\n// module chunks = 0","// this module is a runtime utility for cleaner component module output and will\n// be included in the final webpack user bundle\n\nmodule.exports = function normalizeComponent (\n rawScriptExports,\n compiledTemplate,\n scopeId,\n cssModules\n) {\n var esModule\n var scriptExports = rawScriptExports = rawScriptExports || {}\n\n // ES6 modules interop\n var type = typeof rawScriptExports.default\n if (type === 'object' || type === 'function') {\n esModule = rawScriptExports\n scriptExports = rawScriptExports.default\n }\n\n // Vue.extend constructor export interop\n var options = typeof scriptExports === 'function'\n ? scriptExports.options\n : scriptExports\n\n // render functions\n if (compiledTemplate) {\n options.render = compiledTemplate.render\n options.staticRenderFns = compiledTemplate.staticRenderFns\n }\n\n // scopedId\n if (scopeId) {\n options._scopeId = scopeId\n }\n\n // inject cssModules\n if (cssModules) {\n var computed = Object.create(options.computed || null)\n Object.keys(cssModules).forEach(function (key) {\n var module = cssModules[key]\n computed[key] = function () { return module }\n })\n options.computed = computed\n }\n\n return {\n esModule: esModule,\n exports: scriptExports,\n options: options\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/component-normalizer.js\n// module id = 5\n// module chunks = 0","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('label', {\n class: _vm.className\n }, [_c('input', {\n staticClass: \"v-switch-input\",\n attrs: {\n \"type\": \"checkbox\",\n \"name\": _vm.name,\n \"disabled\": _vm.disabled\n },\n domProps: {\n \"checked\": _vm.value\n },\n on: {\n \"change\": function($event) {\n $event.stopPropagation();\n return _vm.toggle($event)\n }\n }\n }), _vm._v(\" \"), _c('div', {\n staticClass: \"v-switch-core\",\n style: (_vm.coreStyle)\n }, [_c('div', {\n staticClass: \"v-switch-button\",\n style: (_vm.buttonStyle)\n })]), _vm._v(\" \"), (_vm.labels) ? [(_vm.toggled) ? _c('span', {\n staticClass: \"v-switch-label v-left\",\n style: (_vm.labelStyle)\n }, [_vm._t(\"checked\", [\n [_vm._v(_vm._s(_vm.labelChecked))]\n ])], 2) : _c('span', {\n staticClass: \"v-switch-label v-right\",\n style: (_vm.labelStyle)\n }, [_vm._t(\"unchecked\", [\n [_vm._v(_vm._s(_vm.labelUnchecked))]\n ])], 2)] : _vm._e()], 2)\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-25adc6c0\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/Button.vue\n// module id = 6\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a \").prop(\"disabled\",!0).appendTo(\"head\"),a.$breakpoints=h(\"\").prop(\"disabled\",!0).appendTo(\"head\"),a.isInitializing=!0,S.setUpColspan(t,o),S.setupSelector(t,o),o.columnSelector_mediaquery&&S.setupBreakpoints(t,o),a.isInitializing=!1,a.$container.length?S.updateCols(t,o):n&&console.warn(\"ColumnSelector >> container not found\"),t.$table.off(\"refreshColumnSelector\"+c).on(\"refreshColumnSelector\"+c,function(e,t,o){S.refreshColumns(this.config,t,o)}),n&&console.log(\"ColumnSelector >> Widget initialized\")):n&&console.error(\"ColumnSelector >> ERROR: Column Selector aborting, no input found in the layout! ***\")},refreshColumns:function(e,t,o){var l,a,n,c,r=e.selector,s=h.isArray(o||t),i=e.widgetOptions;if(null!=t&&r.$container.length){if(\"selectors\"===t&&(r.$container.empty(),S.setupSelector(e,i),S.setupBreakpoints(e,i),void 0===o&&null!==o&&(o=r.auto)),s)for(a=o||t,h.each(a,function(e,t){a[e]=parseInt(t,10)}),l=0;l'),o=n.selector,l=n.widgetOptions,c.find(\".tablesorter-column-selector\").html(o.$container.html()).find(\"input\").each(function(){var e=h(this).attr(\"data-column\"),t=\"auto\"===e?o.auto:o.states[e];h(this).toggleClass(l.columnSelector_cssChecked,t).prop(\"checked\",t)}),o.$popup=c.on(\"change\",\"input\",function(){if(!o.isInitializing){if(!S.checkChange(n,this.checked))return this.checked=!this.checked,!1;a=h(this).toggleClass(l.columnSelector_cssChecked,this.checked).attr(\"data-column\"),o.$container.find('input[data-column=\"'+a+'\"]').prop(\"checked\",this.checked).trigger(\"change\")}}))}};f.window_resize=function(){f.timer_resize&&clearTimeout(f.timer_resize),f.timer_resize=setTimeout(function(){h(window).trigger(\"resizeEnd\")},250)},f.addWidget({id:\"columnSelector\",priority:10,options:{columnSelector_container:null,columnSelector_columns:{},columnSelector_saveColumns:!0,columnSelector_layout:'',columnSelector_layoutCustomizer:null,columnSelector_name:\"data-selector-name\",columnSelector_mediaquery:!0,columnSelector_mediaqueryName:\"Auto: \",columnSelector_mediaqueryState:!0,columnSelector_mediaqueryHidden:!1,columnSelector_maxVisible:null,columnSelector_minVisible:null,columnSelector_breakpoints:[\"20em\",\"30em\",\"40em\",\"50em\",\"60em\",\"70em\"],columnSelector_maxPriorities:6,columnSelector_priority:\"data-priority\",columnSelector_cssChecked:\"checked\",columnSelector_classHasSpan:\"hasSpan\",columnSelector_updated:\"columnUpdate\"},init:function(e,t,o,l){S.init(e,o,l)},remove:function(e,t,o,l){var a=t.selector;!l&&a&&(a&&a.$container.empty(),a.$popup&&a.$popup.empty(),a.$style.remove(),a.$breakpoints.remove(),h(t.namespace+\"columnselector\"+o.columnSelector_classHasSpan).removeClass(o.filter_filteredRow||\"filtered\"),t.$table.find(\"[data-col-span]\").each(function(e,t){var o=h(t);o.attr(\"colspan\",o.attr(\"data-col-span\"))}),t.$table.off(\"updateAll\"+c+\" update\"+c))}})}(jQuery);return jQuery;}));\n","(function(factory){if (typeof define === 'function' && define.amd){define(['jquery'], factory);} else if (typeof module === 'object' && typeof module.exports === 'object'){module.exports = factory(require('jquery'));} else {factory(jQuery);}}(function(jQuery){\r\n\r\n/*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) */\r\n!function(T,w){\"use strict\";var S=T.tablesorter||{};function x(e,s){var t=isNaN(s.stickyHeaders_offset)?T(s.stickyHeaders_offset):[];return t.length?t.height()||0:parseInt(s.stickyHeaders_offset,10)||0}T.extend(S.css,{sticky:\"tablesorter-stickyHeader\",stickyVis:\"tablesorter-sticky-visible\",stickyHide:\"tablesorter-sticky-hidden\",stickyWrap:\"tablesorter-sticky-wrapper\"}),S.addHeaderResizeEvent=function(e,s,t){if((e=T(e)[0]).config){var i=T.extend({},{timer:250},t),c=e.config,l=c.widgetOptions,r=function(e){var s,t,i,r,a,d,n=c.$headers.length;for(l.resize_flag=!0,t=[],s=0;s'),v=o.parent().addClass(S.css.stickyHide).css({position:g.length?\"absolute\":\"fixed\",padding:parseInt(o.parent().parent().css(\"padding-left\"),10),top:l+_,left:0,visibility:\"hidden\",zIndex:y.stickyHeaders_zIndex||2}),p=o.children(\"thead:first\"),m=\"\",f=function(e,s){var t,i,r,a,d,n=e.filter(\":visible\"),c=n.length;for(t=0;tt.top&&c thead:gt(0), tr.sticky-false\").hide(),o.find(\"> tbody, > tfoot\").remove(),o.find(\"caption\").toggle(y.stickyHeaders_includeCaption),a=p.children().children(),o.css({height:0,width:0,margin:0}),a.find(\".\"+S.css.resizer).remove(),k.addClass(\"hasStickyHeaders\").bind(\"pagerComplete\"+d,function(){C()}),S.bindEvents(e,p.children().children(\".\"+S.css.header)),y.stickyHeaders_appendTo?T(y.stickyHeaders_appendTo).append(v):k.after(v),t.onRenderHeader)for(i=(r=p.children(\"tr\").children()).length,s=0;s> Saving last sort: \"+t.sortList+v.benchmark(a))):(e.addClass(\"hasSaveSort\"),n=\"\",v.storage&&(n=g(t),l&&console.log('saveSort >> Last sort loaded: \"'+n+'\"'+v.benchmark(a)),e.bind(\"saveSortReset\",function(t){t.stopPropagation(),v.storage(s,\"tablesorter-savesort\",\"\")})),r&&n&&0=]/g,query:\"(q|query)\",wild01:/\\?/g,wild0More:/\\*/g,quote:/\\\"/g,isNeg1:/(>=?\\s*-\\d)/,isNeg2:/(<=?\\s*\\d)/},types:{or:function(e,t,r){if(!D.orTest.test(t.iFilter)&&!D.orSplit.test(t.filter)||D.regex.test(t.filter))return null;var i,l,a,n=M.extend({},t),s=t.filter.split(D.orSplit),o=t.iFilter.split(D.orSplit),c=s.length;for(i=0;i]=?/,gtTest:/>/,gteTest:/>=/,ltTest:/'+(l.data(\"placeholder\")||l.attr(\"data-placeholder\")||f.filter_placeholder.select||\"\")+\"\":\"\",0<=(i=n=t).indexOf(f.filter_selectSourceSeparator)&&(i=(n=t.split(f.filter_selectSourceSeparator))[1],n=n[0]),e+=\"\");c.$table.find(\"thead\").find(\"select.\"+_.filter+'[data-column=\"'+a+'\"]').append(e),(s=\"function\"==typeof(i=f.filter_selectSource)||z.getColumnData(r,i,a))&&I.buildSelect(c.table,a,\"\",!0,l.hasClass(f.filter_onlyAvail))}I.buildDefault(r,!0),I.bindSearch(r,c.$table.find(\".\"+_.filter),!0),f.filter_external&&I.bindSearch(r,f.filter_external),f.filter_hideFilters&&I.hideFilters(c),c.showProcessing&&(i=\"filterStart filterEnd \".split(\" \").join(c.namespace+\"filter-sp \"),c.$table.unbind(i.replace(z.regex.spaces,\" \")).bind(i,function(e,t){l=t?c.$table.find(\".\"+_.header).filter(\"[data-column]\").filter(function(){return\"\"!==t[M(this).data(\"column\")]}):\"\",z.isProcessing(r,\"filterStart\"===e.type,t?l:\"\")})),c.filteredRows=c.totalRows,i=\"tablesorter-initialized pagerBeforeInitialized \".split(\" \").join(c.namespace+\"filter \"),c.$table.unbind(i.replace(z.regex.spaces,\" \")).bind(i,function(){I.completeInit(this)}),c.pager&&c.pager.initialized&&!f.filter_initialized?(c.$table.triggerHandler(\"filterFomatterUpdate\"),setTimeout(function(){I.filterInitComplete(c)},100)):f.filter_initialized||I.completeInit(r)},completeInit:function(e){var t=e.config,r=t.widgetOptions,i=I.setDefaults(e,t,r)||[];i.length&&(t.delayInit&&\"\"===i.join(\"\")||z.setFilters(e,i,!0)),t.$table.triggerHandler(\"filterFomatterUpdate\"),setTimeout(function(){r.filter_initialized||I.filterInitComplete(t)},100)},formatterUpdated:function(e,t){var r=e&&e.closest(\"table\"),i=r.length&&r[0].config,l=i&&i.widgetOptions;l&&!l.filter_initialized&&(l.filter_formatterInit[t]=1)},filterInitComplete:function(e){var t,r,i=e.widgetOptions,l=0,a=function(){i.filter_initialized=!0,e.lastSearch=e.$table.data(\"lastSearch\"),e.$table.triggerHandler(\"filterInit\",e),I.findRows(e.table,e.lastSearch||[]),z.debug(e,\"filter\")&&console.log(\"Filter >> Widget initialized\")};if(M.isEmptyObject(i.filter_formatter))a();else{for(r=i.filter_formatterInit.length,t=0;t';for(a=0;a\");for(t.$filters=M(g+=\"\").appendTo(t.$table.children(\"thead\").eq(0)).children(\"td\"),a=0;a\").appendTo(i):((f=z.getColumnData(e,r.filter_formatter,a))?(r.filter_formatterCount++,(g=f(i,a))&&0===g.length&&(g=i.children(\"input\")),g&&(0===g.parent().length||g.parent().length&&g.parent()[0]!==i[0])&&i.append(g)):g=M('').appendTo(i),g&&(d=n.data(\"placeholder\")||n.attr(\"data-placeholder\")||r.filter_placeholder.search||\"\",g.attr(\"placeholder\",d))),g&&(c=(M.isArray(r.filter_cssFilter)?void 0!==r.filter_cssFilter[a]&&r.filter_cssFilter[a]||\"\":r.filter_cssFilter)||\"\",g.addClass(_.filter+\" \"+c),(d=(c=r.filter_filterLabel).match(/{{([^}]+?)}}/g))||(d=[\"{{label}}\"]),M.each(d,function(e,t){var r=new RegExp(t,\"g\"),i=n.attr(\"data-\"+t.replace(/{{|}}/g,\"\")),l=void 0===i?n.text():i;c=c.replace(r,M.trim(l))}),g.attr({\"data-column\":i.attr(\"data-column\"),\"aria-label\":c}),o&&(g.attr(\"placeholder\",\"\").addClass(_.filterDisabled)[0].disabled=!0)))},bindSearch:function(l,e,t){if(l=M(l)[0],(e=M(e)).length){var r,a=l.config,n=a.widgetOptions,i=a.namespace+\"filter\",s=n.filter_$externalFilters;!0!==t&&(r=n.filter_anyColumnSelector+\",\"+n.filter_multipleColumnSelector,n.filter_$anyMatch=e.filter(r),s&&s.length?n.filter_$externalFilters=n.filter_$externalFilters.add(e):n.filter_$externalFilters=e,z.setFilters(l,a.$table.data(\"lastSearch\")||[],!1===t)),r=\"keypress keyup keydown search change input \".split(\" \").join(i+\" \"),e.attr(\"data-lastSearchTime\",(new Date).getTime()).unbind(r.replace(z.regex.spaces,\" \")).bind(\"keydown\"+i,function(e){if(e.which===o.escape&&!l.config.widgetOptions.filter_resetOnEsc)return!1}).bind(\"keyup\"+i,function(e){n=l.config.widgetOptions;var t=parseInt(M(this).attr(\"data-column\"),10),r=\"boolean\"==typeof n.filter_liveSearch?n.filter_liveSearch:z.getColumnData(l,n.filter_liveSearch,t);if(void 0===r&&(r=n.filter_liveSearch.fallback||!1),M(this).attr(\"data-lastSearchTime\",(new Date).getTime()),e.which===o.escape)this.value=n.filter_resetOnEsc?\"\":a.lastSearch[t];else{if(\"\"!==this.value&&(\"number\"==typeof r&&this.value.length=o.left&&e.which<=o.down)))return;if(!1===r&&\"\"!==this.value&&e.which!==o.enter)return}I.searching(l,!0,!0,t)}).bind(\"search change keypress input blur \".split(\" \").join(i+\" \"),function(e){var t=parseInt(M(this).attr(\"data-column\"),10),r=e.type,i=\"boolean\"==typeof n.filter_liveSearch?n.filter_liveSearch:z.getColumnData(l,n.filter_liveSearch,t);!l.config.widgetOptions.filter_initialized||e.which!==o.enter&&\"search\"!==r&&\"blur\"!==r&&(\"change\"!==r&&\"input\"!==r||!0!==i&&(!0===i||\"INPUT\"===e.target.nodeName)||this.value===a.lastSearch[t])||(e.preventDefault(),M(this).attr(\"data-lastSearchTime\",(new Date).getTime()),I.searching(l,\"keypress\"!==r,!0,t))})}},searching:function(e,t,r,i){var l,a=e.config.widgetOptions;void 0===i?l=!1:void 0===(l=\"boolean\"==typeof a.filter_liveSearch?a.filter_liveSearch:z.getColumnData(e,a.filter_liveSearch,i))&&(l=a.filter_liveSearch.fallback||!1),clearTimeout(a.filter_searchTimer),void 0===t||!0===t?a.filter_searchTimer=setTimeout(function(){I.checkFilters(e,t,r)},l?a.filter_searchDelay:10):I.checkFilters(e,t,r)},equalFilters:function(e,t,r){var i,l=[],a=[],n=e.columns+1;for(t=M.isArray(t)?t:[],r=M.isArray(r)?r:[],i=0;i=e.columns&&(s=e.columns-1);n<=s;n++)u[u.length]=n;t=t.replace(l[f],\"\")}if(!r&&/,/.test(t))for(d=(o=t.split(/\\s*,\\s*/)).length,c=0;c> Starting filter widget search\",r),m=new Date),R.filteredRows=0,t=S||[],c=R.totalRows=0;c> Searching through \"+(w&&F> Completed search\"+z.benchmark(m)),T.filter_initialized&&(R.$table.triggerHandler(\"filterBeforeEnd\",R),R.$table.triggerHandler(\"filterEnd\",R)),setTimeout(function(){z.applyWidget(R.table)},0)}},getOptionSource:function(e,t,r){var i=(e=M(e)[0]).config,l=!1,a=i.widgetOptions.filter_selectSource,n=i.$table.data(\"lastSearch\")||[],s=\"function\"==typeof a||z.getColumnData(e,a,t);if(r&&\"\"!==n[t]&&(r=!1),!0===s)l=a(e,t,r);else{if(s instanceof M||\"string\"===M.type(s)&&0<=s.indexOf(\"\"))return s;if(M.isArray(s))l=s;else if(\"object\"===M.type(a)&&s&&null===(l=s(e,t,r)))return null}return!1===l&&(l=I.getOptions(e,t,r)),I.processOptions(e,t,l)},processOptions:function(l,a,r){if(!M.isArray(r))return!1;var n,e,t,i,s,o,c=(l=M(l)[0]).config,f=null!=a&&0<=a&&a'+(p.data(\"placeholder\")||p.attr(\"data-placeholder\")||h.filter_placeholder.select||\"\")+\"\",m=u.$table.find(\"thead\").find(\"select.\"+_.filter+'[data-column=\"'+t+'\"]').val();if(void 0!==r&&\"\"!==r||null!==(r=I.getOptionSource(e,t,l))){if(M.isArray(r)){for(a=0;a\"+d.text.replace(D.quote,\""\")+\"\"}else\"\"+d!=\"[object Object]\"&&(0<=(n=s=d=(\"\"+d).replace(D.quote,\""\")).indexOf(h.filter_selectSourceSeparator)&&(n=(o=s.split(h.filter_selectSourceSeparator))[0],s=o[1]),g+=\"\"!==d?\"\":\"\");r=[]}c=(u.$filters?u.$filters:u.$table.children(\"thead\")).find(\".\"+_.filter),h.filter_$externalFilters&&(c=c&&c.length?c.add(h.filter_$externalFilters):h.filter_$externalFilters),(f=c.filter('select[data-column=\"'+t+'\"]')).length&&(f[i?\"html\":\"append\"](g),M.isArray(r)||f.append(r).val(m),f.val(m))}}},buildDefault:function(e,t){var r,i,l,a=e.config,n=a.widgetOptions,s=a.columns;for(r=0;r= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// setimmediate attaches itself to the global object\nrequire(\"setimmediate\");\n// On some exotic environments, it's not clear which object `setimmediate` was\n// able to install onto. Search each possibility in the same order as the\n// `setimmediate` library.\nexports.setImmediate = (typeof self !== \"undefined\" && self.setImmediate) ||\n (typeof global !== \"undefined\" && global.setImmediate) ||\n (this && this.setImmediate);\nexports.clearImmediate = (typeof self !== \"undefined\" && self.clearImmediate) ||\n (typeof global !== \"undefined\" && global.clearImmediate) ||\n (this && this.clearImmediate);\n","(function (global, undefined) {\n \"use strict\";\n\n if (global.setImmediate) {\n return;\n }\n\n var nextHandle = 1; // Spec says greater than zero\n var tasksByHandle = {};\n var currentlyRunningATask = false;\n var doc = global.document;\n var registerImmediate;\n\n function setImmediate(callback) {\n // Callback can either be a function or a string\n if (typeof callback !== \"function\") {\n callback = new Function(\"\" + callback);\n }\n // Copy function arguments\n var args = new Array(arguments.length - 1);\n for (var i = 0; i < args.length; i++) {\n args[i] = arguments[i + 1];\n }\n // Store and register the task\n var task = { callback: callback, args: args };\n tasksByHandle[nextHandle] = task;\n registerImmediate(nextHandle);\n return nextHandle++;\n }\n\n function clearImmediate(handle) {\n delete tasksByHandle[handle];\n }\n\n function run(task) {\n var callback = task.callback;\n var args = task.args;\n switch (args.length) {\n case 0:\n callback();\n break;\n case 1:\n callback(args[0]);\n break;\n case 2:\n callback(args[0], args[1]);\n break;\n case 3:\n callback(args[0], args[1], args[2]);\n break;\n default:\n callback.apply(undefined, args);\n break;\n }\n }\n\n function runIfPresent(handle) {\n // From the spec: \"Wait until any invocations of this algorithm started before this one have completed.\"\n // So if we're currently running a task, we'll need to delay this invocation.\n if (currentlyRunningATask) {\n // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a\n // \"too much recursion\" error.\n setTimeout(runIfPresent, 0, handle);\n } else {\n var task = tasksByHandle[handle];\n if (task) {\n currentlyRunningATask = true;\n try {\n run(task);\n } finally {\n clearImmediate(handle);\n currentlyRunningATask = false;\n }\n }\n }\n }\n\n function installNextTickImplementation() {\n registerImmediate = function(handle) {\n process.nextTick(function () { runIfPresent(handle); });\n };\n }\n\n function canUsePostMessage() {\n // The test against `importScripts` prevents this implementation from being installed inside a web worker,\n // where `global.postMessage` means something completely different and can't be used for this purpose.\n if (global.postMessage && !global.importScripts) {\n var postMessageIsAsynchronous = true;\n var oldOnMessage = global.onmessage;\n global.onmessage = function() {\n postMessageIsAsynchronous = false;\n };\n global.postMessage(\"\", \"*\");\n global.onmessage = oldOnMessage;\n return postMessageIsAsynchronous;\n }\n }\n\n function installPostMessageImplementation() {\n // Installs an event handler on `global` for the `message` event: see\n // * https://developer.mozilla.org/en/DOM/window.postMessage\n // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages\n\n var messagePrefix = \"setImmediate$\" + Math.random() + \"$\";\n var onGlobalMessage = function(event) {\n if (event.source === global &&\n typeof event.data === \"string\" &&\n event.data.indexOf(messagePrefix) === 0) {\n runIfPresent(+event.data.slice(messagePrefix.length));\n }\n };\n\n if (global.addEventListener) {\n global.addEventListener(\"message\", onGlobalMessage, false);\n } else {\n global.attachEvent(\"onmessage\", onGlobalMessage);\n }\n\n registerImmediate = function(handle) {\n global.postMessage(messagePrefix + handle, \"*\");\n };\n }\n\n function installMessageChannelImplementation() {\n var channel = new MessageChannel();\n channel.port1.onmessage = function(event) {\n var handle = event.data;\n runIfPresent(handle);\n };\n\n registerImmediate = function(handle) {\n channel.port2.postMessage(handle);\n };\n }\n\n function installReadyStateChangeImplementation() {\n var html = doc.documentElement;\n registerImmediate = function(handle) {\n // Create a diff --git a/themes/light/templates/config_general.mako b/themes/light/templates/config_general.mako index 4216de5faf..4465997f56 100644 --- a/themes/light/templates/config_general.mako +++ b/themes/light/templates/config_general.mako @@ -381,7 +381,7 @@ window.app = new Vue({ diff --git a/themes/light/templates/config_notifications.mako b/themes/light/templates/config_notifications.mako index f6ba873be2..4d64161460 100644 --- a/themes/light/templates/config_notifications.mako +++ b/themes/light/templates/config_notifications.mako @@ -153,7 +153,7 @@ window.app = new Vue({ enabled: null, api: [], messageTitle: null, - piority: null, + priority: null, notifyOnSnatch: null, notifyOnDownload: null, notifyOnSubtitleDownload: null @@ -451,7 +451,7 @@ window.app = new Vue({ const response = await apiRoute('home/testTwitter'); const { data } = response; this.twitterTestInfo = data; - } catch { + } catch (e) { this.twitterTestInfo = 'Error while trying to request for a test on the twitter api.' } }, @@ -1659,7 +1659,7 @@ window.app = new Vue({ - + @@ -1668,7 +1668,7 @@ window.app = new Vue({ - + + diff --git a/themes/light/templates/config_search.mako b/themes/light/templates/config_search.mako index 318e56986f..a164434a65 100644 --- a/themes/light/templates/config_search.mako +++ b/themes/light/templates/config_search.mako @@ -48,7 +48,8 @@ window.app = new Vue({ labelOption: true, labelAnimeOption: true, seedTimeOption: true, - pausedOption: true + pausedOption: true, + testStatus: 'Click below to test' }, transmission: { title: 'Transmission', @@ -58,6 +59,7 @@ window.app = new Vue({ seedLocationOption: true, seedTimeOption: true, pausedOption: true, + testStatus: 'Click below to test' }, deluge: { title: 'Deluge (via WebUI)', @@ -69,7 +71,8 @@ window.app = new Vue({ labelAnimeOption: true, seedLocationOption: true, pausedOption: true, - verifyCertOption: true + verifyCertOption: true, + testStatus: 'Click below to test' }, deluged: { title: 'Deluge (via Daemon)', @@ -81,12 +84,14 @@ window.app = new Vue({ labelAnimeOption: true, seedLocationOption: true, pausedOption: true, - verifyCertOption: true + verifyCertOption: true, + testStatus: 'Click below to test' }, downloadstation: { title: 'Synology DS', description: 'URL to your Synology DS client (e.g. http://localhost:5000)', - pathOption: true + pathOption: true, + testStatus: 'Click below to test' }, rtorrent: { title: 'rTorrent', @@ -94,19 +99,22 @@ window.app = new Vue({ pathOption: true, labelOption: true, labelAnimeOption: true, - verifyCertOption: true + verifyCertOption: true, + testStatus: 'Click below to test' }, qbittorrent: { title: 'qBittorrent', description: 'URL to your qBittorrent client (e.g. http://localhost:8080)', labelOption: true, labelAnimeOption: true, - pausedOption: true + pausedOption: true, + testStatus: 'Click below to test' }, mlnet: { title: 'MLDonkey', description: 'URL to your MLDonkey (e.g. http://localhost:4080)', - verifyCertOption: true + verifyCertOption: true, + testStatus: 'Click below to test' } }, nzb: { @@ -138,7 +146,7 @@ window.app = new Vue({ method: null, path: null, paused: null, - rpcurl: null, + rpcUrl: null, seedLocation: null, seedTime: null, username: null, @@ -457,7 +465,7 @@ window.app = new Vue({ - +

time in minutes between searches (min. {{search.general.minBacklogFrequency}})

diff --git a/themes/light/templates/displayShow.mako b/themes/light/templates/displayShow.mako index 1bf57ac7d7..75738eb48e 100644 --- a/themes/light/templates/displayShow.mako +++ b/themes/light/templates/displayShow.mako @@ -9,12 +9,14 @@ %> <%block name="scripts"> <%block name="scripts" /> diff --git a/themes/light/templates/partials/footer.mako b/themes/light/templates/partials/footer.mako index 555009f14f..697e1356bd 100644 --- a/themes/light/templates/partials/footer.mako +++ b/themes/light/templates/partials/footer.mako @@ -6,6 +6,7 @@ import re from medusa import app from medusa.helper.common import pretty_file_size + from medusa.sbdatetime import sbdatetime from medusa.show.show import Show mem_usage = None @@ -50,7 +51,7 @@ % endif Load time: ${"%.4f" % (time() - sbStartTime)}s / Mako: ${"%.4f" % (time() - makoStartTime)}s | Branch: ${app.BRANCH} | - Now: ${datetime.now().strftime(app.DATE_PRESET+" "+app.TIME_PRESET).decode(app.SYS_ENCODING)} + Now: ${sbdatetime.now().sbfdatetime(d_preset=app.DATE_PRESET, t_preset=app.TIME_PRESET)} diff --git a/themes/light/templates/partials/home/banner.mako b/themes/light/templates/partials/home/banner.mako index 8f8d9d08ca..aa57699878 100644 --- a/themes/light/templates/partials/home/banner.mako +++ b/themes/light/templates/partials/home/banner.mako @@ -114,7 +114,7 @@ else: den = 1 download_stat_tip = "Unaired" - progressbar_percent = nom * 100 / den + progressbar_percent = nom * 100 // den %> % if cur_airs_next: diff --git a/themes/light/templates/partials/home/poster.mako b/themes/light/templates/partials/home/poster.mako index a79a95dbed..19bd7d8308 100644 --- a/themes/light/templates/partials/home/poster.mako +++ b/themes/light/templates/partials/home/poster.mako @@ -87,7 +87,7 @@ else: den = 1 download_stat_tip = "Unaired" - progressbar_percent = nom * 100 / den + progressbar_percent = nom * 100 // den data_date = '6000000000.0' if cur_airs_next: data_date = calendar.timegm(sbdatetime.sbdatetime.convert_to_setting(network_timezones.parse_date_time(cur_airs_next, cur_show.airs, cur_show.network)).timetuple()) diff --git a/themes/light/templates/partials/home/simple.mako b/themes/light/templates/partials/home/simple.mako index b99e248710..a90ba2d533 100644 --- a/themes/light/templates/partials/home/simple.mako +++ b/themes/light/templates/partials/home/simple.mako @@ -115,7 +115,7 @@ else: den = 1 download_stat_tip = "Unaired" - progressbar_percent = nom * 100 / den + progressbar_percent = nom * 100 // den %> % if cur_airs_next: diff --git a/themes/light/templates/partials/home/small.mako b/themes/light/templates/partials/home/small.mako index aa45fef442..18b73b25a7 100644 --- a/themes/light/templates/partials/home/small.mako +++ b/themes/light/templates/partials/home/small.mako @@ -114,7 +114,7 @@ else: den = 1 download_stat_tip = "Unaired" - progressbar_percent = nom * 100 / den + progressbar_percent = nom * 100 // den %> % if cur_airs_next: diff --git a/themes/light/templates/partials/schedule/banner.mako b/themes/light/templates/partials/schedule/banner.mako index 8bdbf99890..9fe2bdbef1 100644 --- a/themes/light/templates/partials/schedule/banner.mako +++ b/themes/light/templates/partials/schedule/banner.mako @@ -4,7 +4,7 @@ from medusa import app from medusa.indexers.indexer_api import indexerApi from medusa.indexers.utils import indexer_id_to_name - from medusa import sbdatetime + from medusa.sbdatetime import sbdatetime %> <% @@ -59,17 +59,17 @@ <% too_late_header = True %> % elif cur_ep_enddate >= today and cur_ep_airdate < next_week.date(): % if cur_ep_airdate == today.date(): -

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()}[Today]

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()}[Today]

<% today_header = True %> % else: -

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()}

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()}

% endif % endif <% cur_segment = cur_ep_airdate %> % endif % if cur_ep_airdate == today.date() and not today_header:
-

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()} [Today]

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()} [Today]

<% today_header = True %> % endif @@ -128,7 +128,7 @@ Next Episode: ${'S%02iE%02i' % (int(cur_result['season']), int(cur_result['episode']))} - ${cur_result['name']}
- Airs: ${sbdatetime.sbdatetime.sbfdatetime(cur_result['localtime'])}${('', ' on %s' % cur_result['network'])[bool(cur_result['network'])]} + Airs: ${sbdatetime.sbfdatetime(cur_result['localtime'])}${('', ' on %s' % cur_result['network'])[bool(cur_result['network'])]}
Quality: diff --git a/themes/light/templates/partials/schedule/calendar.mako b/themes/light/templates/partials/schedule/calendar.mako index 2d2055724f..7c788767ba 100644 --- a/themes/light/templates/partials/schedule/calendar.mako +++ b/themes/light/templates/partials/schedule/calendar.mako @@ -5,7 +5,7 @@ from medusa import app from medusa.indexers.utils import indexer_id_to_name - from medusa import sbdatetime + from medusa.sbdatetime import sbdatetime %> <% dates = [today.date() + datetime.timedelta(days = i) for i in range(7)] %> @@ -15,7 +15,7 @@ % for day in dates: <% tbl_day += 1 %> - + <% day_has_show = False %> % for cur_result in results: @@ -28,7 +28,7 @@ % if airday == day: % try: <% day_has_show = True %> - <% airtime = sbdatetime.sbdatetime.fromtimestamp(time.mktime(cur_result['localtime'].timetuple())).sbftime().decode(app.SYS_ENCODING) %> + <% airtime = sbdatetime.fromtimestamp(time.mktime(cur_result['localtime'].timetuple())).sbftime() %> % if app.TRIM_ZERO: <% airtime = re.sub(r'0(\d:\d\d)', r'\1', airtime, 0, re.IGNORECASE | re.MULTILINE) %> % endif diff --git a/themes/light/templates/partials/schedule/poster.mako b/themes/light/templates/partials/schedule/poster.mako index ab7e98b9e4..557b119c89 100644 --- a/themes/light/templates/partials/schedule/poster.mako +++ b/themes/light/templates/partials/schedule/poster.mako @@ -4,7 +4,7 @@ from medusa import app from medusa.indexers.indexer_api import indexerApi from medusa.indexers.utils import indexer_id_to_name - from medusa import sbdatetime + from medusa.sbdatetime import sbdatetime %> <% @@ -59,17 +59,17 @@ <% too_late_header = True %> % elif cur_ep_enddate >= today and cur_ep_airdate < next_week.date(): % if cur_ep_airdate == today.date(): -

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()}[Today]

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()}[Today]

<% today_header = True %> % else: -

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()}

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()}

% endif % endif <% cur_segment = cur_ep_airdate %> % endif % if cur_ep_airdate == today.date() and not today_header:
-

${datetime.date.fromordinal(cur_ep_airdate.toordinal()).strftime('%A').decode(app.SYS_ENCODING).capitalize()} [Today]

+

${sbdatetime.sbftime(dt=cur_ep_airdate, t_preset='%A').capitalize()} [Today]

<% today_header = True %> % endif @@ -126,7 +126,7 @@ Next Episode:${'S%02iE%02i' % (int(cur_result['season']), int(cur_result['episode']))} - ${cur_result['name']}
- Airs: ${sbdatetime.sbdatetime.sbfdatetime(cur_result['localtime'])}${('', ' on %s' % cur_result['network'])[bool(cur_result['network'])]} + Airs: ${sbdatetime.sbfdatetime(cur_result['localtime'])}${('', ' on %s' % cur_result['network'])[bool(cur_result['network'])]}
Quality: diff --git a/themes/light/templates/partials/showheader.mako b/themes/light/templates/partials/showheader.mako deleted file mode 100644 index 43cc528228..0000000000 --- a/themes/light/templates/partials/showheader.mako +++ /dev/null @@ -1,274 +0,0 @@ -<%! - import json - import operator - - from medusa import app, helpers, subtitles, network_timezones - from medusa.common import SKIPPED, WANTED, ARCHIVED, IGNORED, FAILED, DOWNLOADED - from medusa.common import Quality, qualityPresets, statusStrings, Overview - from medusa.helper.common import pretty_file_size - from medusa.indexers.indexer_api import indexerApi -%> -
- ## @TODO: Remove data attributes - ## @SEE: https://github.com/pymedusa/Medusa/pull/5087#discussion_r214074436 -
-
- ## @TODO: Remove data attributes - ## @SEE: https://github.com/pymedusa/Medusa/pull/5087#discussion_r214077142 -

- {{ show.title }} -

-
- -
- - Manual search for:
- {{ show.title }} / Season {{ season }} -
-
-
- - Display Specials: {{ config.layout.show.specials ? 'Hide' : 'Show' }} - - -
- - - - -
-
-
-
- -% if show_message: -
-
- ${show_message} -
-
-% endif - -
-
-
-
-
- -
-
-
- -
- -
-
- -
- - - - - - - [trakt] - - - - - % if xem_numbering or xem_absolute_numbering: - - [xem] - - % endif - [fanart.tv] -
-
-
    - %if show.genre: -
  • {{ genre }}
  • - % elif show.imdb_info.get('genres'): - % for imdbgenre in show.imdb_info['genres'].replace('Sci-Fi', 'Science-Fiction').split('|'): -
  • ${imdbgenre}
  • - % endfor - % endif -
-
-
- -
- -
-
-
${day.strftime('%A').decode(app.SYS_ENCODING).capitalize()}
${sbdatetime.sbftime(dt=day, t_preset='%A').capitalize()}
- - - - - <% allowed_qualities, preferred_qualities = Quality.split_quality(int(show.quality)) %> - - - - - - - % if showLoc[1]: - - % else: - - % endif - % if all_scene_exceptions: - - % endif - % if show.show_words().required_words: - - % endif - % if show.show_words().ignored_words: - - % endif - % if show.show_words().preferred_words: - - % endif - % if show.show_words().undesired_words: - - % endif - % if bwl and bwl.whitelist: - - - - - % endif - % if bwl and bwl.blacklist: - - - - - % endif - -
- -
Quality: - % if show.quality in qualityPresets: - - % else: - % if allowed_qualities: - <% allowed_as_json = json.dumps(sorted(allowed_qualities)) %> - Allowed: - - ${'
' if preferred_qualities else ''} - % endif - % if preferred_qualities: - <% preferred_as_json = json.dumps(sorted(preferred_qualities)) %> - Preferred: - - % endif - % endif -
Originally Airs: {{ show.airs }} ${"" if network_timezones.test_timeformat(show.airs) else "(invalid Timeformat)"} on {{ show.network }}
Originally Airs: {{ show.network }}
Originally Airs: {{ show.airs }} ${"" if network_timezones.test_timeformat(show.airs) else "(invalid Timeformat)"}
Show Status: {{ show.status }}
Default EP Status: {{ show.config.defaultEpisodeStatus }}
Location: ${showLoc[0]}
Location: ${showLoc[0]} (Missing)
Scene Name:${all_scene_exceptions}
Required Words: ${', '.join(show.show_words().required_words)}
Ignored Words: ${', '.join(show.show_words().ignored_words)}
Preferred Words: ${', '.join(show.show_words().preferred_words)}
Undesired Words: ${', '.join(show.show_words().undesired_words)}
Wanted Group${"s" if len(bwl.whitelist) > 1 else ""}:${', '.join(bwl.whitelist)}
Unwanted Group${"s" if len(bwl.blacklist) > 1 else ""}:${', '.join(bwl.blacklist)}
Size:${pretty_file_size(helpers.get_size(showLoc[0]))}
-
- - -
- - <% info_flag = subtitles.code_from_code(show.lang) if show.lang else '' %> - - - - - - - - - -
Info Language:${show.lang}
Subtitles:
Season Folders:
Paused:
Air-by-Date:
Sports:
Anime:
DVD Order:
Scene Numbering:
-
- - - - - - -
-
-
-
-
- <% total_snatched = ep_counts[Overview.SNATCHED] + ep_counts[Overview.SNATCHED_PROPER] + ep_counts[Overview.SNATCHED_BEST] %> - - - - - - - -
-
- - - - - - -
-
-
-
-
-
diff --git a/themes/light/templates/snatchSelection.mako b/themes/light/templates/snatchSelection.mako index f6283c0c86..90b46c5697 100644 --- a/themes/light/templates/snatchSelection.mako +++ b/themes/light/templates/snatchSelection.mako @@ -2,6 +2,7 @@ <%! from datetime import datetime from medusa import app + from medusa.sbdatetime import sbdatetime %> <%block name="scripts"> @@ -11,7 +12,11 @@
- <%include file="/partials/showheader.mako"/> +
@@ -137,12 +142,11 @@ - <% user_preset = app.DATE_PRESET + ' ' + app.TIME_PRESET %> - ${hItem['pubdate'].strftime(user_preset).decode(app.SYS_ENCODING) if hItem['pubdate'] else 'N/A'} + ${sbdatetime.sbfdatetime(dt=hItem['pubdate'], d_preset=app.DATE_PRESET, t_preset=app.TIME_PRESET) if hItem['pubdate'] else 'N/A'} - ${hItem['date_added'].strftime(user_preset).decode(app.SYS_ENCODING) if hItem['date_added'] else 'N/A'} + ${sbdatetime.sbfdatetime(dt=hItem['date_added'], d_preset=app.DATE_PRESET, t_preset=app.TIME_PRESET) if hItem['date_added'] else 'N/A'} search diff --git a/themes/light/templates/status.mako b/themes/light/templates/status.mako index 59cf56017e..0f92672d63 100644 --- a/themes/light/templates/status.mako +++ b/themes/light/templates/status.mako @@ -5,6 +5,7 @@ from medusa.show_queue import ShowQueueActions from medusa.helper.common import dateTimeFormat from random import choice + from six import iteritems %> <%block name="scripts">