From 758154e87e38d75058ddfedb33b9099063596e9f Mon Sep 17 00:00:00 2001 From: rembo10 Date: Wed, 30 Apr 2014 21:00:30 -0700 Subject: [PATCH 1/9] Some initial changes for utorrent --- data/interfaces/default/config.html | 6 +- headphones/__init__.py | 5 +- headphones/utorrent.py | 95 +++++++++++++++++++++++++++++ headphones/webserve.py | 4 +- 4 files changed, 107 insertions(+), 3 deletions(-) diff --git a/data/interfaces/default/config.html b/data/interfaces/default/config.html index 3a7b4204..30589755 100644 --- a/data/interfaces/default/config.html +++ b/data/interfaces/default/config.html @@ -192,7 +192,7 @@
Torrents - Black Hole Transmission + Black Hole Transmission uTorrent
@@ -239,6 +239,10 @@
+
+ + +
diff --git a/headphones/__init__.py b/headphones/__init__.py index b354291b..2d4e9290 100644 --- a/headphones/__init__.py +++ b/headphones/__init__.py @@ -154,6 +154,7 @@ TRANSMISSION_PASSWORD = None UTORRENT_HOST = None UTORRENT_USERNAME = None UTORRENT_PASSWORD = None +UTORRENT_LABEL = None NEWZNAB = False NEWZNAB_HOST = None @@ -346,7 +347,7 @@ def initialize(): RUTRACKER, RUTRACKER_USER, RUTRACKER_PASSWORD, WHATCD, WHATCD_USERNAME, WHATCD_PASSWORD, DOWNLOAD_TORRENT_DIR, \ LIBRARYSCAN, LIBRARYSCAN_INTERVAL, DOWNLOAD_SCAN_INTERVAL, UPDATE_DB_INTERVAL, MB_IGNORE_AGE, SAB_HOST, SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, \ NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_HOST, HEADPHONES_INDEXER, NZBMATRIX, TRANSMISSION_HOST, TRANSMISSION_USERNAME, TRANSMISSION_PASSWORD, \ - UTORRENT_HOST, UTORRENT_USERNAME, UTORRENT_PASSWORD, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, NEWZNAB_ENABLED, EXTRA_NEWZNABS, \ + UTORRENT_HOST, UTORRENT_USERNAME, UTORRENT_PASSWORD, UTORRENT_LABEL, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, NEWZNAB_ENABLED, EXTRA_NEWZNABS, \ NZBSORG, NZBSORG_UID, NZBSORG_HASH, NZBSRUS, NZBSRUS_UID, NZBSRUS_APIKEY, OMGWTFNZBS, OMGWTFNZBS_UID, OMGWTFNZBS_APIKEY, \ NZB_DOWNLOADER, TORRENT_DOWNLOADER, PREFERRED_WORDS, REQUIRED_WORDS, IGNORED_WORDS, LASTFM_USERNAME, \ INTERFACE, FOLDER_PERMISSIONS, FILE_PERMISSIONS, ENCODERFOLDER, ENCODER_PATH, ENCODER, XLDPROFILE, BITRATE, SAMPLINGFREQUENCY, \ @@ -511,6 +512,7 @@ def initialize(): UTORRENT_HOST = check_setting_str(CFG, 'uTorrent', 'utorrent_host', '') UTORRENT_USERNAME = check_setting_str(CFG, 'uTorrent', 'utorrent_username', '') UTORRENT_PASSWORD = check_setting_str(CFG, 'uTorrent', 'utorrent_password', '') + UTORRENT_LABEL = check_setting_str(CFG, 'uTorrent', 'utorrent_label', '') NEWZNAB = bool(check_setting_int(CFG, 'Newznab', 'newznab', 0)) NEWZNAB_HOST = check_setting_str(CFG, 'Newznab', 'newznab_host', '') @@ -941,6 +943,7 @@ def config_write(): new_config['uTorrent']['utorrent_host'] = UTORRENT_HOST new_config['uTorrent']['utorrent_username'] = UTORRENT_USERNAME new_config['uTorrent']['utorrent_password'] = UTORRENT_PASSWORD + new_config['uTorrent']['utorrent_label'] = UTORRENT_LABEL new_config['Newznab'] = {} new_config['Newznab']['newznab'] = int(NEWZNAB) diff --git a/headphones/utorrent.py b/headphones/utorrent.py index fca5f5e3..5b870ea2 100644 --- a/headphones/utorrent.py +++ b/headphones/utorrent.py @@ -12,3 +12,98 @@ # # You should have received a copy of the GNU General Public License # along with Headphones. If not, see . + +import re +import time +import base64 +import headphones + +import simplejson as json + +from headphones import logger, notifiers, request + +# This is just a simple script to send torrents to transmission. The +# intention is to turn this into a class where we can check the state +# of the download, set the download dir, etc. +# TODO: Store the session id so we don't need to make 2 calls +# Store torrent id so we can check up on it + +def addTorrent(link): + method = 'torrent-add' + arguments = {'filename': link, 'download-dir': headphones.DOWNLOAD_TORRENT_DIR} + + response = torrentAction(method,arguments) + + if not response: + return False + + if response['result'] == 'success': + if 'torrent-added' in response['arguments']: + name = response['arguments']['torrent-added']['name'] + retid = response['arguments']['torrent-added']['id'] + elif 'torrent-duplicate' in response['arguments']: + name = response['arguments']['torrent-duplicate']['name'] + retid = response['arguments']['torrent-duplicate']['id'] + else: + name = link + retid = False + + logger.info(u"Torrent sent to Transmission successfully") + return retid + + else: + logger.info('Transmission returned status %s' % response['result']) + return False + +def getTorrentFolder(torrentid): + method = 'torrent-get' + arguments = { 'ids': torrentid, 'fields': ['name','percentDone']} + + response = torrentAction(method, arguments) + percentdone = response['arguments']['torrents'][0]['percentDone'] + torrent_folder_name = response['arguments']['torrents'][0]['name'] + + tries = 1 + + while percentdone == 0 and tries <10: + tries+=1 + time.sleep(5) + response = torrentAction(method, arguments) + percentdone = response['arguments']['torrents'][0]['percentDone'] + + torrent_folder_name = response['arguments']['torrents'][0]['name'] + + return torrent_folder_name + +def torrentAction(method, arguments): + + host = headphones.UTORRENT_HOST + username = headphones.UTORRENT_USERNAME + password = headphones.UTORRENT_PASSWORD + token = '' + + if not host.startswith('http'): + host = 'http://' + host + + if host.endswith('/'): + host = host[:-1] + + if host.endswith('/gui'): + host = host + '/' + else: + host = host + '/gui/' + + # Retrieve session id + auth = (username, password) if username and password else None + token_request = request.request_response(host + 'token.html') + token = re.findall('(.*?) Date: Wed, 30 Apr 2014 21:58:46 -0700 Subject: [PATCH 2/9] Slowly making progress --- headphones/searcher.py | 29 +++++++++++++++++++++++++++++ headphones/utorrent.py | 23 +++++++++++++++-------- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/headphones/searcher.py b/headphones/searcher.py index f4b8ada7..32aa5974 100644 --- a/headphones/searcher.py +++ b/headphones/searcher.py @@ -696,6 +696,35 @@ def send_to_downloader(data, bestqual, album): except Exception, e: logger.exception("Unhandled exception") + else: + logger.info("Sending torrent to uTorrent") + + # rutracker needs cookies to be set, pass the .torrent file instead of url + if bestqual[3] == 'rutracker.org': + file_or_url = rutracker.get_torrent(bestqual[2]) + else: + file_or_url = bestqual[2] + + torrentid = utorrent.addTorrent(file_or_url) + + if not torrentid: + logger.error("Error sending torrent to uTorrent. Are you sure it's running?") + return + + folder_name = utorrent.getTorrentFolder(torrentid) + if folder_name: + logger.info('Torrent folder name: %s' % folder_name) + else: + logger.error('Torrent folder name could not be determined') + return + + # remove temp .torrent file created above + if bestqual[3] == 'rutracker.org': + try: + shutil.rmtree(os.path.split(file_or_url)[0]) + except Exception, e: + logger.exception("Unhandled exception") + myDB = db.DBConnection() myDB.action('UPDATE albums SET status = "Snatched" WHERE AlbumID=?', [album['AlbumID']]) myDB.action('INSERT INTO snatched VALUES( ?, ?, ?, ?, DATETIME("NOW", "localtime"), ?, ?, ?)', [album['AlbumID'], bestqual[0], bestqual[1], bestqual[2], "Snatched", folder_name, kind]) diff --git a/headphones/utorrent.py b/headphones/utorrent.py index 5b870ea2..a1509a04 100644 --- a/headphones/utorrent.py +++ b/headphones/utorrent.py @@ -29,14 +29,23 @@ from headphones import logger, notifiers, request # Store torrent id so we can check up on it def addTorrent(link): - method = 'torrent-add' - arguments = {'filename': link, 'download-dir': headphones.DOWNLOAD_TORRENT_DIR} - response = torrentAction(method,arguments) + if link.startswith("magnet") or link.startswith("http") or link.endswith(".torrent"): + method = None + params = {'action':'add-url', 's':link} + files = None + else: + method = "post" + params = {'action':'add-file'} + files = {'torrent_file':{'music.torrent', link}} + + response = torrentAction(method,params,files) if not response: return False + print response + if response['result'] == 'success': if 'torrent-added' in response['arguments']: name = response['arguments']['torrent-added']['name'] @@ -75,7 +84,7 @@ def getTorrentFolder(torrentid): return torrent_folder_name -def torrentAction(method, arguments): +def torrentAction(method=None, params=None, files=None): host = headphones.UTORRENT_HOST username = headphones.UTORRENT_USERNAME @@ -98,12 +107,10 @@ def torrentAction(method, arguments): token_request = request.request_response(host + 'token.html') token = re.findall('(.*?) Date: Wed, 30 Apr 2014 22:38:20 -0700 Subject: [PATCH 3/9] fixin some bugs --- headphones/utorrent.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/headphones/utorrent.py b/headphones/utorrent.py index a1509a04..97fe1219 100644 --- a/headphones/utorrent.py +++ b/headphones/utorrent.py @@ -45,7 +45,7 @@ def addTorrent(link): return False print response - + if response['result'] == 'success': if 'torrent-added' in response['arguments']: name = response['arguments']['torrent-added']['name'] @@ -104,8 +104,8 @@ def torrentAction(method=None, params=None, files=None): # Retrieve session id auth = (username, password) if username and password else None - token_request = request.request_response(host + 'token.html') - token = re.findall('(.*?)(.*?) Date: Thu, 1 May 2014 00:02:29 -0700 Subject: [PATCH 4/9] Some changes. Getting close --- data/interfaces/default/config.html | 4 +- headphones/searcher.py | 9 +-- headphones/utorrent.py | 98 ++++++++++++----------------- 3 files changed, 43 insertions(+), 68 deletions(-) diff --git a/data/interfaces/default/config.html b/data/interfaces/default/config.html index 30589755..54f513f7 100644 --- a/data/interfaces/default/config.html +++ b/data/interfaces/default/config.html @@ -124,7 +124,7 @@
Usenet - Sabnzbd NZBget Black Hole + Sabnzbd NZBget Black Hole
@@ -192,7 +192,7 @@
Torrents - Black Hole Transmission uTorrent + Black Hole Transmission uTorrent (Beta)
diff --git a/headphones/searcher.py b/headphones/searcher.py index 32aa5974..ecc92acb 100644 --- a/headphones/searcher.py +++ b/headphones/searcher.py @@ -705,13 +705,8 @@ def send_to_downloader(data, bestqual, album): else: file_or_url = bestqual[2] - torrentid = utorrent.addTorrent(file_or_url) - - if not torrentid: - logger.error("Error sending torrent to uTorrent. Are you sure it's running?") - return - - folder_name = utorrent.getTorrentFolder(torrentid) + folder_name = utorrent.addTorrent(bestqual[2],bestqual[0]) + if folder_name: logger.info('Torrent folder name: %s' % folder_name) else: diff --git a/headphones/utorrent.py b/headphones/utorrent.py index 97fe1219..e8fb4809 100644 --- a/headphones/utorrent.py +++ b/headphones/utorrent.py @@ -14,6 +14,7 @@ # along with Headphones. If not, see . import re +import os import time import base64 import headphones @@ -28,67 +29,13 @@ from headphones import logger, notifiers, request # TODO: Store the session id so we don't need to make 2 calls # Store torrent id so we can check up on it -def addTorrent(link): - if link.startswith("magnet") or link.startswith("http") or link.endswith(".torrent"): - method = None - params = {'action':'add-url', 's':link} - files = None - else: - method = "post" - params = {'action':'add-file'} - files = {'torrent_file':{'music.torrent', link}} - - response = torrentAction(method,params,files) - - if not response: - return False - - print response - - if response['result'] == 'success': - if 'torrent-added' in response['arguments']: - name = response['arguments']['torrent-added']['name'] - retid = response['arguments']['torrent-added']['id'] - elif 'torrent-duplicate' in response['arguments']: - name = response['arguments']['torrent-duplicate']['name'] - retid = response['arguments']['torrent-duplicate']['id'] - else: - name = link - retid = False - - logger.info(u"Torrent sent to Transmission successfully") - return retid - - else: - logger.info('Transmission returned status %s' % response['result']) - return False - -def getTorrentFolder(torrentid): - method = 'torrent-get' - arguments = { 'ids': torrentid, 'fields': ['name','percentDone']} - - response = torrentAction(method, arguments) - percentdone = response['arguments']['torrents'][0]['percentDone'] - torrent_folder_name = response['arguments']['torrents'][0]['name'] - - tries = 1 - - while percentdone == 0 and tries <10: - tries+=1 - time.sleep(5) - response = torrentAction(method, arguments) - percentdone = response['arguments']['torrents'][0]['percentDone'] - - torrent_folder_name = response['arguments']['torrents'][0]['name'] - - return torrent_folder_name - -def torrentAction(method=None, params=None, files=None): +def addTorrent(link, title): host = headphones.UTORRENT_HOST username = headphones.UTORRENT_USERNAME password = headphones.UTORRENT_PASSWORD + label = headphones.UTORRENT_LABEL token = '' if not host.startswith('http'): @@ -106,11 +53,44 @@ def torrentAction(method=None, params=None, files=None): auth = (username, password) if username and password else None token_request = request.request_response(host + 'token.html', auth=auth) token = re.findall('(.*?) 1: + folder = os.path.basename(torrent[26]) + tor_hash = torrent[0] + params = {'action':'setprops', 'hash':tor_hash,'s':'label', 'v':label} + response = request.request_json(host, params=params, auth=auth, cookies=cookies) + break + else: + time.sleep(5) + tries += 1 + + return folder + + From 1f3474a1549a23b06092ecd10667de3b55350f87 Mon Sep 17 00:00:00 2001 From: rembo10 Date: Thu, 1 May 2014 00:06:25 -0700 Subject: [PATCH 5/9] bug fix --- headphones/searcher.py | 4 ++-- headphones/utorrent.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/headphones/searcher.py b/headphones/searcher.py index ecc92acb..c89720b3 100644 --- a/headphones/searcher.py +++ b/headphones/searcher.py @@ -705,8 +705,8 @@ def send_to_downloader(data, bestqual, album): else: file_or_url = bestqual[2] - folder_name = utorrent.addTorrent(bestqual[2],bestqual[0]) - + folder_name = utorrent.addTorrent(file_or_url,bestqual[0]) + if folder_name: logger.info('Torrent folder name: %s' % folder_name) else: diff --git a/headphones/utorrent.py b/headphones/utorrent.py index e8fb4809..ee14849b 100644 --- a/headphones/utorrent.py +++ b/headphones/utorrent.py @@ -84,7 +84,7 @@ def addTorrent(link, title): if torrent[2] == title and torrent[4] > 1: folder = os.path.basename(torrent[26]) tor_hash = torrent[0] - params = {'action':'setprops', 'hash':tor_hash,'s':'label', 'v':label} + params = {'action':'setprops', 'hash':tor_hash,'s':'label', 'v':label, token':token} response = request.request_json(host, params=params, auth=auth, cookies=cookies) break else: From 0c7ea8a5a0e8e38a3c6499cef0212013b9860515 Mon Sep 17 00:00:00 2001 From: rembo10 Date: Thu, 1 May 2014 00:09:45 -0700 Subject: [PATCH 6/9] typo --- headphones/utorrent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/headphones/utorrent.py b/headphones/utorrent.py index ee14849b..e11dc958 100644 --- a/headphones/utorrent.py +++ b/headphones/utorrent.py @@ -84,7 +84,7 @@ def addTorrent(link, title): if torrent[2] == title and torrent[4] > 1: folder = os.path.basename(torrent[26]) tor_hash = torrent[0] - params = {'action':'setprops', 'hash':tor_hash,'s':'label', 'v':label, token':token} + params = {'action':'setprops', 'hash':tor_hash,'s':'label', 'v':label, 'token':token} response = request.request_json(host, params=params, auth=auth, cookies=cookies) break else: From e155f19d0d2954cac875751bc422f641b37c565a Mon Sep 17 00:00:00 2001 From: rembo10 Date: Thu, 1 May 2014 00:14:10 -0700 Subject: [PATCH 7/9] Debug logging --- headphones/utorrent.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/headphones/utorrent.py b/headphones/utorrent.py index e11dc958..ce39020a 100644 --- a/headphones/utorrent.py +++ b/headphones/utorrent.py @@ -37,7 +37,7 @@ def addTorrent(link, title): password = headphones.UTORRENT_PASSWORD label = headphones.UTORRENT_LABEL token = '' - + logger.info("2") if not host.startswith('http'): host = 'http://' + host @@ -52,18 +52,22 @@ def addTorrent(link, title): # Retrieve session id auth = (username, password) if username and password else None token_request = request.request_response(host + 'token.html', auth=auth) + logger.info("3") token = re.findall('(.*?) Date: Thu, 1 May 2014 00:28:50 -0700 Subject: [PATCH 8/9] Took out debug logging, put the torrent checking in the right place --- headphones/searcher.py | 2 +- headphones/utorrent.py | 27 +++++++++++++-------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/headphones/searcher.py b/headphones/searcher.py index c89720b3..6207551e 100644 --- a/headphones/searcher.py +++ b/headphones/searcher.py @@ -31,7 +31,7 @@ import subprocess import headphones from headphones.common import USER_AGENT from headphones import logger, db, helpers, classes, sab, nzbget, request -from headphones import transmission, notifiers +from headphones import utorrent, transmission, notifiers import lib.bencode as bencode diff --git a/headphones/utorrent.py b/headphones/utorrent.py index ce39020a..ff313589 100644 --- a/headphones/utorrent.py +++ b/headphones/utorrent.py @@ -37,7 +37,7 @@ def addTorrent(link, title): password = headphones.UTORRENT_PASSWORD label = headphones.UTORRENT_LABEL token = '' - logger.info("2") + if not host.startswith('http'): host = 'http://' + host @@ -52,19 +52,16 @@ def addTorrent(link, title): # Retrieve session id auth = (username, password) if username and password else None token_request = request.request_response(host + 'token.html', auth=auth) - logger.info("3") + token = re.findall('(.*?) 1: folder = os.path.basename(torrent[26]) From 9c2da72dccd26897a2fa1c4225e39de1686376c6 Mon Sep 17 00:00:00 2001 From: rembo10 Date: Thu, 1 May 2014 01:09:26 -0700 Subject: [PATCH 9/9] Bug fixes to get utorrent working --- headphones/searcher.py | 4 ++-- headphones/utorrent.py | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/headphones/searcher.py b/headphones/searcher.py index 6207551e..42e124d8 100644 --- a/headphones/searcher.py +++ b/headphones/searcher.py @@ -705,7 +705,7 @@ def send_to_downloader(data, bestqual, album): else: file_or_url = bestqual[2] - folder_name = utorrent.addTorrent(file_or_url,bestqual[0]) + folder_name = utorrent.addTorrent(file_or_url) if folder_name: logger.info('Torrent folder name: %s' % folder_name) @@ -1450,4 +1450,4 @@ def preprocess(resultlist): logger.error("Couldn't retrieve the best nzb. Skipping.") continue - return (None, None) \ No newline at end of file + return (None, None) diff --git a/headphones/utorrent.py b/headphones/utorrent.py index ff313589..7be48355 100644 --- a/headphones/utorrent.py +++ b/headphones/utorrent.py @@ -30,7 +30,7 @@ from headphones import logger, notifiers, request # Store torrent id so we can check up on it -def addTorrent(link, title): +def addTorrent(link): host = headphones.UTORRENT_HOST username = headphones.UTORRENT_USERNAME @@ -72,27 +72,32 @@ def addTorrent(link, title): # Not really sure how to ID these? Title seems safest) # Also, not sure when the torrent will pop up in the list, so we'll make sure it exists and is 1% downloaded tries = 0 + folder = None while tries < 10: # NOW WE WILL CHECK UTORRENT FOR THE FOLDER NAME & SET THE LABEL params = {'list':'1', 'token':token} response = request.request_json(host, params=params, auth=auth, cookies=cookies) + if not response: logger.error("Error getting torrent information from uTorrent") - time.sleep(5) - continue + return for torrent in response['torrents']: - if torrent[2] == title and torrent[4] > 1: + + if torrent[19] == link and torrent[4] > 1: folder = os.path.basename(torrent[26]) tor_hash = torrent[0] params = {'action':'setprops', 'hash':tor_hash,'s':'label', 'v':label, 'token':token} response = request.request_json(host, params=params, auth=auth, cookies=cookies) break - else: - time.sleep(5) - tries += 1 + + if folder: + break + else: + time.sleep(5) + tries += 1 return folder