Private GIT

Skip to content
Snippets Groups Projects
Select Git revision
  • df0e168ee8346273731b81cc5783ebb4979f20a0
  • master default protected
  • fix_nzb_cat
  • develop
  • guessit2-minimal
  • ssl_warning
  • UHD-qualities
  • fix_providers8
  • !
  • tvvault
  • provider_alpharatio
  • v5.1.1
  • v5.1
  • v5.0.3
  • v5.0.2
  • v5.0.1
  • v5.0
  • v4.2.1.07
  • v4.2.1.06
  • v4.2.1.05
  • v4.2.1.04
  • v4.2.1.03
  • v4.2.1.02
  • v4.2.1.01
  • v4.2.1.0
  • v4.2.0.6
  • v4.2.0.5
  • v4.2.0.4
  • v4.2.0.3
  • v4.2.0.2
  • v4.2.0.1
31 results

yggtorrent.py

Blame
  • user avatar
    skillfr authored and miigotu committed
    df0e168e
    History
    yggtorrent.py 6.97 KiB
    # coding=utf-8
    # Author: adaur <adaur.underground@gmail.com>
    # Contributor: PHD <phd59fr@gmail.com>
    #
    # URL: https://sickrage.github.io
    #
    # This file is part of SickRage.
    #
    # SickRage 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.
    #
    # SickRage 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 SickRage. If not, see <http://www.gnu.org/licenses/>.
    
    from __future__ import unicode_literals
    
    import re
    
    from requests.compat import urljoin
    from requests.utils import dict_from_cookiejar
    
    from sickbeard import logger, tvcache
    from sickbeard.bs4_parser import BS4Parser
    from sickrage.helper.common import convert_size, try_int
    from sickrage.providers.torrent.TorrentProvider import TorrentProvider
    
    
    class YggTorrentProvider(TorrentProvider):  # pylint: disable=too-many-instance-attributes
    
        def __init__(self):
    
            # Provider Init
            TorrentProvider.__init__(self, 'YggTorrent')
    
            # Credentials
            self.username = None
            self.password = None
    
            # Torrent Stats
            self.minseed = None
            self.minleech = None
    
            # URLs
            self.url = 'https://ww2.yggtorrent.is/'
            self.urls = {
                'login': urljoin(self.url, 'user/login'),
                'search': urljoin(self.url, 'engine/search')
            }
    
            # Proper Strings
            self.proper_strings = ['PROPER']
    
            # Cache
            self.cache = tvcache.TVCache(self, min_time=30)
    
        def login(self):
            login_params = {
                'id': self.username,
                'pass': self.password,
            }
    
            response = self.get_url(self.urls['login'], post_data=login_params, returns='response')
    
            # The login is now an AJAX call (401 : Bad credentials, 200 : Logged in, other : server failure)
            if not response or response.status_code != 200:
                logger.log('Unable to connect to provider', logger.WARNING)
                return False
            else:
                # It seems we are logged, let's verify that !
                response = self.get_url(self.url, returns='response')
    
                if response.status_code != 200:
                    logger.log('Unable to connect to provider', logger.WARNING)
                    return False
                if 'logout' not in response.text:
                    logger.log('Invalid username or password. Check your settings', logger.WARNING)
                    return False
    
            return True
    
        def search(self, search_strings, age=0, ep_obj=None):  # pylint: disable=too-many-locals, too-many-branches
            results = []
    
            for mode in search_strings:
                items = []
                logger.log('Search Mode: {0}'.format(mode), logger.DEBUG)
    
                for search_string in search_strings[mode]:
    
                    if mode != 'RSS':
                        logger.log('Search string: {0}'.format
                                   (search_string.decode('utf-8')), logger.DEBUG)
                    # search string needs to be normalized, single quotes are apparently not allowed on the site
                    # ç should also be replaced, people tend to use c instead
                    replace_chars = {
                                    "'": '',
                                    "ç": 'c'
                    }
    
                    for k, v in replace_chars.iteritems():
                        search_string = search_string.replace(k, v)
    
                    logger.log('Sanitized string: {0}'.format
                                   (search_string.decode('utf-8')), logger.DEBUG)
    
                    try:
                        search_params = {
                            'category': "2145",
                            'sub_category' : "2184",
                            'name': re.sub(r'[()]', '', search_string),
                            'do': 'search'
                        }
                        data = self.get_url(self.urls['search'], params=search_params, returns='text')
                        if not data:
                            continue
    
                        if 'logout' not in data:
                            logger.log('Refreshing cookies', logger.DEBUG)
                            self.login()
    
                        with BS4Parser(data, 'html5lib') as html:
                            torrent_table = html.find(class_='table')
                            torrent_rows = torrent_table('tr') if torrent_table else []
    
                            # Continue only if at least one Release is found
                            if len(torrent_rows) < 2:
                                logger.log('Data returned from provider does not contain any torrents', logger.DEBUG)
                                continue
    
                            # Skip column headers
                            for result in torrent_rows[1:]:
                                cells = result('td')
                                if len(cells) < 9:
                                    continue
    
                                title = cells[1].find('a').get_text(strip=True)
                                id = cells[2].find('a')['target']
                                download_url = urljoin(self.url, 'engine/download_torrent?id=' + id)
    
                                if not (title and download_url):
                                    continue
    
                                seeders = try_int(cells[7].get_text(strip=True))
                                leechers = try_int(cells[8].get_text(strip=True))
    
                                torrent_size = cells[5].get_text()
                                size = convert_size(torrent_size) or -1
    
                                # Filter unseeded torrent
                                if seeders < self.minseed or leechers < self.minleech:
                                    if mode != 'RSS':
                                        logger.log('Discarding torrent because it doesn\'t meet the minimum seeders or leechers: {0} (S:{1} L:{2})'.format
                                                   (title, seeders, leechers), logger.DEBUG)
                                    continue
    
                                item = {'title': title, 'link': download_url, 'size': size, 'seeders': seeders, 'leechers': leechers, 'hash': ''}
                                if mode != 'RSS':
                                    logger.log('Found result: {0} with {1} seeders and {2} leechers'.format
                                               (title, seeders, leechers), logger.DEBUG)
    
                                items.append(item)
    
                    except (AttributeError, TypeError, KeyError, ValueError):
                        logger.log('Failed parsing provider {}.'.format(self.name), logger.ERROR)
    
                # For each search mode sort all the items by seeders if available
                items.sort(key=lambda d: try_int(d.get('seeders', 0)), reverse=True)
                results += items
    
            return results
    
    
    provider = YggTorrentProvider()