From e27defe769c0256ecfdbe558f1a6c1743adcfeeb Mon Sep 17 00:00:00 2001 From: Ade Date: Fri, 22 Jun 2012 23:37:38 +1200 Subject: [PATCH] Get torrent folder name from the .torrent file --- headphones/bencode.py | 131 +++++++++++++++++++++++++++++++++++++++++ headphones/searcher.py | 14 +++-- 2 files changed, 140 insertions(+), 5 deletions(-) create mode 100644 headphones/bencode.py diff --git a/headphones/bencode.py b/headphones/bencode.py new file mode 100644 index 00000000..3181ee1c --- /dev/null +++ b/headphones/bencode.py @@ -0,0 +1,131 @@ +# Got this from here: https://gist.github.com/1126793 + +# The contents of this file are subject to the Python Software Foundation +# License Version 2.3 (the License). You may not copy or use this file, in +# either source code or executable form, except in compliance with the License. +# You may obtain a copy of the License at http://www.python.org/license. +# +# Software distributed under the License is distributed on an AS IS basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. + +# Written by Petru Paler + +# Minor modifications made by Andrew Resch to replace the BTFailure errors with Exceptions + +def decode_int(x, f): + f += 1 + newf = x.index('e', f) + n = int(x[f:newf]) + if x[f] == '-': + if x[f + 1] == '0': + raise ValueError + elif x[f] == '0' and newf != f+1: + raise ValueError + return (n, newf+1) + +def decode_string(x, f): + colon = x.index(':', f) + n = int(x[f:colon]) + if x[f] == '0' and colon != f+1: + raise ValueError + colon += 1 + return (x[colon:colon+n], colon+n) + +def decode_list(x, f): + r, f = [], f+1 + while x[f] != 'e': + v, f = decode_func[x[f]](x, f) + r.append(v) + return (r, f + 1) + +def decode_dict(x, f): + r, f = {}, f+1 + while x[f] != 'e': + k, f = decode_string(x, f) + r[k], f = decode_func[x[f]](x, f) + return (r, f + 1) + +decode_func = {} +decode_func['l'] = decode_list +decode_func['d'] = decode_dict +decode_func['i'] = decode_int +decode_func['0'] = decode_string +decode_func['1'] = decode_string +decode_func['2'] = decode_string +decode_func['3'] = decode_string +decode_func['4'] = decode_string +decode_func['5'] = decode_string +decode_func['6'] = decode_string +decode_func['7'] = decode_string +decode_func['8'] = decode_string +decode_func['9'] = decode_string + +def bdecode(x): + try: + r, l = decode_func[x[0]](x, 0) + except (IndexError, KeyError, ValueError): + raise Exception("not a valid bencoded string") + + return r + +from types import StringType, IntType, LongType, DictType, ListType, TupleType + + +class Bencached(object): + + __slots__ = ['bencoded'] + + def __init__(self, s): + self.bencoded = s + +def encode_bencached(x,r): + r.append(x.bencoded) + +def encode_int(x, r): + r.extend(('i', str(x), 'e')) + +def encode_bool(x, r): + if x: + encode_int(1, r) + else: + encode_int(0, r) + +def encode_string(x, r): + r.extend((str(len(x)), ':', x)) + +def encode_list(x, r): + r.append('l') + for i in x: + encode_func[type(i)](i, r) + r.append('e') + +def encode_dict(x,r): + r.append('d') + ilist = x.items() + ilist.sort() + for k, v in ilist: + r.extend((str(len(k)), ':', k)) + encode_func[type(v)](v, r) + r.append('e') + +encode_func = {} +encode_func[Bencached] = encode_bencached +encode_func[IntType] = encode_int +encode_func[LongType] = encode_int +encode_func[StringType] = encode_string +encode_func[ListType] = encode_list +encode_func[TupleType] = encode_list +encode_func[DictType] = encode_dict + +try: + from types import BooleanType + encode_func[BooleanType] = encode_bool +except ImportError: + pass + +def bencode(x): + r = [] + encode_func[type(x)](x, r) + return ''.join(r) diff --git a/headphones/searcher.py b/headphones/searcher.py index 0ed33eaf..3f1176d8 100644 --- a/headphones/searcher.py +++ b/headphones/searcher.py @@ -11,6 +11,8 @@ import string import headphones, exceptions from headphones import logger, db, helpers, classes, sab +import bencode + class NewzbinDownloader(urllib.FancyURLopener): def __init__(self): @@ -879,15 +881,17 @@ def searchTorrent(albumid=None, new=False, losslessOnly=False): elif headphones.TORRENTBLACKHOLE_DIR != "": + # Get torrent name from .torrent, this is usually used by the torrent client as the folder name + torrent_name = torrent_folder_name + '.torrent' download_path = os.path.join(headphones.TORRENTBLACKHOLE_DIR, torrent_name) try: - f = open(download_path, 'wb') - f.write(data) - f.close() - logger.info('File saved to: %s' % torrent_name) + torrent_file = open(download_path, 'rb').read() + torrent_info = bencode.bdecode(torrent_file) + torrent_folder_name = torrent_info['info'].get('name','') + logger.info('Torrent folder name: %s' % torrent_folder_name) except Exception, e: - logger.error('Couldn\'t write Torrent file: %s' % e) + logger.error('Couldn\'t get name from Torrent file: %s' % e) break myDB.action('UPDATE albums SET status = "Snatched" WHERE AlbumID=?', [albums[2]])