def get_torrent_info(self, filename): """ Return information about a torrent on the filesystem. :param filename: the path to the torrent :type filename: string :returns: information about the torrent: :: { "name": the torrent name, "files_tree": the files the torrent contains, "info_hash" the torrents info_hash } :rtype: dictionary """ try: torrent_info = TorrentInfo(filename.strip(), 2) return torrent_info.as_dict('name', 'info_hash', 'files_tree') except Exception as ex: log.error(ex) return False
def test_hash_optional_md5sum(self): # Ensure `md5sum` key is not included in filetree output filename = common.get_test_data_file('md5sum.torrent') files_tree = {'test': {'lol': (0, 4, True), 'rofl': (1, 5, True)}} ti = TorrentInfo(filename, filetree=1) self.assertEqual(ti.files_tree, files_tree) ti = TorrentInfo(filename, filetree=2) files_tree2 = { 'contents': { 'test': { 'type': 'dir', 'contents': { 'lol': { 'type': 'file', 'path': 'test/lol', 'index': 0, 'length': 4, 'download': True, }, 'rofl': { 'type': 'file', 'path': 'test/rofl', 'index': 1, 'length': 5, 'download': True, }, }, 'length': 9, 'download': True, } }, 'type': 'dir', } self.assertEqual(ti.files_tree, files_tree2)
def __init__(self, uri): QtGui.QListWidgetItem.__init__(self, None) if deluge.common.is_magnet(uri): # TODO: better magnet parsing s = uri.split("&")[0][20:] if len(s) == 32: self.info_hash = base64.b32decode(s).encode("hex") elif len(s) == 40: self.info_hash = s for i in uri.split("&"): if i.startswith("dn="): self.setText("%s (%s)" % (i[3:], uri)) break else: self.setText(uri) else: info = TorrentInfo(uri) self.filename = os.path.basename(uri) self.info_hash = info.info_hash self.filedata = info.filedata self.file_model = TorrentFileModel(info.files, None) self.setText(info.name) self.options = {} self.priorities = []
def check_torrent(filename): # Test loading with libtorrent to make sure it's valid from deluge._libtorrent import lt lt.torrent_info(filename) # Test loading with our internal TorrentInfo class from deluge.ui.common import TorrentInfo ti = TorrentInfo(filename)
def test_hash_optional_single_file(self): """Ensure single file with `ed2k` and `sha1` keys are not in filetree output.""" filename = common.get_test_data_file('test.torrent') files_tree = {'azcvsupdater_2.6.2.jar': (0, 307949, True)} ti = TorrentInfo(filename, filetree=1) self.assertEqual(ti.files_tree, files_tree) files_tree2 = { 'contents': { 'azcvsupdater_2.6.2.jar': { 'type': 'file', 'index': 0, 'length': 307949, 'download': True, } } } ti = TorrentInfo(filename, filetree=2) self.assertEqual(ti.files_tree, files_tree2)
def add_torrent(t_file, options, success_cb, fail_cb, ress): t_options = {} if options['path']: t_options['download_location'] = os.path.expanduser(options['path']) t_options['add_paused'] = options['add_paused'] is_url = (options['path_type'] != 1) and ( deluge.common.is_url(t_file) or options['path_type'] == 2 ) is_magnet = ( not (is_url) and (options['path_type'] != 1) and deluge.common.is_magnet(t_file) ) if is_url or is_magnet: files = [t_file] else: files = glob.glob(_bracket_fixup(t_file)) num_files = len(files) ress['total'] = num_files if num_files <= 0: fail_cb('Does not exist', t_file, ress) for f in files: if is_url: client.core.add_torrent_url(f, t_options).addCallback( success_cb, f, ress ).addErrback(fail_cb, f, ress) elif is_magnet: client.core.add_torrent_magnet(f, t_options).addCallback( success_cb, f, ress ).addErrback(fail_cb, f, ress) else: if not os.path.exists(f): fail_cb('Does not exist', f, ress) continue if not os.path.isfile(f): fail_cb('Is a directory', f, ress) continue try: TorrentInfo(f) except Exception as ex: fail_cb(ex.message, f, ress) continue filename = os.path.split(f)[-1] with open(f, 'rb') as _file: filedump = b64encode(_file.read()) client.core.add_torrent_file_async( filename, filedump, t_options ).addCallback(success_cb, f, ress).addErrback(fail_cb, f, ress)
def test_hash_optional_multi_file(self): """Ensure multi-file with `filehash` and `ed2k` are keys not in filetree output.""" filename = common.get_test_data_file('filehash_field.torrent') files_tree = { 'torrent_filehash': { 'tull.txt': (0, 54, True), '還在一個人無聊嗎~還不趕緊上來聊天美.txt': (1, 54, True), } } ti = TorrentInfo(filename, filetree=1) self.assertEqual(ti.files_tree, files_tree) filestree2 = { 'contents': { 'torrent_filehash': { 'type': 'dir', 'contents': { 'tull.txt': { 'type': 'file', 'path': 'torrent_filehash/tull.txt', 'length': 54, 'index': 0, 'download': True, }, '還在一個人無聊嗎~還不趕緊上來聊天美.txt': { 'type': 'file', 'path': 'torrent_filehash/還在一個人無聊嗎~還不趕緊上來聊天美.txt', 'length': 54, 'index': 1, 'download': True, }, }, 'length': 108, 'download': True, } }, 'type': 'dir', } ti = TorrentInfo(filename, filetree=2) self.assertEqual(ti.files_tree, filestree2)
def _on_uri_metadata(self, result, uri, trackers): """Process prefetched metadata to allow file priority selection.""" info_hash, metadata = result log.debug('magnet metadata for %s (%s)', uri, info_hash) if info_hash not in self.prefetching_magnets: return if metadata: info = TorrentInfo.from_metadata(metadata, [[t] for t in trackers]) self.files[info_hash] = info.files self.infos[info_hash] = info.filedata else: log.info('Unable to fetch metadata for magnet: %s', uri) self.prefetching_magnets.remove(info_hash) self._on_torrent_changed(self.listview_torrents.get_selection())
def test_utf8_encoded_paths2(self): if windows_check(): raise unittest.SkipTest('on windows KeyError: unicode_filenames') filename = common.get_test_data_file('unicode_filenames.torrent') filepath1 = '\u30c6\u30af\u30b9\u30fb\u30c6\u30af\u30b5\u30f3.mkv' filepath2 = ('\u041c\u0438\u0445\u0430\u0438\u043b \u0413\u043e' '\u0440\u0431\u0430\u0447\u0451\u0432.mkv') filepath3 = "Alisher ibn G'iyosiddin Navoiy.mkv" filepath4 = 'Ascii title.mkv' filepath5 = '\u09b8\u09c1\u0995\u09c1\u09ae\u09be\u09b0 \u09b0\u09be\u09df.mkv' ti = TorrentInfo(filename) files_tree = ti.files_tree['unicode_filenames'] self.assertIn(filepath1, files_tree) self.assertIn(filepath2, files_tree) self.assertIn(filepath3, files_tree) self.assertIn(filepath4, files_tree) self.assertIn(filepath5, files_tree) result_files = [ { 'download': True, 'path': 'unicode_filenames/' + filepath3, 'size': 126158658, }, { 'download': True, 'path': 'unicode_filenames/' + filepath4, 'size': 189321363, }, { 'download': True, 'path': 'unicode_filenames/' + filepath2, 'size': 106649699, }, { 'download': True, 'path': 'unicode_filenames/' + filepath5, 'size': 21590269, }, { 'download': True, 'path': 'unicode_filenames/' + filepath1, 'size': 1771 }, ] assertCountEqual(self, ti.files, result_files)
def _on_uri_metadata(self, result, uri): """Process prefetched metadata to allow file priority selection.""" info_hash, b64_metadata = result log.debug('on_uri_metadata for %s (%s)', uri, info_hash) if info_hash not in self.prefetching_magnets: return if b64_metadata: metadata = b64decode(b64_metadata) info = TorrentInfo(metadata=metadata) self.files[info_hash] = info.files self.infos[info_hash] = info.filedata else: log.info('Unable to fetch metadata for magnet: %s', uri) self.prefetching_magnets.remove(info_hash) self._on_torrent_changed(self.listview_torrents.get_selection())
def add_from_files(self, filenames): already_added = 0 for filename in filenames: # Get the torrent data from the torrent file try: info = TorrentInfo(filename) except Exception as ex: log.debug('Unable to open torrent file: %s', ex) ErrorDialog(_('Invalid File'), ex, self.dialog).run() continue if not self._add_torrent_liststore(info.info_hash, info.name, filename, info.files, info.filedata): already_added += 1 if already_added: self.show_already_added_dialog(already_added)
def add_torrent(t_file, options, success_cb, fail_cb, ress): t_options = {} if options["path"]: t_options["download_location"] = os.path.expanduser(options["path"]) t_options["add_paused"] = options["add_paused"] is_url = (not (options["path_type"]==1)) and (deluge.common.is_url(t_file) or options["path_type"]==2) is_mag = not(is_url) and (not (options["path_type"]==1)) and deluge.common.is_magnet(t_file) if is_url or is_mag: files = [t_file] else: files = glob.glob(__bracket_fixup(t_file)) num_files = len(files) ress["total"] = num_files if num_files <= 0: fail_cb("Doesn't exist",t_file,ress) for f in files: if is_url: client.core.add_torrent_url(f, t_options).addCallback(success_cb,f,ress).addErrback(fail_cb,f,ress) elif is_mag: client.core.add_torrent_magnet(f, t_options).addCallback(success_cb,f,ress).addErrback(fail_cb,f,ress) else: if not os.path.exists(f): fail_cb("Doesn't exist",f,ress) continue if not os.path.isfile(f): fail_cb("Is a directory",f,ress) continue try: TorrentInfo(f) except Exception as e: fail_cb(e.message,f,ress) continue filename = os.path.split(f)[-1] filedump = base64.encodestring(open(f).read()) client.core.add_torrent_file(filename, filedump, t_options).addCallback(success_cb,f,ress).addErrback(fail_cb,f,ress)
def test_utf8_encoded_paths2(self): filename = common.get_test_data_file('unicode_filenames.torrent') ti = TorrentInfo(filename) files = ti.files_tree['unicode_filenames'] self.assertTrue( (b'\xe3\x83\x86\xe3\x82\xaf\xe3\x82\xb9\xe3\x83\xbb\xe3\x83' b'\x86\xe3\x82\xaf\xe3\x82\xb5\xe3\x83\xb3.mkv' ).decode('utf8') in files) self.assertTrue( (b'\xd0\x9c\xd0\xb8\xd1\x85\xd0\xb0\xd0\xb8\xd0\xbb \xd0\x93' b'\xd0\xbe\xd1\x80\xd0\xb1\xd0\xb0\xd1\x87\xd1\x91\xd0\xb2.mkv' ).decode('utf8') in files) self.assertTrue( b"Alisher ibn G'iyosiddin Navoiy.mkv".decode('utf8') in files) self.assertTrue(b'Ascii title.mkv'.decode('utf8') in files) self.assertTrue(( b'\xe0\xa6\xb8\xe0\xa7\x81\xe0\xa6\x95\xe0\xa7\x81\xe0\xa6\xae\xe0\xa6\xbe' b'\xe0\xa6\xb0 \xe0\xa6\xb0\xe0\xa6\xbe\xe0\xa7\x9f.mkv' ).decode('utf8') in files)
def add_from_files(self, filenames): new_row = None already_added = 0 for filename in filenames: # Get the torrent data from the torrent file try: info = TorrentInfo(filename) except Exception as ex: log.debug('Unable to open torrent file: %s', ex) ErrorDialog(_('Invalid File'), ex, self.dialog).run() continue if info.info_hash in self.files: already_added += 1 continue new_row = self.torrent_liststore.append( [info.info_hash, info.name, xml_escape(filename)]) self.files[info.info_hash] = info.files self.infos[info.info_hash] = info.filedata self.listview_torrents.get_selection().select_iter(new_row) self.set_default_options() self.save_torrent_options(new_row) (model, row) = self.listview_torrents.get_selection().get_selected() if not row and new_row: self.listview_torrents.get_selection().select_iter(new_row) self.dialog.set_title( _('Add Torrents (%d)') % len(self.torrent_liststore)) if already_added: log.debug('Tried to add %d duplicate torrents!', already_added) ErrorDialog( _('Duplicate Torrent(s)'), _('You cannot add the same torrent twice. %d torrents were already added.' % already_added), self.dialog).run()
def test_utf8_encoded_paths(self): filename = common.get_test_data_file('test.torrent') ti = TorrentInfo(filename) self.assertTrue('azcvsupdater_2.6.2.jar' in ti.files_tree)