diff --git a/CHANGELOG.md b/CHANGELOG.md index f56bbf119b..f900976c4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## Unreleased #### New Features +- Added provider nordicbits ([#5854](https://github.com/pymedusa/Medusa/pull/5854)) #### Improvements diff --git a/medusa/providers/__init__.py b/medusa/providers/__init__.py index 726d43b2a0..c9ea575a0e 100644 --- a/medusa/providers/__init__.py +++ b/medusa/providers/__init__.py @@ -40,6 +40,7 @@ nebulance, newpct, norbits, + nordicbits, nyaa, pretome, privatehd, @@ -69,7 +70,7 @@ 'speedcd', 'nyaa', 'torrentbytes', 'torrent9', 'morethantv', 'tokyotoshokan', 'iptorrents', 'hebits', 'alpharatio', 'sdbits', 'shazbat', 'rarbg', 'tntvillage', 'binsearch', 'xthor', 'abnormal', 'scenetime', 'nebulance', 'tvchaosuk', 'bitcannon', 'torrentz2', 'pretome', 'anizb', - 'hdspace', 'newpct', 'danishbits', 'limetorrents', 'norbits', 'bithdtv', + 'hdspace', 'newpct', 'nordicbits', 'danishbits', 'limetorrents', 'norbits', 'bithdtv', 'zooqle', 'animebytes', 'animetorrents', 'horriblesubs', 'anidex', 'shanaproject', 'torrenting', 'yggtorrent', 'elitetracker', 'archetorrent', 'privatehd', 'cinemaz', 'avistaz', 'bjshare', 'btdb' ] diff --git a/medusa/providers/torrent/__init__.py b/medusa/providers/torrent/__init__.py index ba268643d2..2baa1b3caf 100644 --- a/medusa/providers/torrent/__init__.py +++ b/medusa/providers/torrent/__init__.py @@ -24,6 +24,7 @@ morethantv, nebulance, newpct, + nordicbits, pretome, privatehd, scenetime, @@ -66,8 +67,8 @@ __all__ = [ 'abnormal', 'alpharatio', 'animebytes', 'archetorrent', 'bithdtv', 'torrent9', 'danishbits', - 'hdspace', 'hdtorrents', 'iptorrents', 'limetorrents', 'morethantv', 'torznab', - 'newpct', 'pretome', 'sdbits', 'scenetime', 'speedcd', 'thepiratebay', 'tntvillage', 'tokyotoshokan', + 'hdspace', 'hdtorrents', 'iptorrents', 'limetorrents', 'morethantv', 'torznab', 'newpct', 'nordicbits', + 'pretome', 'sdbits', 'scenetime', 'speedcd', 'thepiratebay', 'tntvillage', 'tokyotoshokan', 'torrentbytes', 'torrentleech', 'nebulance', 'tvchaosuk', 'xthor', 'zooqle', 'bitcannon', 'btn', 'hdbits', 'norbits', 'rarbg', 'torrentday', 'nyaa', 'rsstorrent', 'shazbat', 'hebits', 'torrentz2', 'animetorrents', 'horriblesubs', 'anidex', 'shanaproject', 'torrenting', 'yggtorrent', diff --git a/medusa/providers/torrent/html/nordicbits.py b/medusa/providers/torrent/html/nordicbits.py new file mode 100644 index 0000000000..002c1e2237 --- /dev/null +++ b/medusa/providers/torrent/html/nordicbits.py @@ -0,0 +1,206 @@ +# coding=utf-8 + +"""Provider code for NordicBits.""" + +from __future__ import unicode_literals + +import logging + +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 +from requests.utils import dict_from_cookiejar + +log = BraceAdapter(logging.getLogger(__name__)) +log.logger.addHandler(logging.NullHandler()) + + +class NordicBitsProvider(TorrentProvider): + """NordicBits Torrent provider.""" + + def __init__(self): + """Initialize the class.""" + super(NordicBitsProvider, self).__init__('NordicBits') + + # Credentials + self.username = None + self.password = None + + # URLs + self.url = 'https://nordicb.org' + self.urls = { + 'login': urljoin(self.url, 'takelogin.php'), + 'search': urljoin(self.url, 'browse.php'), + } + + # Proper Strings + self.proper_strings = ['PROPER', 'REPACK', 'REAL', 'RERIP'] + + # Miscellaneous Options + self.freeleech = False + + # Torrent Stats + self.minseed = None + self.minleech = None + + # Cache + self.cache = tv.Cache(self) + + def search(self, search_strings, **kwargs): + """ + Search a provider and parse the results. + + :param search_strings: A dict with mode (key) and the search value (value) + :returns: A list of search results (structure) + """ + results = [] + if not self.login(): + return results + + search_params = { + 'cats2[]': [48, 57, 66, 11, 7, 5, 30, 31, 32], + 'searchin': 'title', + 'incldead': 0 # Fixed to not include dead torrents for now + } + + if self.freeleech: + search_params['only_free'] = 1 + + for mode in search_strings: + log.debug('Search mode: {0}', mode) + + for search_string in search_strings[mode]: + + if mode != 'RSS': + search_params['search'] = search_string + log.debug('Search string: {search}', + {'search': search_string}) + + 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 + + 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 + """ + def get_label_title(label): + """Get table row header labels.""" + if label.get_text(): + return label.get_text(strip=True) + if label.a and label.a.get_text(strip=True): + return label.a.get_text(strip=True) + if label.img: + return label.img.get('title') + + items = [] + if '