Skip to content

Commit

Permalink
Merge pull request #54 from pymedusa/upstream
Browse files Browse the repository at this point in the history
Upstream
  • Loading branch information
labrys committed Feb 29, 2016
2 parents 2768f26 + a0b13b4 commit 24eb637
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 6 deletions.
Binary file added gui/slick/images/providers/norbits.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions sickbeard/providers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
from sickbeard.providers import btn, newznab, rsstorrent, womble, thepiratebay, torrentleech, kat, iptorrents, torrentz, \
omgwtfnzbs, scc, hdtorrents, torrentday, hdbits, hounddawgs, speedcd, nyaatorrents, bluetigers, xthor, abnormal, phxbit, torrentbytes, cpasbien,\
freshontv, morethantv, bitsoup, t411, tokyotoshokan, shazbat, rarbg, alpharatio, tntvillage, binsearch, torrentproject, extratorrent, \
scenetime, btdigg, transmitthenet, tvchaosuk, bitcannon, pretome, gftracker, hdspace, newpct, elitetorrent, bitsnoop, danishbits, hd4free, limetorrents
scenetime, btdigg, transmitthenet, tvchaosuk, bitcannon, pretome, gftracker, hdspace, newpct, elitetorrent, bitsnoop, danishbits, hd4free, limetorrents, \
norbits

__all__ = [
'womble', 'btn', 'thepiratebay', 'kat', 'torrentleech', 'scc', 'hdtorrents',
Expand All @@ -35,7 +36,8 @@
'shazbat', 'rarbg', 'tntvillage', 'binsearch', 'bluetigers',
'xthor', 'abnormal', 'phxbit', 'scenetime', 'btdigg', 'transmitthenet', 'tvchaosuk',
'torrentproject', 'extratorrent', 'bitcannon', 'torrentz', 'pretome', 'gftracker',
'hdspace', 'newpct', 'elitetorrent', 'bitsnoop', 'danishbits', 'hd4free', 'limetorrents'
'hdspace', 'newpct', 'elitetorrent', 'bitsnoop', 'danishbits', 'hd4free', 'limetorrents',
'norbits'
]


Expand Down
144 changes: 144 additions & 0 deletions sickbeard/providers/norbits.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# coding=utf-8
'''A Norbits (https://norbits.net) provider'''

# 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 requests.compat import urlencode

from sickbeard import logger, tvcache

from sickrage.helper.exceptions import AuthException
from sickrage.providers.torrent.TorrentProvider import TorrentProvider

try:
import json
except ImportError:
import simplejson as json


class NorbitsProvider(TorrentProvider): # pylint: disable=too-many-instance-attributes
'''Main provider object'''

def __init__(self):
''' Initialize the class '''
TorrentProvider.__init__(self, 'Norbits')

self.username = None
self.passkey = None
self.ratio = None
self.minseed = None
self.minleech = None

self.cache = tvcache.TVCache(self, min_time=20) # only poll Norbits every 15 minutes max

self.url = 'https://norbits.net'
self.urls = {'search': self.url + '/api2.php?action=torrents',
'download': self.url + '/download.php?'}

self.logger = logger.Logger()

def _check_auth(self):

if not self.username or not self.passkey:
raise AuthException(('Your authentication credentials for %s are '
'missing, check your config.') % self.name)

return True

def _checkAuthFromData(self, parsed_json): # pylint: disable=invalid-name
''' Check that we are authenticated. '''

if 'status' in parsed_json and 'message' in parsed_json:
if parsed_json.get('status') == 3:
self.logger.log((u'Invalid username or password. '
'Check your settings'), logger.WARNING)

return True

def search(self, search_params, age=0, ep_obj=None): # pylint: disable=too-many-locals
''' Do the actual searching and JSON parsing'''

results = []

for mode in search_params:
items = []
self.logger.log(u'Search Mode: {}'.format(mode), logger.DEBUG)

for search_string in search_params[mode]:
if mode != 'RSS':
self.logger.log('Search string: {}'.format(search_string.decode('utf-8')),
logger.DEBUG)

post_data = {
'username': self.username,
'passkey': self.passkey,
'category': '2', # TV Category
'search': search_string,
}

self._check_auth()
parsed_json = self.get_url(self.urls['search'],
post_data=json.dumps(post_data),
json=True)

if not parsed_json:
return []

if self._checkAuthFromData(parsed_json):
if parsed_json and 'data' in parsed_json:
json_items = parsed_json['data']
else:
self.logger.log((u'Resulting JSON from provider is not correct, '
'not parsing it'), logger.ERROR)
if 'torrents' in json_items:
for item in json_items['torrents']:
seeders = item['seeders']
leechers = item['leechers']
title = item['name']
info_hash = item['info_hash']
size = item['size']
download_url = ('{}{}'.format(self.urls['download'],
urlencode({'id': item['id'],
'passkey': self.passkey})))

if seeders < self.minseed or leechers < self.minleech:
self.logger.log((u'Discarding torrent because it does not meet '
'the minimum seeders or leechers: '
'{} (S:{} L:{})').format
(title, seeders, leechers), logger.DEBUG)
continue
else:
item = title, download_url, size, seeders, leechers, info_hash
if mode != "RSS":
self.logger.log((u'Found result: {} with {} seeders and {}'
'leechers').format(title,
seeders,
leechers), logger.DEBUG)

items.append(item)
# For each search mode sort all the items by seeders if available
items.sort(key=lambda tup: tup[3], reverse=True)

results += items

return results

def seed_ratio(self):
return self.ratio

provider = NorbitsProvider() # pylint: disable=invalid-name
4 changes: 2 additions & 2 deletions sickbeard/providers/tntvillage.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,12 @@ def _check_auth(self):
return True

def login(self):
if any(dict_from_cookiejar(self.session.cookies).values()):
if len(dict_from_cookiejar(self.session.cookies)) == 3:
return True

login_params = {'UserName': self.username,
'PassWord': self.password,
'CookieDate': 0,
'CookieDate': 1,
'submit': 'Connettiti al Forum'}

response = self.get_url(self.urls['login'], post_data=login_params, timeout=30)
Expand Down
16 changes: 14 additions & 2 deletions sickbeard/providers/tvchaosuk.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.

import re
import time
from requests.utils import dict_from_cookiejar

from sickbeard import logger, tvcache
Expand Down Expand Up @@ -65,7 +66,9 @@ def _check_auth(self):
raise AuthException('Your authentication credentials for ' + self.name + ' are missing, check your config.')

def login(self):
if any(dict_from_cookiejar(self.session.cookies).values()):
# cloudflare leaves __cfduid cookie even if cookie is expired,
# there are 4 cookies when cookie is valid
if len(dict_from_cookiejar(self.session.cookies)) == 4:
return True

login_params = {
Expand All @@ -77,12 +80,21 @@ def login(self):
}

# Must be done twice, or it isnt really logged in
response = self.get_url(self.urls['login'], post_data=login_params, timeout=30)
# first time gets __cfduid, if we already have __cfduid this might get the cookie
response = self.get_url(self.urls['login'], post_data=login_params, timeout=30)
if not response:
logger.log(u"Unable to connect to provider", logger.WARNING)
return False

# if the first post only got the __cfduid then sleep 5 seconds for cloudflare anti-bot
# and then get the actual cookie
if len(dict_from_cookiejar(self.session.cookies)) < 4:
time.sleep(5)
response = self.get_url(self.urls['login'], post_data=login_params, timeout=30)
if not response:
logger.log(u"Unable to connect to provider", logger.WARNING)
return False

if re.search('Error: Username or password incorrect!', response):
logger.log(u"Invalid username or password. Check your settings", logger.WARNING)
return False
Expand Down

0 comments on commit 24eb637

Please sign in to comment.