Merge branch 'refs/heads/develop'
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
config = {
|
||||
config = [{
|
||||
'name': 'download_providers',
|
||||
'groups': [
|
||||
{
|
||||
@@ -10,4 +10,4 @@ config = {
|
||||
'options': [],
|
||||
},
|
||||
],
|
||||
}
|
||||
}]
|
||||
|
||||
@@ -136,11 +136,11 @@ class Transmission(Downloader):
|
||||
|
||||
def removeFailed(self, item):
|
||||
log.info('%s failed downloading, deleting...', item['name'])
|
||||
return self.trpc.remove_torrent(item['hashString'], True)
|
||||
return self.trpc.remove_torrent(item['id'], True)
|
||||
|
||||
def processComplete(self, item, delete_files = False):
|
||||
log.debug('Requesting Transmission to remove the torrent %s%s.', (item['name'], ' and cleanup the downloaded files' if delete_files else ''))
|
||||
return self.trpc.remove_torrent(item['hashString'], delete_files)
|
||||
return self.trpc.remove_torrent(item['id'], delete_files)
|
||||
|
||||
class TransmissionRPC(object):
|
||||
|
||||
|
||||
@@ -107,9 +107,9 @@ class uTorrent(Downloader):
|
||||
|
||||
count += 1
|
||||
# Check if torrent is saved in subfolder of torrent name
|
||||
data = self.utorrent_api.get_files(torrent_hash)
|
||||
getfiles_data = self.utorrent_api.get_files(torrent_hash)
|
||||
|
||||
torrent_files = json.loads(data)
|
||||
torrent_files = json.loads(getfiles_data)
|
||||
if torrent_files.get('error'):
|
||||
log.error('Error getting data from uTorrent: %s', torrent_files.get('error'))
|
||||
return False
|
||||
@@ -200,7 +200,7 @@ class uTorrent(Downloader):
|
||||
if not self.connect():
|
||||
return False
|
||||
return self.utorrent_api.remove_torrent(item['id'], remove_data = delete_files)
|
||||
|
||||
|
||||
def removeReadOnly(self, folder):
|
||||
#Removes all read-only flags in a folder
|
||||
if folder and os.path.isdir(folder):
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from couchpotato.core.event import fireEvent
|
||||
from couchpotato.core.logger import CPLog
|
||||
import glob
|
||||
import os
|
||||
import traceback
|
||||
|
||||
@@ -81,17 +80,10 @@ class Loader(object):
|
||||
def addFromDir(self, plugin_type, priority, module, dir_name):
|
||||
|
||||
# Load dir module
|
||||
try:
|
||||
m = __import__(module)
|
||||
splitted = module.split('.')
|
||||
for sub in splitted[1:]:
|
||||
m = getattr(m, sub)
|
||||
except:
|
||||
raise
|
||||
self.addModule(priority, plugin_type, module, os.path.basename(dir_name))
|
||||
|
||||
for cur_file in glob.glob(os.path.join(dir_name, '*')):
|
||||
name = os.path.basename(cur_file)
|
||||
if os.path.isdir(os.path.join(dir_name, name)) and name != 'static' and os.path.isfile(os.path.join(cur_file, '__init__.py')):
|
||||
for name in os.listdir(dir_name):
|
||||
if os.path.isdir(os.path.join(dir_name, name)) and name != 'static' and os.path.isfile(os.path.join(dir_name, name, '__init__.py')):
|
||||
module_name = '%s.%s' % (module, name)
|
||||
self.addModule(priority, plugin_type, module_name, name)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
config = {
|
||||
config = [{
|
||||
'name': 'notification_providers',
|
||||
'groups': [
|
||||
{
|
||||
@@ -10,4 +10,4 @@ config = {
|
||||
'options': [],
|
||||
},
|
||||
],
|
||||
}
|
||||
}]
|
||||
|
||||
@@ -2,6 +2,7 @@ from couchpotato.core.helpers.encoding import toUnicode
|
||||
from couchpotato.core.helpers.variable import splitString
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.notifications.base import Notification
|
||||
from couchpotato.environment import Env
|
||||
from email.mime.text import MIMEText
|
||||
import smtplib
|
||||
import traceback
|
||||
@@ -23,7 +24,7 @@ class Email(Notification):
|
||||
smtp_pass = self.conf('smtp_pass')
|
||||
|
||||
# Make the basic message
|
||||
message = MIMEText(toUnicode(message))
|
||||
message = MIMEText(toUnicode(message), _charset = Env.get('encoding'))
|
||||
message['Subject'] = self.default_title
|
||||
message['From'] = from_address
|
||||
message['To'] = to_address
|
||||
|
||||
Regular → Executable
+8
-3
@@ -17,10 +17,15 @@ config = [{
|
||||
'type': 'enabler',
|
||||
},
|
||||
{
|
||||
'name': 'host',
|
||||
'name': 'media_server',
|
||||
'label': 'Media Server',
|
||||
'default': 'localhost',
|
||||
'description': 'Default should be on localhost',
|
||||
'advanced': True,
|
||||
'description': 'Hostname/IP, default localhost'
|
||||
},
|
||||
{
|
||||
'name': 'clients',
|
||||
'default': '',
|
||||
'description': 'Comma separated list of client names\'s (computer names). Top right when you start Plex'
|
||||
},
|
||||
{
|
||||
'name': 'on_snatch',
|
||||
|
||||
Regular → Executable
+155
-54
@@ -1,79 +1,184 @@
|
||||
from couchpotato.core.event import addEvent
|
||||
from couchpotato.core.helpers.encoding import tryUrlencode
|
||||
from couchpotato.core.helpers.variable import cleanHost, splitString
|
||||
from couchpotato.core.helpers.variable import cleanHost
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.notifications.base import Notification
|
||||
from urllib2 import URLError
|
||||
from datetime import datetime
|
||||
from urlparse import urlparse
|
||||
from xml.dom import minidom
|
||||
import json
|
||||
import requests
|
||||
import traceback
|
||||
|
||||
try:
|
||||
import xml.etree.cElementTree as etree
|
||||
except ImportError:
|
||||
import xml.etree.ElementTree as etree
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
|
||||
class Plex(Notification):
|
||||
|
||||
client_update_time = 5 * 60
|
||||
http_time_between_calls = 0
|
||||
|
||||
def __init__(self):
|
||||
super(Plex, self).__init__()
|
||||
|
||||
self.clients = {}
|
||||
self.clients_updated = None
|
||||
|
||||
addEvent('renamer.after', self.addToLibrary)
|
||||
|
||||
def addToLibrary(self, message = None, group = None):
|
||||
def updateClients(self, force = False):
|
||||
if not self.conf('media_server'):
|
||||
log.warning("Plex media server hostname is required")
|
||||
return
|
||||
|
||||
since_update = ((datetime.now() - self.clients_updated).total_seconds())\
|
||||
if self.clients_updated is not None else None
|
||||
|
||||
if force or self.clients_updated is None or since_update > self.client_update_time:
|
||||
self.clients = {}
|
||||
|
||||
data = self.urlopen('%s/clients' % self.createHost(self.conf('media_server'), port = 32400))
|
||||
client_result = etree.fromstring(data)
|
||||
|
||||
clients = [x.strip().lower() for x in self.conf('clients').split(',')]
|
||||
|
||||
for server in client_result.findall('Server'):
|
||||
if server.get('name').lower() in clients:
|
||||
clients.remove(server.get('name').lower())
|
||||
protocol = server.get('protocol', 'xbmchttp')
|
||||
|
||||
if protocol in ['xbmcjson', 'xbmchttp']:
|
||||
self.clients[server.get('name')] = {
|
||||
'name': server.get('name'),
|
||||
'address': server.get('address'),
|
||||
'port': server.get('port'),
|
||||
'protocol': protocol
|
||||
}
|
||||
|
||||
if len(clients) > 0:
|
||||
log.info2('Unable to find plex clients: %s', ', '.join(clients))
|
||||
|
||||
log.info2('Found hosts: %s', ', '.join(self.clients.keys()))
|
||||
|
||||
self.clients_updated = datetime.now()
|
||||
|
||||
|
||||
def addToLibrary(self, message = None, group = {}):
|
||||
if self.isDisabled(): return
|
||||
if not group: group = {}
|
||||
|
||||
log.info('Sending notification to Plex')
|
||||
hosts = self.getHosts(port = 32400)
|
||||
|
||||
for host in hosts:
|
||||
source_type = ['movie']
|
||||
base_url = '%s/library/sections' % self.createHost(self.conf('media_server'), port = 32400)
|
||||
refresh_url = '%s/%%s/refresh' % base_url
|
||||
|
||||
source_type = ['movie']
|
||||
base_url = '%s/library/sections' % host
|
||||
refresh_url = '%s/%%s/refresh' % base_url
|
||||
try:
|
||||
sections_xml = self.urlopen(base_url)
|
||||
xml_sections = minidom.parseString(sections_xml)
|
||||
sections = xml_sections.getElementsByTagName('Directory')
|
||||
|
||||
try:
|
||||
sections_xml = self.urlopen(base_url)
|
||||
xml_sections = minidom.parseString(sections_xml)
|
||||
sections = xml_sections.getElementsByTagName('Directory')
|
||||
for s in sections:
|
||||
if s.getAttribute('type') in source_type:
|
||||
url = refresh_url % s.getAttribute('key')
|
||||
x = self.urlopen(url)
|
||||
|
||||
for s in sections:
|
||||
if s.getAttribute('type') in source_type:
|
||||
url = refresh_url % s.getAttribute('key')
|
||||
self.urlopen(url)
|
||||
|
||||
except:
|
||||
log.error('Plex library update failed for %s, Media Server not running: %s', (host, traceback.format_exc(1)))
|
||||
return False
|
||||
except:
|
||||
log.error('Plex library update failed for %s, Media Server not running: %s',
|
||||
(self.conf('media_server'), traceback.format_exc(1)))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def notify(self, message = '', data = None, listener = None):
|
||||
if not data: data = {}
|
||||
def sendHTTP(self, command, client):
|
||||
url = 'http://%s:%s/xbmcCmds/xbmcHttp/?%s' % (
|
||||
client['address'],
|
||||
client['port'],
|
||||
tryUrlencode(command)
|
||||
)
|
||||
|
||||
hosts = self.getHosts(port = 3000)
|
||||
successful = 0
|
||||
for host in hosts:
|
||||
if self.send({'command': 'ExecBuiltIn', 'parameter': 'Notification(CouchPotato, %s)' % message}, host):
|
||||
successful += 1
|
||||
|
||||
return successful == len(hosts)
|
||||
|
||||
def send(self, command, host):
|
||||
|
||||
url = '%s/xbmcCmds/xbmcHttp/?%s' % (host, tryUrlencode(command))
|
||||
headers = {}
|
||||
|
||||
try:
|
||||
self.urlopen(url, headers = headers, show_error = False)
|
||||
except URLError:
|
||||
log.error("Couldn't sent command to Plex, probably just running Media Server")
|
||||
return False
|
||||
except:
|
||||
log.error("Couldn't sent command to Plex: %s", traceback.format_exc())
|
||||
self.urlopen(url, headers = headers, timeout = 3, show_error = False)
|
||||
except Exception, err:
|
||||
log.error("Couldn't sent command to Plex: %s", err)
|
||||
return False
|
||||
|
||||
log.info('Plex notification to %s successful.', host)
|
||||
return True
|
||||
|
||||
def notifyHTTP(self, message = '', data = {}, listener = None):
|
||||
total = 0
|
||||
successful = 0
|
||||
|
||||
data = {
|
||||
'command': 'ExecBuiltIn',
|
||||
'parameter': 'Notification(CouchPotato, %s)' % message
|
||||
}
|
||||
|
||||
for name, client in self.clients.items():
|
||||
if client['protocol'] == 'xbmchttp':
|
||||
total += 1
|
||||
if self.sendHTTP(data, client):
|
||||
successful += 1
|
||||
|
||||
return successful == total
|
||||
|
||||
def sendJSON(self, method, params, client):
|
||||
log.debug('sendJSON("%s", %s, %s)', (method, params, client))
|
||||
url = 'http://%s:%s/jsonrpc' % (
|
||||
client['address'],
|
||||
client['port']
|
||||
)
|
||||
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
request = {
|
||||
'id':1,
|
||||
'jsonrpc': '2.0',
|
||||
'method': method,
|
||||
'params': params
|
||||
}
|
||||
|
||||
try:
|
||||
requests.post(url, headers = headers, timeout = 3, data = json.dumps(request))
|
||||
except Exception, err:
|
||||
log.error("Couldn't sent command to Plex: %s", err)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def notifyJSON(self, message = '', data = {}, listener = None):
|
||||
total = 0
|
||||
successful = 0
|
||||
|
||||
params = {
|
||||
'title': 'CouchPotato',
|
||||
'message': message
|
||||
}
|
||||
|
||||
for name, client in self.clients.items():
|
||||
if client['protocol'] == 'xbmcjson':
|
||||
total += 1
|
||||
if self.sendJSON('GUI.ShowNotification', params, client):
|
||||
successful += 1
|
||||
|
||||
return successful == total
|
||||
|
||||
def notify(self, message = '', data = {}, listener = None, force = False):
|
||||
self.updateClients(force)
|
||||
|
||||
http_result = self.notifyHTTP(message, data, listener)
|
||||
json_result = self.notifyJSON(message, data, listener)
|
||||
|
||||
return http_result and json_result
|
||||
|
||||
def test(self, **kwargs):
|
||||
|
||||
test_type = self.testNotifyName()
|
||||
@@ -83,7 +188,8 @@ class Plex(Notification):
|
||||
success = self.notify(
|
||||
message = self.test_message,
|
||||
data = {},
|
||||
listener = 'test'
|
||||
listener = 'test',
|
||||
force = True
|
||||
)
|
||||
success2 = self.addToLibrary()
|
||||
|
||||
@@ -91,17 +197,12 @@ class Plex(Notification):
|
||||
'success': success or success2
|
||||
}
|
||||
|
||||
def getHosts(self, port = None):
|
||||
def createHost(self, host, port = None):
|
||||
|
||||
raw_hosts = splitString(self.conf('host'))
|
||||
hosts = []
|
||||
h = cleanHost(host)
|
||||
p = urlparse(h)
|
||||
h = h.rstrip('/')
|
||||
if port and not p.port:
|
||||
h += ':%s' % port
|
||||
|
||||
for h in raw_hosts:
|
||||
h = cleanHost(h)
|
||||
p = urlparse(h)
|
||||
h = h.rstrip('/')
|
||||
if port and not p.port:
|
||||
h += ':%s' % port
|
||||
hosts.append(h)
|
||||
|
||||
return hosts
|
||||
return h
|
||||
|
||||
@@ -121,7 +121,7 @@ class Plugin(object):
|
||||
|
||||
# http request
|
||||
def urlopen(self, url, timeout = 30, params = None, headers = None, opener = None, multipart = False, show_error = True):
|
||||
url = ss(url)
|
||||
url = urllib2.quote(ss(url), safe = "%/:=&?~#+!$,;'@()*[]")
|
||||
|
||||
if not headers: headers = {}
|
||||
if not params: params = {}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from couchpotato import get_session
|
||||
from couchpotato.api import addApiView
|
||||
from couchpotato.core.event import addEvent
|
||||
from couchpotato.core.helpers.encoding import toUnicode
|
||||
from couchpotato.core.helpers.encoding import toUnicode, ss
|
||||
from couchpotato.core.helpers.variable import mergeDicts, md5, getExt
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.plugins.base import Plugin
|
||||
@@ -192,15 +192,19 @@ class QualityPlugin(Plugin):
|
||||
return None
|
||||
|
||||
def containsTag(self, quality, words, cur_file = ''):
|
||||
cur_file = ss(cur_file)
|
||||
|
||||
# Check alt and tags
|
||||
for tag_type in ['alternative', 'tags']:
|
||||
for alt in quality.get(tag_type, []):
|
||||
if isinstance(alt, tuple) and '.'.join(alt) in '.'.join(words):
|
||||
for tag_type in ['alternative', 'tags', 'label']:
|
||||
qualities = quality.get(tag_type, [])
|
||||
qualities = [qualities] if isinstance(qualities, (str, unicode)) else qualities
|
||||
|
||||
for alt in qualities:
|
||||
if (isinstance(alt, tuple) and '.'.join(alt) in '.'.join(words)) or (isinstance(alt, (str, unicode)) and ss(alt.lower()) in cur_file.lower()):
|
||||
log.debug('Found %s via %s %s in %s', (quality['identifier'], tag_type, quality.get(tag_type), cur_file))
|
||||
return True
|
||||
|
||||
if list(set(quality.get(tag_type, [])) & set(words)):
|
||||
if list(set(qualities) & set(words)):
|
||||
log.debug('Found %s via %s %s in %s', (quality['identifier'], tag_type, quality.get(tag_type), cur_file))
|
||||
return True
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from couchpotato import get_session
|
||||
from couchpotato.core.event import fireEvent, addEvent
|
||||
from couchpotato.core.helpers.encoding import toUnicode, simplifyString, ss
|
||||
from couchpotato.core.helpers.variable import getExt, getImdb, tryInt
|
||||
from couchpotato.core.helpers.variable import getExt, getImdb, tryInt, \
|
||||
splitString
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.plugins.base import Plugin
|
||||
from couchpotato.core.settings.model import File, Movie
|
||||
@@ -741,9 +742,14 @@ class Scanner(Plugin):
|
||||
|
||||
def createStringIdentifier(self, file_path, folder = '', exclude_filename = False):
|
||||
|
||||
identifier = file_path.replace(folder, '') # root folder
|
||||
year = self.findYear(file_path)
|
||||
|
||||
identifier = file_path.replace(folder, '').lstrip(os.path.sep) # root folder
|
||||
identifier = os.path.splitext(identifier)[0] # ext
|
||||
|
||||
path_split = splitString(identifier, os.path.sep)
|
||||
identifier = path_split[-2] if len(path_split) > 1 and len(path_split[-2]) > len(path_split[-1]) else path_split[-1] # Only get filename
|
||||
|
||||
if exclude_filename:
|
||||
identifier = identifier[:len(identifier) - len(os.path.split(identifier)[-1])]
|
||||
|
||||
@@ -757,7 +763,6 @@ class Scanner(Plugin):
|
||||
identifier = re.sub(self.clean, '::', simplifyString(identifier)).strip(':')
|
||||
|
||||
# Year
|
||||
year = self.findYear(identifier)
|
||||
if year and identifier[:4] != year:
|
||||
identifier = '%s %s' % (identifier.split(year)[0].strip(), year)
|
||||
else:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
config = {
|
||||
config = [{
|
||||
'name': 'automation_providers',
|
||||
'groups': [
|
||||
{
|
||||
@@ -18,4 +18,4 @@ config = {
|
||||
'options': [],
|
||||
},
|
||||
],
|
||||
}
|
||||
}]
|
||||
|
||||
@@ -18,6 +18,13 @@ config = [{
|
||||
'default': False,
|
||||
'type': 'enabler',
|
||||
},
|
||||
{
|
||||
'name': 'backlog',
|
||||
'advanced': True,
|
||||
'description': 'Parses the history until the minimum movie year is reached. (Will be disabled once it has completed)',
|
||||
'default': False,
|
||||
'type': 'bool',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from bs4 import BeautifulSoup
|
||||
from couchpotato.core.helpers.rss import RSS
|
||||
from couchpotato.core.helpers.variable import tryInt
|
||||
from couchpotato.core.logger import CPLog
|
||||
@@ -10,11 +11,49 @@ class Bluray(Automation, RSS):
|
||||
|
||||
interval = 1800
|
||||
rss_url = 'http://www.blu-ray.com/rss/newreleasesfeed.xml'
|
||||
backlog_url = 'http://www.blu-ray.com/movies/movies.php?show=newreleases&page=%s'
|
||||
|
||||
def getIMDBids(self):
|
||||
|
||||
movies = []
|
||||
|
||||
if self.conf('backlog'):
|
||||
|
||||
page = 0
|
||||
while True:
|
||||
page = page + 1
|
||||
|
||||
url = self.backlog_url % page
|
||||
data = self.getHTMLData(url)
|
||||
soup = BeautifulSoup(data)
|
||||
|
||||
try:
|
||||
# Stop if the release year is before the minimal year
|
||||
page_year = soup.body.find_all('center')[3].table.tr.find_all('td', recursive = False)[3].h3.get_text().split(', ')[1]
|
||||
if tryInt(page_year) < self.getMinimal('year'):
|
||||
break
|
||||
|
||||
for table in soup.body.find_all('center')[3].table.tr.find_all('td', recursive = False)[3].find_all('table')[1:20]:
|
||||
name = table.h3.get_text().lower().split('blu-ray')[0].strip()
|
||||
year = table.small.get_text().split('|')[1].strip()
|
||||
|
||||
if not name.find('/') == -1: # make sure it is not a double movie release
|
||||
continue
|
||||
|
||||
if tryInt(year) < self.getMinimal('year'):
|
||||
continue
|
||||
|
||||
imdb = self.search(name, year)
|
||||
|
||||
if imdb:
|
||||
if self.isMinimalMovie(imdb):
|
||||
movies.append(imdb['imdb'])
|
||||
except:
|
||||
log.debug('Error loading page: %s', page)
|
||||
break
|
||||
|
||||
self.conf('backlog', value = False)
|
||||
|
||||
rss_movies = self.getRSSData(self.rss_url)
|
||||
|
||||
for movie in rss_movies:
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
from .main import Flixster
|
||||
|
||||
def start():
|
||||
return Flixster()
|
||||
|
||||
config = [{
|
||||
'name': 'flixster',
|
||||
'groups': [
|
||||
{
|
||||
'tab': 'automation',
|
||||
'list': 'watchlist_providers',
|
||||
'name': 'flixster_automation',
|
||||
'label': 'Flixster',
|
||||
'description': 'Import movies from any public <a href="http://www.flixster.com/">Flixster</a> watchlist',
|
||||
'options': [
|
||||
{
|
||||
'name': 'automation_enabled',
|
||||
'default': False,
|
||||
'type': 'enabler',
|
||||
},
|
||||
{
|
||||
'name': 'automation_ids_use',
|
||||
'label': 'Use',
|
||||
},
|
||||
{
|
||||
'name': 'automation_ids',
|
||||
'label': 'User ID',
|
||||
'type': 'combined',
|
||||
'combine': ['automation_ids_use', 'automation_ids'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}]
|
||||
@@ -0,0 +1,48 @@
|
||||
from couchpotato.core.helpers.variable import tryInt, splitString
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.providers.automation.base import Automation
|
||||
import json
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
|
||||
class Flixster(Automation):
|
||||
|
||||
url = 'http://www.flixster.com/api/users/%s/movies/ratings?scoreTypes=wts'
|
||||
|
||||
interval = 60
|
||||
|
||||
def getIMDBids(self):
|
||||
|
||||
ids = splitString(self.conf('automation_ids'))
|
||||
|
||||
if len(ids) == 0:
|
||||
return []
|
||||
|
||||
movies = []
|
||||
|
||||
for movie in self.getWatchlist():
|
||||
imdb_id = self.search(movie.get('title'), movie.get('year'), imdb_only = True)
|
||||
movies.append(imdb_id)
|
||||
|
||||
return movies
|
||||
|
||||
def getWatchlist(self):
|
||||
|
||||
enablers = [tryInt(x) for x in splitString(self.conf('automation_ids_use'))]
|
||||
ids = splitString(self.conf('automation_ids'))
|
||||
|
||||
index = -1
|
||||
movies = []
|
||||
for user_id in ids:
|
||||
|
||||
index += 1
|
||||
if not enablers[index]:
|
||||
continue
|
||||
|
||||
data = json.loads(self.getHTMLData(self.url % user_id))
|
||||
|
||||
for movie in data:
|
||||
movies.append({'title': movie['movie']['title'], 'year': movie['movie']['year'] })
|
||||
|
||||
return movies
|
||||
@@ -1,4 +1,4 @@
|
||||
config = {
|
||||
config = [{
|
||||
'name': 'nzb_providers',
|
||||
'groups': [
|
||||
{
|
||||
@@ -11,4 +11,4 @@ config = {
|
||||
'options': [],
|
||||
},
|
||||
],
|
||||
}
|
||||
}]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
config = {
|
||||
config = [{
|
||||
'name': 'torrent_providers',
|
||||
'groups': [
|
||||
{
|
||||
@@ -11,4 +11,4 @@ config = {
|
||||
'options': [],
|
||||
},
|
||||
],
|
||||
}
|
||||
}]
|
||||
|
||||
@@ -15,7 +15,7 @@ class TorrentShack(TorrentProvider):
|
||||
'login' : 'https://torrentshack.net/login.php',
|
||||
'login_check': 'https://torrentshack.net/inbox.php',
|
||||
'detail' : 'https://torrentshack.net/torrent/%s',
|
||||
'search' : 'https://torrentshack.net/torrents.php?searchstr=%s&filter_cat[%d]=1',
|
||||
'search' : 'https://torrentshack.net/torrents.php?action=advanced&searchstr=%s&scene=%s&filter_cat[%d]=1',
|
||||
'download' : 'https://torrentshack.net/%s',
|
||||
}
|
||||
|
||||
@@ -31,7 +31,9 @@ class TorrentShack(TorrentProvider):
|
||||
|
||||
def _searchOnTitle(self, title, movie, quality, results):
|
||||
|
||||
url = self.urls['search'] % (tryUrlencode('"%s" %s' % (title.replace(':', ''), movie['library']['year'])), self.getCatId(quality['identifier'])[0])
|
||||
scene_only = '1' if self.conf('scene_only') else ''
|
||||
|
||||
url = self.urls['search'] % (tryUrlencode('%s %s' % (title.replace(':', ''), movie['library']['year'])), scene_only, self.getCatId(quality['identifier'])[0])
|
||||
data = self.getHTMLData(url, opener = self.login_opener)
|
||||
|
||||
if data:
|
||||
@@ -49,22 +51,15 @@ class TorrentShack(TorrentProvider):
|
||||
link = result.find('span', attrs = {'class' : 'torrent_name_link'}).parent
|
||||
url = result.find('td', attrs = {'class' : 'torrent_td'}).find('a')
|
||||
|
||||
extra_info = ''
|
||||
if result.find('span', attrs = {'class' : 'torrent_extra_info'}):
|
||||
extra_info = result.find('span', attrs = {'class' : 'torrent_extra_info'}).text
|
||||
|
||||
if not self.conf('scene_only') or extra_info != '[NotScene]':
|
||||
results.append({
|
||||
'id': link['href'].replace('torrents.php?torrentid=', ''),
|
||||
'name': unicode(link.span.string).translate({ord(u'\xad'): None}),
|
||||
'url': self.urls['download'] % url['href'],
|
||||
'detail_url': self.urls['download'] % link['href'],
|
||||
'size': self.parseSize(result.find_all('td')[4].string),
|
||||
'seeders': tryInt(result.find_all('td')[6].string),
|
||||
'leechers': tryInt(result.find_all('td')[7].string),
|
||||
})
|
||||
else:
|
||||
log.info('Not adding release %s [NotScene]' % unicode(link.span.string).translate({ord(u'\xad'): None}))
|
||||
results.append({
|
||||
'id': link['href'].replace('torrents.php?torrentid=', ''),
|
||||
'name': unicode(link.span.string).translate({ord(u'\xad'): None}),
|
||||
'url': self.urls['download'] % url['href'],
|
||||
'detail_url': self.urls['download'] % link['href'],
|
||||
'size': self.parseSize(result.find_all('td')[4].string),
|
||||
'seeders': tryInt(result.find_all('td')[6].string),
|
||||
'leechers': tryInt(result.find_all('td')[7].string),
|
||||
})
|
||||
|
||||
except:
|
||||
log.error('Failed to parsing %s: %s', (self.getName(), traceback.format_exc()))
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import platform
|
||||
|
||||
from collections import defaultdict
|
||||
from itertools import imap
|
||||
@@ -23,22 +24,48 @@ class DelugeClient(object):
|
||||
self._request_counter = 0
|
||||
|
||||
def _get_local_auth(self):
|
||||
xdg_config = os.path.expanduser(os.environ.get("XDG_CONFIG_HOME", "~/.config"))
|
||||
config_home = os.path.join(xdg_config, "deluge")
|
||||
auth_file = os.path.join(config_home, "auth")
|
||||
|
||||
auth_file = ""
|
||||
username = password = ""
|
||||
with open(auth_file) as fd:
|
||||
for line in fd:
|
||||
if platform.system() in ('Windows', 'Microsoft'):
|
||||
appDataPath = os.environ.get("APPDATA")
|
||||
if not appDataPath:
|
||||
import _winreg
|
||||
hkey = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders")
|
||||
appDataReg = _winreg.QueryValueEx(hkey, "AppData")
|
||||
appDataPath = appDataReg[0]
|
||||
_winreg.CloseKey(hkey)
|
||||
|
||||
auth_file = os.path.join(appDataPath, "deluge", "auth")
|
||||
else:
|
||||
from xdg.BaseDirectory import save_config_path
|
||||
try:
|
||||
auth_file = os.path.join(save_config_path("deluge"), "auth")
|
||||
except OSError, e:
|
||||
return username, password
|
||||
|
||||
|
||||
if os.path.exists(auth_file):
|
||||
for line in open(auth_file):
|
||||
if line.startswith("#"):
|
||||
# This is a comment line
|
||||
continue
|
||||
line = line.strip()
|
||||
try:
|
||||
lsplit = line.split(":")
|
||||
except Exception, e:
|
||||
continue
|
||||
|
||||
auth = line.split(":")
|
||||
if len(auth) >= 2 and auth[0] == "localclient":
|
||||
username, password = auth[0], auth[1]
|
||||
break
|
||||
if len(lsplit) == 2:
|
||||
username, password = lsplit
|
||||
elif len(lsplit) == 3:
|
||||
username, password, level = lsplit
|
||||
else:
|
||||
continue
|
||||
|
||||
return username, password
|
||||
if username == "localclient":
|
||||
return (username, password)
|
||||
|
||||
return ("", "")
|
||||
|
||||
def _create_module_method(self, module, method):
|
||||
fullname = "{0}.{1}".format(module, method)
|
||||
|
||||
Reference in New Issue
Block a user