Add name to torrent options

This commit is contained in:
Calum Lind 2014-02-14 14:58:41 +00:00
parent 0aed074796
commit 7dceb629ca
3 changed files with 84 additions and 25 deletions

View File

@ -46,6 +46,7 @@ import logging
import pkg_resources import pkg_resources
import gettext import gettext
import locale import locale
import base64
try: try:
import json import json
@ -499,6 +500,48 @@ def is_magnet(uri):
return True return True
return False return False
def get_magnet_info(uri):
"""
Return information about a magnet link.
:param uri: the magnet link
:type uri: string
:returns: information about the magnet link:
::
{
"name": the torrent name,
"info_hash": the torrents info_hash,
"files_tree": empty value for magnet links
}
:rtype: dictionary
"""
magnet_scheme = 'magnet:?'
xt_param = 'xt=urn:btih:'
dn_param = 'dn='
if uri.startswith(magnet_scheme):
name = None
info_hash = None
for param in uri[len(magnet_scheme):].split('&'):
if param.startswith(xt_param):
xt_hash = param[len(xt_param):]
if len(xt_hash) == 32:
info_hash = base64.b32decode(xt_hash).encode("hex")
elif len(xt_hash) == 40:
info_hash = xt_hash
else:
break
elif param.startswith(dn_param):
name = unquote_plus(param[len(dn_param):])
if info_hash:
if not name:
name = info_hash
return {"name":name, "info_hash":info_hash, "files_tree":''}
return False
def create_magnet_uri(infohash, name=None, trackers=[]): def create_magnet_uri(infohash, name=None, trackers=[]):
""" """

View File

@ -111,6 +111,7 @@ class TorrentOptions(dict):
file_priorities (list of int): The priority for files in torrent, range is [0..7] however file_priorities (list of int): The priority for files in torrent, range is [0..7] however
only [0, 1, 5, 7] are normally used and correspond to [Do Not Download, Normal, High, Highest] only [0, 1, 5, 7] are normally used and correspond to [Do Not Download, Normal, High, Highest]
mapped_files (dict): A mapping of the renamed filenames in 'index:filename' pairs. mapped_files (dict): A mapping of the renamed filenames in 'index:filename' pairs.
name (str): The name of the torrent
''' '''
def __init__(self): def __init__(self):
config = ConfigManager("core.conf").config config = ConfigManager("core.conf").config
@ -139,6 +140,7 @@ class TorrentOptions(dict):
self["file_priorities"] = [] self["file_priorities"] = []
self["mapped_files"] = {} self["mapped_files"] = {}
self["owner"] = None self["owner"] = None
self["name"] = None
class Torrent(object): class Torrent(object):
@ -252,19 +254,20 @@ class Torrent(object):
options = options.copy() options = options.copy()
# set_prioritize_first_last is called by set_file_priorities so only run if not in options # set_prioritize_first_last is called by set_file_priorities so only run if not in options
skip_func = []
if "file_priorities" in options: if "file_priorities" in options:
self.options["prioritize_first_last_pieces"] = options["prioritize_first_last_pieces"] self.options["prioritize_first_last_pieces"] = options["prioritize_first_last_pieces"]
del options["prioritize_first_last_pieces"] skip_func.append("prioritize_first_last_pieces")
for key, value in options.items(): for key, value in options.items():
if key in self.options: if key in self.options:
options_set_func = getattr(self, "set_" + key, None) options_set_func = getattr(self, "set_" + key, None)
if options_set_func: if options_set_func and key not in skip_func:
options_set_func(value) options_set_func(value)
del options[key] del options[key]
else: else:
# Update config options that do not have funcs # Update config options that do not have funcs
self.options.update({key:value}) self.options[key] = value
def get_options(self): def get_options(self):
return self.options return self.options
@ -724,6 +727,22 @@ class Torrent(object):
return status_dict return status_dict
def get_name(self):
''' Return the name of the torrent
Can be set through options
:return: the name
:rtype: str
'''
if not self.options['name']:
handle_name = self.handle.name()
if handle_name:
return decode_string(handle_name)
else:
return self.torrent_id
else:
return self.options['name']
def update_status(self, status): def update_status(self, status):
""" """
Updates the cached status. Updates the cached status.
@ -812,24 +831,6 @@ class Torrent(object):
"priority": lambda: self.status.priority, "priority": lambda: self.status.priority,
} }
def get_name(self):
if self.has_metadata:
name = self.torrent_info.file_at(0).path.replace("\\", "/", 1).split("/", 1)[0]
if not name:
name = self.torrent_info.name()
return decode_string(name)
elif self.magnet:
try:
keys = dict([k.split('=') for k in self.magnet.split('?')[-1].split('&')])
name = keys.get('dn')
if not name:
return self.torrent_id
name = unquote(name).replace('+', ' ')
return decode_string(name)
except:
pass
return self.torrent_id
def pause(self): def pause(self):
"""Pause this torrent""" """Pause this torrent"""
# Turn off auto-management so the torrent will not be unpaused by lt queueing # Turn off auto-management so the torrent will not be unpaused by lt queueing

View File

@ -57,7 +57,7 @@ import deluge.component as component
from deluge.configmanager import ConfigManager, get_config_dir from deluge.configmanager import ConfigManager, get_config_dir
from deluge.core.authmanager import AUTH_LEVEL_ADMIN from deluge.core.authmanager import AUTH_LEVEL_ADMIN
from deluge.core.torrent import Torrent, TorrentOptions, sanitize_filepath from deluge.core.torrent import Torrent, TorrentOptions, sanitize_filepath
from deluge.common import utf8_encoded, decode_string from deluge.common import utf8_encoded, decode_string, get_magnet_info
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -89,7 +89,8 @@ class TorrentState:
owner=None, owner=None,
shared=False, shared=False,
super_seeding=False, super_seeding=False,
priority=0 priority=0,
name=None
): ):
self.torrent_id = torrent_id self.torrent_id = torrent_id
self.filename = filename self.filename = filename
@ -119,6 +120,7 @@ class TorrentState:
self.super_seeding = super_seeding self.super_seeding = super_seeding
self.priority = priority self.priority = priority
self.owner = owner self.owner = owner
self.name = name
class TorrentManagerState: class TorrentManagerState:
def __init__(self): def __init__(self):
@ -358,6 +360,7 @@ class TorrentManager(component.Component):
options["super_seeding"] = state.super_seeding options["super_seeding"] = state.super_seeding
options["priority"] = state.priority options["priority"] = state.priority
options["owner"] = state.owner options["owner"] = state.owner
options["name"] = state.name
torrent_info = self.get_torrent_info_from_file( torrent_info = self.get_torrent_info_from_file(
os.path.join(self.state_dir, state.torrent_id + ".torrent")) os.path.join(self.state_dir, state.torrent_id + ".torrent"))
@ -457,7 +460,18 @@ class TorrentManager(component.Component):
add_torrent_params["flags"] |= lt.add_torrent_params_flags_t.flag_seed_mode add_torrent_params["flags"] |= lt.add_torrent_params_flags_t.flag_seed_mode
if magnet: if magnet:
add_torrent_params["url"] = utf8_encoded(magnet) magnet_info = get_magnet_info(magnet)
if magnet_info:
add_torrent_params['url'] = utf8_encoded(magnet)
add_torrent_params['name'] = magnet_info['name']
if options['name']:
add_torrent_params['name'] = options['name']
elif torrent_info:
name = torrent_info.name()
if not name:
name = torrent_info.file_at(0).path.replace("\\", "/", 1).split("/", 1)[0]
add_torrent_params['name'] = name
# We need to pause the AlertManager momentarily to prevent alerts # We need to pause the AlertManager momentarily to prevent alerts
# for this torrent being generated before a Torrent object is created. # for this torrent being generated before a Torrent object is created.
@ -698,7 +712,8 @@ class TorrentManager(component.Component):
torrent.options["owner"], torrent.options["owner"],
torrent.options["shared"], torrent.options["shared"],
torrent.options["super_seeding"], torrent.options["super_seeding"],
torrent.options["priority"] torrent.options["priority"],
torrent.options["name"]
) )
state.torrents.append(torrent_state) state.torrents.append(torrent_state)