Merge branch 'refs/heads/develop' into tv
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
from base64 import b16encode, b32decode
|
from base64 import b16encode, b32decode
|
||||||
|
from bencode import bencode, bdecode
|
||||||
from hashlib import sha1
|
from hashlib import sha1
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@@ -13,7 +14,6 @@ log = CPLog(__name__)
|
|||||||
|
|
||||||
autoload = 'qBittorrent'
|
autoload = 'qBittorrent'
|
||||||
|
|
||||||
|
|
||||||
class qBittorrent(Downloader):
|
class qBittorrent(Downloader):
|
||||||
|
|
||||||
protocol = ['torrent', 'torrent_magnet']
|
protocol = ['torrent', 'torrent_magnet']
|
||||||
@@ -45,7 +45,6 @@ class qBittorrent(Downloader):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def download(self, data = None, media = None, filedata = None):
|
def download(self, data = None, media = None, filedata = None):
|
||||||
if not media: media = {}
|
if not media: media = {}
|
||||||
if not data: data = {}
|
if not data: data = {}
|
||||||
@@ -59,8 +58,17 @@ class qBittorrent(Downloader):
|
|||||||
log.error('Failed sending torrent, no data')
|
log.error('Failed sending torrent, no data')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
if data.get('protocol') == 'torrent_magnet':
|
||||||
|
filedata = self.magnetToTorrent(data.get('url'))
|
||||||
|
|
||||||
|
if filedata is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
data['protocol'] = 'torrent'
|
||||||
|
|
||||||
info = bdecode(filedata)["info"]
|
info = bdecode(filedata)["info"]
|
||||||
torrent_hash = sha1(bencode(info)).hexdigest().upper()
|
torrent_hash = sha1(bencode(info)).hexdigest()
|
||||||
|
|
||||||
# Convert base 32 to hex
|
# Convert base 32 to hex
|
||||||
if len(torrent_hash) == 32:
|
if len(torrent_hash) == 32:
|
||||||
@@ -68,14 +76,7 @@ class qBittorrent(Downloader):
|
|||||||
|
|
||||||
# Send request to qBittorrent
|
# Send request to qBittorrent
|
||||||
try:
|
try:
|
||||||
if data.get('protocol') == 'torrent_magnet':
|
self.qb.add_file(filedata)
|
||||||
torrent = self.qb.add_url(filedata)
|
|
||||||
else:
|
|
||||||
torrent = self.qb.add_file(filedata)
|
|
||||||
|
|
||||||
if not torrent:
|
|
||||||
log.error('Unable to find the torrent, did it fail to load?')
|
|
||||||
return False
|
|
||||||
|
|
||||||
return self.downloadReturnId(torrent_hash)
|
return self.downloadReturnId(torrent_hash)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -100,18 +101,18 @@ class qBittorrent(Downloader):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
torrents = self.qb.get_torrents()
|
torrents = self.qb.get_torrents()
|
||||||
self.qb.update_general() # get extra info
|
|
||||||
|
|
||||||
release_downloads = ReleaseDownloadList(self)
|
release_downloads = ReleaseDownloadList(self)
|
||||||
|
|
||||||
for torrent in torrents:
|
for torrent in torrents:
|
||||||
if torrent.hash in ids:
|
if torrent.hash in ids:
|
||||||
|
torrent.update_general() # get extra info
|
||||||
torrent_files = []
|
torrent_files = []
|
||||||
t_files = torrent.get_files()
|
t_files = torrent.get_files()
|
||||||
|
|
||||||
check_dir = os.path.join(torrent.save_path, torrent.name)
|
check_dir = os.path.join(torrent.save_path, torrent.name)
|
||||||
if os.path.isdir(check_dir):
|
if os.path.isdir(check_dir):
|
||||||
torrent.save_path = os.path.isdir(check_dir)
|
torrent.save_path = check_dir
|
||||||
|
|
||||||
if len(t_files) > 1 and os.path.isdir(torrent.save_path): # multi file torrent
|
if len(t_files) > 1 and os.path.isdir(torrent.save_path): # multi file torrent
|
||||||
for root, _, files in os.walk(torrent.save_path):
|
for root, _, files in os.walk(torrent.save_path):
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from urllib import unquote
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from couchpotato.core.helpers.encoding import toUnicode
|
from couchpotato.core.helpers.encoding import toUnicode
|
||||||
from couchpotato.core.helpers.variable import natsortKey
|
from couchpotato.core.helpers.variable import natsortKey, tryInt
|
||||||
|
|
||||||
|
|
||||||
def getParams(params):
|
def getParams(params):
|
||||||
@@ -43,7 +43,7 @@ def getParams(params):
|
|||||||
|
|
||||||
return dictToList(temp)
|
return dictToList(temp)
|
||||||
|
|
||||||
|
non_decimal = re.compile(r'[^\d.]+')
|
||||||
def dictToList(params):
|
def dictToList(params):
|
||||||
|
|
||||||
if type(params) is dict:
|
if type(params) is dict:
|
||||||
@@ -53,7 +53,15 @@ def dictToList(params):
|
|||||||
convert = lambda text: int(text) if text.isdigit() else text.lower()
|
convert = lambda text: int(text) if text.isdigit() else text.lower()
|
||||||
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
|
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
|
||||||
sorted_keys = sorted(value.keys(), key = alphanum_key)
|
sorted_keys = sorted(value.keys(), key = alphanum_key)
|
||||||
new_value = [dictToList(value[k]) for k in sorted_keys]
|
|
||||||
|
all_ints = 0
|
||||||
|
for pnr in sorted_keys:
|
||||||
|
all_ints += 1 if non_decimal.sub('', pnr) == pnr else 0
|
||||||
|
|
||||||
|
if all_ints == len(sorted_keys):
|
||||||
|
new_value = [dictToList(value[k]) for k in sorted_keys]
|
||||||
|
else:
|
||||||
|
new_value = value
|
||||||
except:
|
except:
|
||||||
new_value = value
|
new_value = value
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from couchpotato import get_db, CPLog
|
from couchpotato import get_db, CPLog
|
||||||
from couchpotato.core.event import addEvent, fireEvent, fireEventAsync
|
from couchpotato.core.event import addEvent, fireEvent, fireEventAsync
|
||||||
|
from couchpotato.core.helpers.encoding import toUnicode
|
||||||
from couchpotato.core.plugins.base import Plugin
|
from couchpotato.core.plugins.base import Plugin
|
||||||
|
|
||||||
|
|
||||||
@@ -45,3 +47,53 @@ class MediaBase(Plugin):
|
|||||||
log.error('Failed creating onComplete: %s', traceback.format_exc())
|
log.error('Failed creating onComplete: %s', traceback.format_exc())
|
||||||
|
|
||||||
return notifyFront
|
return notifyFront
|
||||||
|
|
||||||
|
def getDefaultTitle(self, info, ):
|
||||||
|
|
||||||
|
# Set default title
|
||||||
|
default_title = toUnicode(info.get('title'))
|
||||||
|
titles = info.get('titles', [])
|
||||||
|
counter = 0
|
||||||
|
def_title = None
|
||||||
|
for title in titles:
|
||||||
|
if (len(default_title) == 0 and counter == 0) or len(titles) == 1 or title.lower() == toUnicode(default_title.lower()) or (toUnicode(default_title) == six.u('') and toUnicode(titles[0]) == title):
|
||||||
|
def_title = toUnicode(title)
|
||||||
|
break
|
||||||
|
counter += 1
|
||||||
|
|
||||||
|
if not def_title:
|
||||||
|
def_title = toUnicode(titles[0])
|
||||||
|
|
||||||
|
return def_title or 'UNKNOWN'
|
||||||
|
|
||||||
|
def getPoster(self, image_urls, existing_files):
|
||||||
|
image_type = 'poster'
|
||||||
|
|
||||||
|
# Remove non-existing files
|
||||||
|
file_type = 'image_%s' % image_type
|
||||||
|
|
||||||
|
# Make existing unique
|
||||||
|
unique_files = list(set(existing_files.get(file_type, [])))
|
||||||
|
|
||||||
|
# Remove files that can't be found
|
||||||
|
for ef in unique_files:
|
||||||
|
if not os.path.isfile(ef):
|
||||||
|
unique_files.remove(ef)
|
||||||
|
|
||||||
|
# Replace new files list
|
||||||
|
existing_files[file_type] = unique_files
|
||||||
|
if len(existing_files) == 0:
|
||||||
|
del existing_files[file_type]
|
||||||
|
|
||||||
|
# Loop over type
|
||||||
|
for image in image_urls.get(image_type, []):
|
||||||
|
if not isinstance(image, (str, unicode)):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if file_type not in existing_files or len(existing_files.get(file_type, [])) == 0:
|
||||||
|
file_path = fireEvent('file.download', url = image, single = True)
|
||||||
|
if file_path:
|
||||||
|
existing_files[file_type] = [file_path]
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ class Base(TorrentMagnetProvider):
|
|||||||
return tryInt(age)
|
return tryInt(age)
|
||||||
|
|
||||||
def isEnabled(self):
|
def isEnabled(self):
|
||||||
return super(KickAssTorrents, self).isEnabled() and self.getDomain()
|
return super(Base, self).isEnabled() and self.getDomain()
|
||||||
|
|
||||||
def correctProxy(self, data):
|
def correctProxy(self, data):
|
||||||
return 'search query' in data.lower()
|
return 'search query' in data.lower()
|
||||||
|
|||||||
@@ -41,11 +41,11 @@ class Base(TorrentMagnetProvider):
|
|||||||
total_pages = 1
|
total_pages = 1
|
||||||
cats = self.getCatId(quality['identifier'])
|
cats = self.getCatId(quality['identifier'])
|
||||||
|
|
||||||
search_url = self.urls['search'] % self.getDomain()
|
base_search_url = self.urls['search'] % self.getDomain()
|
||||||
|
|
||||||
while page < total_pages:
|
while page < total_pages:
|
||||||
|
|
||||||
search_url = search_url % self.buildUrl(media, page, cats)
|
search_url = base_search_url % self.buildUrl(media, page, cats)
|
||||||
|
|
||||||
page += 1
|
page += 1
|
||||||
|
|
||||||
|
|||||||
@@ -344,6 +344,7 @@
|
|||||||
top: auto;
|
top: auto;
|
||||||
right: auto;
|
right: auto;
|
||||||
color: #FFF;
|
color: #FFF;
|
||||||
|
line-height: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.touch_enabled .movies.list_list .movie .info .year {
|
.touch_enabled .movies.list_list .movie .info .year {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ from couchpotato.core.media.movie.providers.base import MovieProvider
|
|||||||
|
|
||||||
log = CPLog(__name__)
|
log = CPLog(__name__)
|
||||||
|
|
||||||
|
autoload = 'IPTorrents'
|
||||||
|
|
||||||
|
|
||||||
class IPTorrents(MovieProvider, Base):
|
class IPTorrents(MovieProvider, Base):
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ from couchpotato.core.media.movie.providers.base import MovieProvider
|
|||||||
|
|
||||||
log = CPLog(__name__)
|
log = CPLog(__name__)
|
||||||
|
|
||||||
|
autoload = 'KickAssTorrents'
|
||||||
|
|
||||||
|
|
||||||
class KickAssTorrents(MovieProvider, Base):
|
class KickAssTorrents(MovieProvider, Base):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ from couchpotato.core.media.movie.providers.base import MovieProvider
|
|||||||
|
|
||||||
log = CPLog(__name__)
|
log = CPLog(__name__)
|
||||||
|
|
||||||
|
autoload = 'PassThePopcorn'
|
||||||
|
|
||||||
|
|
||||||
class PassThePopcorn(MovieProvider, Base):
|
class PassThePopcorn(MovieProvider, Base):
|
||||||
|
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase):
|
|||||||
fireEvent('release.delete', release.get('_id'), single = True)
|
fireEvent('release.delete', release.get('_id'), single = True)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
log.info('Better quality (%s) already available or snatched for %s', (quality['label'], default_title))
|
log.info('Better quality (%s) already available or snatched for %s', (q_identifier, default_title))
|
||||||
fireEvent('media.restatus', movie['_id'])
|
fireEvent('media.restatus', movie['_id'])
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -11,3 +11,5 @@ class File(Base):
|
|||||||
self.priority = None
|
self.priority = None
|
||||||
|
|
||||||
self.is_seed = None
|
self.is_seed = None
|
||||||
|
|
||||||
|
self.size = None
|
||||||
|
|||||||
@@ -36,6 +36,21 @@ class Torrent(Base):
|
|||||||
self.comment = None
|
self.comment = None
|
||||||
self.save_path = None
|
self.save_path = None
|
||||||
|
|
||||||
|
self.eta = None
|
||||||
|
self.size = None
|
||||||
|
self.dlspeed = None
|
||||||
|
self.upspeed = None
|
||||||
|
self.nb_connections = None
|
||||||
|
self.share_ratio = None
|
||||||
|
self.piece_size = None
|
||||||
|
self.total_wasted = None
|
||||||
|
self.total_downloaded = None
|
||||||
|
self.total_uploaded = None
|
||||||
|
self.creation_date = None
|
||||||
|
self.time_elapsed = None
|
||||||
|
self.up_limit = None
|
||||||
|
self.dl_limit = None
|
||||||
|
|
||||||
#
|
#
|
||||||
# Commands
|
# Commands
|
||||||
#
|
#
|
||||||
|
|||||||
Reference in New Issue
Block a user