Browse Source

Merge branch 'develop'

pull/131/merge
Ruud 8 years ago
parent
commit
ec4259167f
  1. 14
      couchpotato/core/media/_base/providers/nzb/newznab.py
  2. 7
      couchpotato/core/media/_base/providers/torrent/bithdtv.py
  3. 3
      couchpotato/core/media/_base/providers/torrent/kickasstorrents.py
  4. 21
      couchpotato/core/media/_base/providers/torrent/thepiratebay.py
  5. 10
      couchpotato/core/media/_base/providers/torrent/yts.py
  6. 3
      couchpotato/core/media/movie/providers/info/omdbapi.py
  7. 3
      couchpotato/core/media/movie/providers/nzb/newznab.py
  8. 34
      couchpotato/core/notifications/script.py
  9. 2
      couchpotato/core/plugins/subtitle.py
  10. 3
      libs/subliminal/core.py
  11. 13
      libs/subliminal/services/subscenter.py
  12. 140
      libs/subliminal/services/thewiz.py

14
couchpotato/core/media/_base/providers/nzb/newznab.py

@ -128,6 +128,7 @@ class Base(NZBProvider, RSS):
api_keys = splitString(self.conf('api_key'), clean = False)
extra_score = splitString(self.conf('extra_score'), clean = False)
custom_tags = splitString(self.conf('custom_tag'), clean = False)
custom_categories = splitString(self.conf('custom_categories'), clean = False)
list = []
for nr in range(len(hosts)):
@ -144,12 +145,16 @@ class Base(NZBProvider, RSS):
try: custom_tag = custom_tags[nr]
except: custom_tag = ''
try: custom_category = custom_categories[nr].replace(" ", ",")
except: custom_category = ''
list.append({
'use': uses[nr],
'host': host,
'api_key': key,
'extra_score': score,
'custom_tag': custom_tag
'custom_tag': custom_tag,
'custom_category' : custom_category
})
return list
@ -266,6 +271,13 @@ config = [{
'description': 'Add custom tags, for example add rls=1 to get only scene releases from nzbs.org',
},
{
'name': 'custom_categories',
'advanced': True,
'label': 'Custom Categories',
'default': '2000,2000,2000,2000,2000,2000',
'description': 'Specify categories to search in seperated by a single space, defaults to all movies. EG: "2030 2040 2060" would only search in HD, SD, and 3D movie categories',
},
{
'name': 'api_key',
'default': ',,,,,',
'label': 'Api Key',

7
couchpotato/core/media/_base/providers/torrent/bithdtv.py

@ -42,7 +42,12 @@ class Base(TorrentProvider):
html = BeautifulSoup(data, 'html.parser')
try:
result_table = html.find('table', attrs = {'width': '750', 'class': ''})
result_tables = html.find_all('table', attrs = {'width': '750', 'class': ''})
if result_tables is None:
return
result_table = result_tables[1]
if result_table is None:
return

3
couchpotato/core/media/_base/providers/torrent/kickasstorrents.py

@ -50,8 +50,7 @@ class Base(TorrentMagnetProvider):
'https://kickass.bypassed.live',
'https://kickass.bypassed.video',
'https://kickass.bypassed.red',
'https://kat.cr',
'https://kickass.unblocked.pw/',
'https://kickass.unblocked.pw',
'https://katproxy.com'
]

21
couchpotato/core/media/_base/providers/torrent/thepiratebay.py

@ -25,35 +25,18 @@ class Base(TorrentMagnetProvider):
http_time_between_calls = 0
proxy_list = [
'https://thepiratebay.mn',
'https://thepiratebay.gd',
'https://thepiratebay.la',
'https://pirateproxy.sx',
'https://piratebay.host',
'https://thepiratebay.expert',
'https://pirateproxy.cat',
'https://pirateproxy.wf',
'https://pirateproxy.tf',
'https://urbanproxy.eu',
'https://pirate.guru',
'https://piratebays.co',
'https://pirateproxy.yt',
'https://thepiratebay.uk.net',
'https://tpb.ninja',
'https://thehiddenbay.me',
'https://ukunlocked.com',
'https://thebay.tv',
'https://tpb.freed0m4all.net',
'https://piratebays.eu',
'https://thepirateproxy.co',
'https://thepiratebayz.com',
'https://zaatoka.eu',
'https://piratemirror.net',
'https://theproxypirate.pw',
'https://torrentdr.com',
'https://tpbproxy.co',
'https://arrr.xyz',
'https://www.cleantpbproxy.com',
'http://tpb.dashitz.com',
'https://tpb.dashitz.com'
]
def __init__(self):

10
couchpotato/core/media/_base/providers/torrent/yts.py

@ -1,7 +1,6 @@
from datetime import datetime
from couchpotato.core.helpers.variable import tryInt
from couchpotato.core.helpers.variable import tryInt, getIdentifier
from couchpotato.core.logger import CPLog
from couchpotato.core.helpers.variable import getTitle
from couchpotato.core.media._base.providers.torrent.base import TorrentMagnetProvider
import random
@ -19,7 +18,7 @@ class Base(TorrentMagnetProvider):
def _search(self, movie, quality, results):
limit = 10
page = 1
data = self.getJsonData(self.urls['search'] % (getTitle(movie), limit, page))
data = self.getJsonData(self.urls['search'] % (getIdentifier(movie), limit, page))
if data:
movie_count = tryInt(data['data']['movie_count'])
@ -32,11 +31,6 @@ class Base(TorrentMagnetProvider):
for i in range(0,len(movie_results)):
result = data['data']['movies'][i]
name = result['title']
t = movie['info']['original_title'].split(' ')
if all(word in name for word in t) and movie['info']['year'] == result['year']:
year = result['year']
detail_url = result['url']

3
couchpotato/core/media/movie/providers/info/omdbapi.py

@ -88,7 +88,8 @@ class OMDBAPI(MovieProvider):
tmp_movie = movie.copy()
for key in tmp_movie:
if tmp_movie.get(key).lower() == 'n/a':
tmp_movie_elem = tmp_movie.get(key)
if not isinstance(tmp_movie_elem, str) or tmp_movie_elem.lower() == 'n/a':
del movie[key]
year = tryInt(movie.get('Year', ''))

3
couchpotato/core/media/movie/providers/nzb/newznab.py

@ -23,4 +23,7 @@ class Newznab(MovieProvider, Base):
if len(host.get('custom_tag', '')) > 0:
query = '%s&%s' % (query, host.get('custom_tag'))
if len(host['custom_category']) > 0:
query = '%s&cat=%s' % (query, host['custom_category'])
return query

34
couchpotato/core/notifications/script.py

@ -1,38 +1,48 @@
import traceback
import subprocess
import os
from couchpotato.core.helpers.encoding import toUnicode
from couchpotato.core.helpers.variable import getIdentifier
from couchpotato.api import addApiView
from couchpotato.core.event import addEvent
from couchpotato.core.logger import CPLog
from couchpotato.core.notifications.base import Notification
log = CPLog(__name__)
autoload = 'Script'
class Script(Notification):
def notify(self, message = '', data = None, listener = None):
if not data: data = {}
def __init__(self):
addApiView(self.testNotifyName(), self.test)
script_data = {
'message': toUnicode(message)
}
addEvent('renamer.after', self.runScript)
if getIdentifier(data):
script_data.update({
'imdb_id': getIdentifier(data)
})
def runScript(self, message = None, group = None):
if self.isDisabled(): return
if not group: group = {}
command = [self.conf('path'), group.get('destination_dir')]
log.info('Executing script command: %s ', command)
try:
subprocess.call([self.conf('path'), message])
p = subprocess.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
out = p.communicate()
log.info('Result from script: %s', str(out))
return True
except:
log.error('Script notification failed: %s', traceback.format_exc())
except OSError as e:
log.error('Unable to run script: %s', e)
return False
def test(self, **kwargs):
return {
'success': os.path.isfile(self.conf('path'))
}
config = [{
'name': 'script',

2
couchpotato/core/plugins/subtitle.py

@ -16,7 +16,7 @@ autoload = 'Subtitle'
class Subtitle(Plugin):
services = ['opensubtitles', 'thesubdb', 'subswiki', 'subscenter']
services = ['opensubtitles', 'thesubdb', 'subswiki', 'subscenter', 'thewiz']
def __init__(self):
addEvent('renamer.before', self.searchSingle)

3
libs/subliminal/core.py

@ -32,7 +32,8 @@ __all__ = ['SERVICES', 'LANGUAGE_INDEX', 'SERVICE_INDEX', 'SERVICE_CONFIDENCE',
'create_list_tasks', 'create_download_tasks', 'consume_task', 'matching_confidence',
'key_subtitles', 'group_by_video']
logger = logging.getLogger(__name__)
SERVICES = ['opensubtitles', 'bierdopje', 'subswiki', 'subtitulos', 'thesubdb', 'addic7ed', 'tvsubtitles', 'subscenter']
SERVICES = ['opensubtitles', 'bierdopje', 'subswiki', 'subtitulos', 'thesubdb', 'addic7ed', 'tvsubtitles',
'subscenter', 'thewiz']
LANGUAGE_INDEX, SERVICE_INDEX, SERVICE_CONFIDENCE, MATCHING_CONFIDENCE = range(4)

13
libs/subliminal/services/subscenter.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright 2012 Ofir Brukner <ofirbrukner@gmail.com>
# Copyright 2012 Ofir123 <ofirbrukner@gmail.com>
#
# This file is part of subliminal.
#
@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with subliminal. If not, see <http://www.gnu.org/licenses/>.
from . import ServiceBase
from ..exceptions import ServiceError
from ..exceptions import DownloadFailedError, ServiceError
from ..language import language_set
from ..subtitles import get_subtitle_path, ResultSubtitle
from ..videos import Episode, Movie
@ -30,7 +30,7 @@ logger = logging.getLogger(__name__)
class Subscenter(ServiceBase):
server = 'http://www.subscenter.co/he/'
server = 'http://www.subscenter.org/he/'
api_based = False
languages = language_set(['he'])
videos = [Episode, Movie]
@ -110,10 +110,11 @@ class Subscenter(ServiceBase):
# Read the item.
subtitle_id = subtitle_item['id']
subtitle_key = subtitle_item['key']
subtitle_version = subtitle_item['h_version']
release = subtitle_item['subtitle_version']
subtitle_path = get_subtitle_path(filepath, language_object, self.config.multi)
download_link = self.server_url + 'subtitle/download/{0}/{1}/?v={2}&key={3}'.format(
language_code, subtitle_id, release, subtitle_key)
language_code, subtitle_id, subtitle_version, subtitle_key)
# Add the release and increment downloaded count if we already have the subtitle.
if subtitle_id in subtitles:
logger.debug('Found additional release {0} for subtitle {1}'.format(
@ -128,7 +129,11 @@ class Subscenter(ServiceBase):
return subtitles.values()
def download(self, subtitle):
try:
self.download_zip_file(subtitle.link, subtitle.path)
except DownloadFailedError:
# If no zip file was retrieved, daily downloads limit has exceeded.
raise ServiceError('Daily limit exceeded')
return subtitle

140
libs/subliminal/services/thewiz.py

@ -0,0 +1,140 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Ofir123 <ofirbrukner@gmail.com>
#
# This file is part of subliminal.
#
# subliminal 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.
#
# subliminal 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 subliminal. If not, see <http://www.gnu.org/licenses/>.
from . import ServiceBase
from ..exceptions import ServiceError
from ..language import language_set
from ..subtitles import get_subtitle_path, ResultSubtitle
from ..videos import Episode, Movie
from ..utils import to_unicode
import bisect
import logging
import os
logger = logging.getLogger(__name__)
class TheWiz(ServiceBase):
server = 'http://subs.thewiz.info/'
api_based = True
languages = language_set(['he'])
videos = [Episode, Movie]
require_video = False
_tmdb_api_key = 'f7f51775877e0bb6703520952b3c7840'
def _search_imdb_id(self, title, year, is_movie):
"""Search the IMDB ID for the given `title` and `year`.
:param str title: title to search for.
:param int year: year to search for (or 0 if not relevant).
:param bool is_movie: If True, IMDB ID will be searched for in TMDB instead of TheWiz.
:return: the IMDB ID for the given title and year (or None if not found).
:rtype: str
"""
# make the search
logger.info('Searching IMDB ID for %r%r', title, '' if not year else ' ({})'.format(year))
title = title.replace('\'', '')
if is_movie:
# get TMDB ID first
r = self.session.get('http://api.tmdb.org/3/search/movie?api_key={}&query={}{}&language=en'.format(
self._tmdb_api_key, title, '' if not year else '&year={}'.format(year)))
r.raise_for_status()
tmdb_results = r.json().get('results')
if tmdb_results:
tmdb_id = tmdb_results[0].get('id')
if tmdb_id:
# get actual IMDB ID from TMDB
r = self.session.get('http://api.tmdb.org/3/movie/{}?api_key={}&language=en'.format(
tmdb_id, self._tmdb_api_key))
r.raise_for_status()
return str(r.json().get('imdb_id', '')) or None
return None
# handle TV series
r = self.session.get(self.server_url + 'search.tv.php', params={'name': title}, timeout=10)
r.raise_for_status()
return r.text or None
def list_checked(self, video, languages):
series = None
season = None
episode = None
title = video.title
imdb_id = video.imdbid
year = video.year
if isinstance(video, Episode):
series = video.series
season = video.season
episode = video.episode
return self.query(video.path or video.release, languages, series, season,
episode, title, imdb_id, year)
def query(self, filepath, languages=None, series=None, season=None, episode=None, title=None, imdbid=None, year=None):
logger.debug(u'Getting subtitles for {0} season {1} episode {2} with languages {3}'.format(
series, season, episode, languages))
# search for the IMDB ID if needed
is_movie = not (series and season and episode)
if is_movie and not title:
raise ServiceError('One or more parameters are missing')
# for tv series, we need the series IMDB ID, and not the specific episode ID
imdb_id = (is_movie and imdbid) or self._search_imdb_id(title, year, is_movie)
# get search parameters
season = season or 0
episode = episode or 0
version = os.path.splitext(os.path.basename(filepath))[0] if filepath else 0
# search
logger.debug(u'Using IMDB ID {0}'.format(imdb_id))
url = 'http://subs.thewiz.info/search.id.php?imdb={}&season={}&episode={}&version={}'.format(
imdb_id, season, episode, version)
# get the list of subtitles
logger.debug(u'Getting the list of subtitles')
r = self.session.get(url)
r.raise_for_status()
results = r.json()
# loop over results
subtitles = dict()
for result in results:
language_object = self.get_language('heb')
subtitle_id = result['id']
release = result['versioname']
subtitle_path = get_subtitle_path(filepath, language_object, self.config.multi)
download_link = self.server_url + 'zip/{0}.zip'.format(subtitle_id)
# add the release and increment downloaded count if we already have the subtitle
if subtitle_id in subtitles:
logger.debug(u'Found additional release {0} for subtitle {1}'.format(release, subtitle_id))
bisect.insort_left(subtitles[subtitle_id].releases, release) # deterministic order
subtitles[subtitle_id].downloaded += 1
continue
# otherwise create it
subtitle = ResultSubtitle(subtitle_path, language_object, self.__class__.__name__.lower(),
download_link, release=to_unicode(release))
logger.debug(u'Found subtitle {0}'.format(subtitle))
subtitles[subtitle_id] = subtitle
return subtitles.values()
def download(self, subtitle):
self.download_zip_file(subtitle.link, subtitle.path)
return subtitle
Service = TheWiz
Loading…
Cancel
Save