diff --git a/couchpotato/core/downloaders/rtorrent/__init__.py b/couchpotato/core/downloaders/rtorrent/__init__.py
index 4a593fd2..f793cad1 100755
--- a/couchpotato/core/downloaders/rtorrent/__init__.py
+++ b/couchpotato/core/downloaders/rtorrent/__init__.py
@@ -31,8 +31,8 @@ config = [{
{
'name': 'host',
'default': 'localhost:80',
- 'description': 'Hostname with port or XML-RPC Endpoint URI. Usually scgi://localhost:5000 '
- 'or localhost:80'
+ 'description': 'RPC Communication URI. Usually scgi://localhost:5000, '
+ 'httprpc://localhost/rutorrent or localhost:80'
},
{
'name': 'ssl',
@@ -46,7 +46,7 @@ config = [{
'type': 'string',
'default': 'RPC2',
'advanced': True,
- 'description': 'Change if you don\'t run rTorrent RPC at the default url.',
+ 'description': 'Change if your RPC mount is at a different path.',
},
{
'name': 'username',
diff --git a/couchpotato/core/downloaders/rtorrent/main.py b/couchpotato/core/downloaders/rtorrent/main.py
index 12aba510..8e21e7fc 100755
--- a/couchpotato/core/downloaders/rtorrent/main.py
+++ b/couchpotato/core/downloaders/rtorrent/main.py
@@ -1,14 +1,15 @@
-from base64 import b16encode, b32decode
-from bencode import bencode, bdecode
from couchpotato.core.downloaders.base import Downloader, ReleaseDownloadList
from couchpotato.core.event import fireEvent, addEvent
from couchpotato.core.helpers.encoding import sp
from couchpotato.core.helpers.variable import cleanHost, splitString
from couchpotato.core.logger import CPLog
+from base64 import b16encode, b32decode
+from bencode import bencode, bdecode
from datetime import timedelta
from hashlib import sha1
from rtorrent import RTorrent
from rtorrent.err import MethodError
+from urlparse import urlparse
import os
from scandir import scandir
@@ -52,7 +53,12 @@ class rTorrent(Downloader):
if self.rt is not None:
return self.rt
- url = cleanHost(self.conf('host'), protocol = True, ssl = self.conf('ssl')) + self.conf('rpc_url')
+ url = cleanHost(self.conf('host'), protocol = True, ssl = self.conf('ssl'))
+ parsed = urlparse(url)
+
+ # rpc_url is only used on http/https scgi pass-through
+ if parsed.scheme in ['http', 'https']:
+ url += self.conf('rpc_url')
if self.conf('username') and self.conf('password'):
self.rt = RTorrent(
@@ -169,6 +175,21 @@ class rTorrent(Downloader):
log.error('Failed to send torrent to rTorrent: %s', err)
return False
+ def getTorrentStatus(self, torrent):
+ if torrent.hashing or torrent.hash_checking or torrent.message:
+ return 'busy'
+
+ if not torrent.complete:
+ return 'busy'
+
+ if not torrent.open:
+ return 'completed'
+
+ if torrent.state and torrent.active:
+ return 'seeding'
+
+ return 'busy'
+
def getAllDownloadStatus(self, ids):
log.debug('Checking rTorrent download status.')
@@ -193,17 +214,10 @@ class rTorrent(Downloader):
torrent_files.append(sp(file_path))
- status = 'busy'
- if torrent.complete:
- if torrent.active:
- status = 'seeding'
- else:
- status = 'completed'
-
release_downloads.append({
'id': torrent.info_hash,
'name': torrent.name,
- 'status': status,
+ 'status': self.getTorrentStatus(torrent),
'seed_ratio': torrent.ratio,
'original_status': torrent.state,
'timeleft': str(timedelta(seconds = float(torrent.left_bytes) / torrent.down_rate)) if torrent.down_rate > 0 else -1,
diff --git a/couchpotato/core/notifications/pushbullet/main.py b/couchpotato/core/notifications/pushbullet/main.py
index 15120f0b..487fb3aa 100644
--- a/couchpotato/core/notifications/pushbullet/main.py
+++ b/couchpotato/core/notifications/pushbullet/main.py
@@ -1,5 +1,5 @@
from couchpotato.core.helpers.encoding import toUnicode
-from couchpotato.core.helpers.variable import tryInt
+from couchpotato.core.helpers.variable import splitString
from couchpotato.core.logger import CPLog
from couchpotato.core.notifications.base import Notification
import base64
@@ -32,7 +32,7 @@ class Pushbullet(Notification):
response = self.request(
'pushes',
cache = False,
- device_id = device,
+ device_iden = device,
type = 'note',
title = self.default_title,
body = toUnicode(message)
@@ -46,24 +46,7 @@ class Pushbullet(Notification):
return successful == len(devices)
def getDevices(self):
- devices = [d.strip() for d in self.conf('devices').split(',')]
-
- # Remove empty items
- devices = [d for d in devices if len(d)]
-
- # Break on any ids that aren't integers
- valid_devices = []
-
- for device_id in devices:
- d = tryInt(device_id, None)
-
- if not d:
- log.error('Device ID "%s" is not valid', device_id)
- return None
-
- valid_devices.append(d)
-
- return valid_devices
+ return splitString(self.conf('devices'))
def request(self, method, cache = True, **kwargs):
try:
diff --git a/couchpotato/core/providers/torrent/passthepopcorn/main.py b/couchpotato/core/providers/torrent/passthepopcorn/main.py
index 21bfa72e..bc6136fc 100644
--- a/couchpotato/core/providers/torrent/passthepopcorn/main.py
+++ b/couchpotato/core/providers/torrent/passthepopcorn/main.py
@@ -89,11 +89,11 @@ class PassThePopcorn(TorrentProvider):
if 'GoldenPopcorn' in torrent and torrent['GoldenPopcorn']:
torrentdesc += ' HQ'
if self.conf('prefer_golden'):
- torrentscore += 200
+ torrentscore += 5000
if 'Scene' in torrent and torrent['Scene']:
torrentdesc += ' Scene'
if self.conf('prefer_scene'):
- torrentscore += 50
+ torrentscore += 2000
if 'RemasterTitle' in torrent and torrent['RemasterTitle']:
torrentdesc += self.htmlToASCII(' %s' % torrent['RemasterTitle'])
diff --git a/couchpotato/core/providers/torrent/sceneaccess/main.py b/couchpotato/core/providers/torrent/sceneaccess/main.py
index dcf0b351..8db1b4ef 100644
--- a/couchpotato/core/providers/torrent/sceneaccess/main.py
+++ b/couchpotato/core/providers/torrent/sceneaccess/main.py
@@ -40,7 +40,7 @@ class SceneAccess(TorrentProvider):
arguments = tryUrlencode({
'search': movie['identifier'],
- 'method': 1,
+ 'method': 3,
})
url = "%s&%s" % (url, arguments)
diff --git a/couchpotato/core/providers/torrent/yify/main.py b/couchpotato/core/providers/torrent/yify/main.py
index 00d67eb0..080e6e36 100644
--- a/couchpotato/core/providers/torrent/yify/main.py
+++ b/couchpotato/core/providers/torrent/yify/main.py
@@ -18,9 +18,9 @@ class Yify(TorrentMagnetProvider):
proxy_list = [
'http://yify.unlocktorrent.com',
- 'http://yify.ftwnet.co.uk',
'http://yify-torrents.com.come.in',
'http://yts.re',
+ 'http://yts.im'
'https://yify-torrents.im',
]
diff --git a/libs/rtorrent/__init__.py b/libs/rtorrent/__init__.py
index 2c0f3fa9..4aec991e 100755
--- a/libs/rtorrent/__init__.py
+++ b/libs/rtorrent/__init__.py
@@ -22,8 +22,8 @@ import os.path
import time
import xmlrpclib
-from rtorrent.common import find_torrent, \
- is_valid_port, convert_version_tuple_to_str
+from rtorrent.common import find_torrent, join_uri, \
+ update_uri, is_valid_port, convert_version_tuple_to_str
from rtorrent.lib.torrentparser import TorrentParser
from rtorrent.lib.xmlrpc.http import HTTPServerProxy
from rtorrent.lib.xmlrpc.scgi import SCGIServerProxy
@@ -48,18 +48,18 @@ class RTorrent:
def __init__(self, uri, username=None, password=None,
verify=False, sp=None, sp_kwargs=None):
- self.uri = uri # : From X{__init__(self, url)}
+ self.uri = self._transform_uri(uri) # : From X{__init__(self, url)}
self.username = username
self.password = password
- self.schema = urllib.splittype(uri)[0]
+ self.scheme = urllib.splittype(self.uri)[0]
if sp:
self.sp = sp
- elif self.schema in ['http', 'https']:
+ elif self.scheme in ['http', 'https']:
self.sp = HTTPServerProxy
- elif self.schema == 'scgi':
+ elif self.scheme == 'scgi':
self.sp = SCGIServerProxy
else:
raise NotImplementedError()
@@ -74,10 +74,23 @@ class RTorrent:
if verify is True:
self._verify_conn()
+ def _transform_uri(self, uri):
+ scheme = urllib.splittype(uri)[0]
+
+ if scheme == 'httprpc' or scheme.startswith('httprpc+'):
+ # Try find HTTPRPC transport (token after '+' in 'httprpc+https'), otherwise assume HTTP
+ transport = scheme[scheme.index('+') + 1:] if '+' in scheme else 'http'
+
+ # Transform URI with new path and scheme
+ uri = join_uri(uri, 'plugins/httprpc/action.php', construct=False)
+ return update_uri(uri, scheme=transport)
+
+ return uri
+
def _get_conn(self):
"""Get ServerProxy instance"""
if self.username is not None and self.password is not None:
- if self.schema == 'scgi':
+ if self.scheme == 'scgi':
raise NotImplementedError()
return self.sp(
diff --git a/libs/rtorrent/common.py b/libs/rtorrent/common.py
index 371c71c3..668865b0 100755
--- a/libs/rtorrent/common.py
+++ b/libs/rtorrent/common.py
@@ -17,7 +17,8 @@
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
+import urlparse
+import os
from rtorrent.compat import is_py3
@@ -84,3 +85,67 @@ def safe_repr(fmt, *args, **kwargs):
return out.encode("utf-8")
else:
return fmt.format(*args, **kwargs)
+
+
+def split_path(path):
+ fragments = path.split('/')
+
+ if len(fragments) == 1:
+ return fragments
+
+ if not fragments[-1]:
+ return fragments[:-1]
+
+ return fragments
+
+
+def join_path(base, path):
+ # Return if we have a new absolute path
+ if os.path.isabs(path):
+ return path
+
+ # non-absolute base encountered
+ if base and not os.path.isabs(base):
+ raise NotImplementedError()
+
+ return '/'.join(split_path(base) + split_path(path))
+
+
+def join_uri(base, uri, construct=True):
+ p_uri = urlparse.urlparse(uri)
+
+ # Return if there is nothing to join
+ if not p_uri.path:
+ return base
+
+ scheme, netloc, path, params, query, fragment = urlparse.urlparse(base)
+
+ # Switch to 'uri' parts
+ _, _, _, params, query, fragment = p_uri
+
+ path = join_path(path, p_uri.path)
+
+ result = urlparse.ParseResult(scheme, netloc, path, params, query, fragment)
+
+ if not construct:
+ return result
+
+ # Construct from parts
+ return urlparse.urlunparse(result)
+
+
+def update_uri(uri, construct=True, **kwargs):
+ if isinstance(uri, urlparse.ParseResult):
+ uri = dict(uri._asdict())
+
+ if type(uri) is not dict:
+ raise ValueError("Unknown URI type")
+
+ uri.update(kwargs)
+
+ result = urlparse.ParseResult(**uri)
+
+ if not construct:
+ return result
+
+ return urlparse.urlunparse(result)