def add(self, data, download_dir=None): """ Add a torrent to the client :param data: Torrent data to load in :type data: TorrentData :param download_dir: Path on deluge server to store download :type download_dir: basestring :return: Status of successful load (according to deluge) :rtype: bool """ try: torrent = Torrent.from_str(data.torrent_data) try: self.torrent_status(torrent.info_hash) except KeyError: pass else: self.log.warn("Tried to load duplicate info hash: {}".format( torrent.info_hash)) return True torrent_data = b64encode(data.torrent_data) res = self.client.add_torrent(torrent_data, download_dir=download_dir) except TransmissionError as err: try: msg = err._message except AttributeError: msg = err.message if "duplicate torrent" in msg: self.log.warning("Tried to add duplicate torrent file") return True self.log.exception(err) return False return res
def parse_entry(self, session, entry): """ Parse RSS entry data for qualified torrents to download :param session: DB Session :type session: sqlalchemy.orm.session.Session :param entry: RSS Feed entry data :type entry: dict :return: A parsed release object ready to load into backend client or None on fail :rtype: release.TorrentData, None """ release_name = entry.get('title', "") if not release_name: self.log.warning("No title parsed from RSS feed. Malformed?") return False release_info = parser.parse_release(release_name) if not release_info.release_key: self.log.warning("No release key parsed from release name: {}".format(release_name)) return False release_key = release_info.release_key section_name = parser.validate_section(release_info) if not section_name or section_name == "section_movie": return False if self.exists(session, release_key) and not self.is_replacement(release_info): return False torrent_data = net.http_request(entry['link'], json=False) if not torrent_data: self.log.error("Failed to download torrent data from server: {0}".format(entry['link'])) return False data = release.TorrentData(bytes(release_name), torrent_data, section_name), release_info torrent = Torrent.from_str(torrent_data) if not parser.valid_size(torrent, section_name): return False return data
def add(self, data, download_dir=None): """ Add a torrent to the client :param data: Torrent data to load in :type data: TorrentData :param download_dir: Path on deluge server to store download :type download_dir: basestring :return: Status of successful load (according to deluge) :rtype: bool """ try: torrent = Torrent.from_str(data.torrent_data) try: self.torrent_status(torrent.info_hash) except KeyError: pass else: self.log.warn("Tried to load duplicate info hash: {}".format(torrent.info_hash)) return True torrent_data = b64encode(data.torrent_data) res = self.client.add_torrent(torrent_data, download_dir=download_dir) except TransmissionError as err: try: msg = err._message except AttributeError: msg = err.message if "duplicate torrent" in msg: self.log.warning("Tried to add duplicate torrent file") return True self.log.exception(err) return False return res
def add(self, data, download_dir=None): try: torrent = Torrent.from_str(data) try: self.torrent_status(torrent.info_hash) except KeyError: pass else: self.log.warn("Tried to load duplicate info hash: {}".format(torrent.info_hash)) return True encoded_data = b64encode(data) res = self.client.add(encoded_data, download_dir=download_dir) except TransmissionError as err: try: msg = err._message except AttributeError: msg = err.message if "duplicate torrent" in msg: self.log.warning("Tried to add duplicate torrent file") return True self.log.exception(err) return False return res
def add(self, torrent, download_dir=None): payload = xmlrpclib.Binary(torrent.torrent_data) info_hash = Torrent.from_str(torrent.torrent_data).info_hash.upper() # Make sure the xml-rpc size limit doesnt overflow self._server.set_xmlrpc_size_limit(len(torrent.torrent_data) * 2) self._server.load_raw(payload) if download_dir: self._server.d.set_directory_base(info_hash, download_dir) self._server.d.start(info_hash) return True
def add(self, torrent, download_dir=None): payload = xmlrpc.client.Binary(torrent.torrent_data) info_hash = Torrent.from_str(torrent.torrent_data).info_hash.upper() # Make sure the xml-rpc size limit doesnt overflow self._server.set_xmlrpc_size_limit(len(torrent.torrent_data) * 2) self._server.load_raw(payload) if download_dir: self._server.d.set_directory_base(info_hash, download_dir) self._server.d.start(info_hash) return True
def test_valid_size(self): t = Torrent.from_file(get_fixture("linux-iso.torrent")) section_name = "section_movie" config.set(section_name, "size_min", 1) config.set(section_name, "size_max", 10000) self.assertTrue(parser.valid_size(t, section_name)) config.set(section_name, "size_max", 400) self.assertFalse(parser.valid_size(t, section_name)) config.set(section_name, "size_min", 7000) config.set(section_name, "size_max", 10000) self.assertFalse(parser.valid_size(t, section_name))
def fetch_releases(self, session, scene_only=True): """ Generator which yields torrent data to be loaded into backend daemons :param session: :type session: sqlalchemy.orm.session.Session :param scene_only: Only fetch scene releases :type scene_only: bool :return: Matched Downloaded torrents :rtype: TorrentData[] """ found = [] try: releases = list(self.get_torrents_browse(50)['torrents'].values()) except (TypeError, KeyError) as err: self.log.debug("Failed to fetch releases") else: if scene_only: releases = [ rls for rls in releases if rls['Origin'] == "Scene" ] for entry in releases: release_name = entry['ReleaseName'] release_info = parser.parse_release( release_name, guess_type=constants.MEDIA_TV) if not release_info: continue section_name = parser.validate_section(release_info) if not section_name: continue if self.exists(session, release_info.release_key ) and not self.is_replacement(release_info): continue #dl_url = self.get_torrent_url(entry['TorrentID']) torrent_data = net.http_request(entry['DownloadURL'], json=False) if not torrent_data: self.log.error( "Failed to download torrent data from server: {0}". format(entry['link'])) continue data = release.TorrentData(str(release_name), torrent_data, section_name) torrent = Torrent.from_str(torrent_data) if not parser.valid_size(torrent, section_name): continue yield data, release_info
def parse_entry(self, session, entry): """ Parse RSS entry data for qualified torrents to download :param session: DB Session :type session: sqlalchemy.orm.session.Session :param entry: RSS Feed entry data :type entry: dict :return: A parsed release object ready to load into backend client or None on fail :rtype: release.TorrentData, None """ release_name = entry.get('title', "") if not release_name: self.log.warning("No title parsed from RSS feed. Malformed?") return False release_info = parser.parse_release(release_name) if not release_info.release_key: self.log.warning( "No release key parsed from release name: {}".format( release_name)) return False release_key = release_info.release_key section_name = parser.validate_section(release_info) if not section_name or section_name == "section_movie": return False if self.exists(session, release_key) and not self.is_replacement(release_info): return False torrent_data = net.http_request(entry['link'], json=False) if not torrent_data: self.log.error( "Failed to download torrent data from server: {0}".format( entry['link'])) return False data = release.TorrentData(bytes(release_name), torrent_data, section_name), release_info torrent = Torrent.from_str(torrent_data) if not parser.valid_size(torrent, section_name): return False return data
def add_torrents_from_cli(args): """ Parse command line args and try to load torrent files found :param args: :type args: :return: :rtype: """ try: if len(args) <= 1: raise ConfigError("! Not enough arguments") torrent_data = [] for torrent in args[1:]: try: torrent_data.append(open(torrent, 'r').read()) except IOError as err: pass if len(torrent_data) != len(args[1:]): raise ConfigError("! Failed to locate any files") except (ConfigError, Exception) as err: print(err) return 1 else: if torrent_data: client = init_client() print("> Connected to {}".format(client)) for raw_torrent in torrent_data: torrent_struct = Torrent.from_str(raw_torrent) print("-> {} @ {}".format( torrent_struct['info']['name'].decode('utf8'), torrent_struct.size(human=True))) if client.add(raw_torrent): print("--> Upload successful") return 0 else: print("--> Upload failed") return 1
def fetch_releases(self, session, scene_only=True): """ Generator which yields torrent data to be loaded into backend daemons :param session: :type session: sqlalchemy.orm.session.Session :param scene_only: Only fetch scene releases :type scene_only: bool :return: Matched Downloaded torrents :rtype: TorrentData[] """ found = [] try: releases = self.get_torrents_browse(50)['torrents'].values() except (TypeError, KeyError) as err: self.log.debug("Failed to fetch releases") else: if scene_only: releases = [rls for rls in releases if rls['Origin'] == "Scene"] for entry in releases: release_name = entry['ReleaseName'] release_info = parser.parse_release(release_name, guess_type=constants.MEDIA_TV) if not release_info: continue section_name = parser.validate_section(release_info) if not section_name: continue if self.exists(session, release_info.release_key) and not self.is_replacement(release_info): continue #dl_url = self.get_torrent_url(entry['TorrentID']) torrent_data = net.http_request(entry['DownloadURL'], json=False) if not torrent_data: self.log.error("Failed to download torrent data from server: {0}".format(entry['link'])) continue data = release.TorrentData(str(release_name), torrent_data, section_name) torrent = Torrent.from_str(torrent_data) if not parser.valid_size(torrent, section_name): continue yield data, release_info
def add_torrents_from_cli(args): """ Parse command line args and try to load torrent files found :param args: :type args: :return: :rtype: """ try: if len(args) <= 1: raise ConfigError("! Not enough arguments") torrent_data = [] for torrent in args[1:]: try: torrent_data.append(open(torrent, 'r').read()) except IOError as err: pass if len(torrent_data) != len(args[1:]): raise ConfigError("! Failed to locate any files") except (ConfigError, Exception) as err: print(err) return 1 else: if torrent_data: client = init_client() print("> Connected to {}".format(client)) for raw_torrent in torrent_data: torrent_struct = Torrent.from_str(raw_torrent) print("-> {} @ {}".format(torrent_struct['info']['name'].decode('utf8'), torrent_struct.size(human=True))) if client.add(raw_torrent): print("--> Upload successful") return 0 else: print("--> Upload failed") return 1
class TorrentTests(TrannyTestCase): live_test = False test_file_1 = get_fixture('linux-iso.torrent') test_file_2 = get_fixture('linux-iso-2.torrent') test_file_3 = get_fixture('linux-iso-3.torrent') torrent = Torrent.from_file(test_file_1) torrent2 = Torrent.from_file(test_file_2) torrent3 = Torrent.from_file(test_file_3) def sleep_live(self, t): if self.live_test: time.sleep(t) def _wipe_all(self): try: for torrent in self.client.torrent_list(): self.client.torrent_remove(torrent.info_hash, remove_data=True) except: pass def make_client(self): raise NotImplementedError("") def setUp(self): self.client = self.make_client() self.client_name = self.client.config_key.split("_")[1] self._wipe_all() def tearDown(self): self._wipe_all() time.sleep(1) def test_client_version(self): with client_env(self.track("torrent_version"), self.live_test): ver = self.client.client_version() num, rev = ver.split(" ") self.assertTrue(float(int(rev[1:][:-1])) > 2) self.assertTrue(rev > 10000) def test_torrent_add(self): with client_env(self.track("torrent_add_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_add_b"), self.live_test): torrent = self.client.torrent_status(self.torrent.info_hash) self.assertEqual(torrent.info_hash, self.torrent.info_hash) def test_current_speeds(self): with client_env(self.track("torrent_current_speeds"), self.live_test): speed = self.client.current_speeds() self.assertTrue(len(speed) == 2) self.assertGreaterEqual(speed[0], 0) self.assertGreaterEqual(speed[1], 0) def test_torrent_peers(self): with client_env(self.track("torrent_peers_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) self.sleep_live(10) with client_env(self.track("torrent_peers_b"), self.live_test): peers = self.client.torrent_peers(self.torrent.info_hash) self.assertTrue(len(peers) > 0) self.assertSetEqual({'client', 'down_speed', 'ip', 'progress', 'up_speed', 'country'}, set(peers[0].keys())) def test_torrent_files(self): with client_env(self.track("torrent_files_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_files_b"), self.live_test): files = self.client.torrent_files(self.torrent.info_hash) self.assertTrue(files) def test_torrent_speed(self): with client_env(self.track("torrent_speed_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_speed_b"), self.live_test): speed = self.client.torrent_speed(self.torrent.info_hash) self.assertTrue(speed) def test_torrent_status(self): with client_env(self.track("torrent_status_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) self.sleep_live(5) with client_env(self.track("torrent_status_b"), self.live_test): status = self.client.torrent_status(self.torrent.info_hash) self.assertTrue(status) def test_torrent_queue_up(self): with client_env(self.track("torrent_queue_up_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_queue_up_b"), self.live_test): torrent_a = self.client.torrent_status(self.torrent.info_hash) self.assertEqual(torrent_a.queue_position, 0) with client_env(self.track("torrent_queue_up_c"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_2, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_queue_up_d"), self.live_test): torrent_b = self.client.torrent_status(self.torrent2.info_hash) self.assertEqual(torrent_b.queue_position, 1) with client_env(self.track("torrent_queue_up_e"), self.live_test): self.client.torrent_queue_up(self.torrent2.info_hash) with client_env(self.track("torrent_queue_up_f"), self.live_test): torrent_a = self.client.torrent_status(self.torrent.info_hash) self.assertEqual(torrent_a.queue_position, 1) with client_env(self.track("torrent_queue_up_g"), self.live_test): torrent_b = self.client.torrent_status(self.torrent2.info_hash) self.assertEqual(torrent_b.queue_position, 0) def test_torrent_queue_down(self): with client_env(self.track("torrent_queue_down_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_queue_down_b"), self.live_test): torrent_a = self.client.torrent_status(self.torrent.info_hash) self.assertEqual(torrent_a.queue_position, 0) with client_env(self.track("torrent_queue_down_c"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_2, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_queue_down_d"), self.live_test): torrent_b = self.client.torrent_status(self.torrent2.info_hash) self.assertEqual(torrent_b.queue_position, 1) with client_env(self.track("torrent_queue_down_e"), self.live_test): self.client.torrent_queue_down(self.torrent.info_hash) with client_env(self.track("torrent_queue_down_f"), self.live_test): torrent_a = self.client.torrent_status(self.torrent.info_hash) self.assertEqual(torrent_a.queue_position, 1) with client_env(self.track("torrent_queue_down_g"), self.live_test): torrent_b = self.client.torrent_status(self.torrent2.info_hash) self.assertEqual(torrent_b.queue_position, 0) def test_torrent_queue_top(self): with client_env(self.track("torrent_queue_top_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_queue_top_b"), self.live_test): torrent_a = self.client.torrent_status(self.torrent.info_hash) self.assertEqual(torrent_a.queue_position, 0) with client_env(self.track("torrent_queue_top_c"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_2, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_queue_top_d"), self.live_test): torrent_b = self.client.torrent_status(self.torrent2.info_hash) self.assertEqual(torrent_b.queue_position, 1) with client_env(self.track("torrent_queue_top_e"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_3, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_queue_top_f"), self.live_test): torrent_c = self.client.torrent_status(self.torrent3.info_hash) self.assertEqual(torrent_c.queue_position, 2) with client_env(self.track("torrent_queue_top_g"), self.live_test): self.assertTrue(self.client.torrent_queue_top(self.torrent3.info_hash)) with client_env(self.track("torrent_queue_top_h"), self.live_test): torrent_c = self.client.torrent_status(self.torrent3.info_hash) self.assertEqual(torrent_c.queue_position, 0) with client_env(self.track("torrent_queue_top_i"), self.live_test): torrent_a = self.client.torrent_status(self.torrent.info_hash) self.assertEqual(torrent_a.queue_position, 1) with client_env(self.track("torrent_queue_top_j"), self.live_test): torrent_a = self.client.torrent_status(self.torrent2.info_hash) self.assertEqual(torrent_a.queue_position, 2) def test_torrent_queue_bottom(self): with client_env(self.track("torrent_queue_bottom_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_queue_bottom_b"), self.live_test): torrent_a = self.client.torrent_status(self.torrent.info_hash) self.assertEqual(torrent_a.queue_position, 0) with client_env(self.track("torrent_queue_bottom_c"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_2, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_queue_bottom_d"), self.live_test): torrent_b = self.client.torrent_status(self.torrent2.info_hash) self.assertEqual(torrent_b.queue_position, 1) with client_env(self.track("torrent_queue_bottom_e"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_3, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_queue_bottom_f"), self.live_test): torrent_c = self.client.torrent_status(self.torrent3.info_hash) self.assertEqual(torrent_c.queue_position, 2) with client_env(self.track("torrent_queue_bottom_g"), self.live_test): self.assertTrue(self.client.torrent_queue_bottom(self.torrent.info_hash)) with client_env(self.track("torrent_queue_bottom_h"), self.live_test): torrent_c = self.client.torrent_status(self.torrent3.info_hash) self.assertEqual(torrent_c.queue_position, 1) with client_env(self.track("torrent_queue_bottom_i"), self.live_test): torrent_a = self.client.torrent_status(self.torrent.info_hash) self.assertEqual(torrent_a.queue_position, 2) with client_env(self.track("torrent_queue_bottom_j"), self.live_test): torrent_a = self.client.torrent_status(self.torrent2.info_hash) self.assertEqual(torrent_a.queue_position, 0) def test_torrent_reannounce(self): with client_env(self.track("torrent_reannounce_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_reannounce_b"), self.live_test): torrent_a = self.client.torrent_status(self.torrent.info_hash) self.assertEqual(torrent_a.next_announce, 0) time.sleep(5) with client_env(self.track("torrent_reannounce_c"), self.live_test): self.client.torrent_reannounce(self.torrent.info_hash) with client_env(self.track("torrent_reannounce_d"), self.live_test): torrent_a = self.client.torrent_status(self.torrent.info_hash) self.assertGreater(torrent_a.next_announce, 0) def test_disconnect(self): self.assertTrue(self.client.disconnect()) def test_torrent_recheck(self): # Not sure best way to check this.. with client_env(self.track("torrent_recheck_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_recheck_b"), self.live_test): self.assertTrue(self.client.torrent_recheck(self.torrent.info_hash)) @unittest.skip("Not sure how to test yet") def test_torrent_pause(self): with client_env(self.track("torrent_pause_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_pause_b"), self.live_test): torrent_a = self.client.torrent_status(self.torrent.info_hash) self.assertIn(torrent_a.state, [TorrentState.PAUSED, TorrentState.CHECKING, TorrentState.DOWNLOADING]) with client_env(self.track("torrent_pause_c"), self.live_test): self.assertTrue(self.client.torrent_pause(self.torrent.info_hash)) def test_torrent_start(self): with client_env(self.track("torrent_start_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) time.sleep(2) with client_env(self.track("torrent_start_b"), self.live_test): self.assertTrue(self.client.torrent_pause(self.torrent.info_hash)) time.sleep(2) with client_env(self.track("torrent_start_c"), self.live_test): status = self.client.torrent_status(self.torrent.info_hash) self.assertEqual(status.state, TorrentState.PAUSED) time.sleep(2) with client_env(self.track("torrent_start_d"), self.live_test): self.assertTrue(self.client.torrent_start(self.torrent.info_hash)) time.sleep(2) with client_env(self.track("torrent_start_e"), self.live_test): status = self.client.torrent_status(self.torrent.info_hash) self.assertIn(status.state, [TorrentState.STARTED, TorrentState.DOWNLOADING]) def test_torrent_add_duplicate(self): with client_env(self.track("torrent_add_duplicate_a"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir())) with client_env(self.track("torrent_add_duplicate_b"), self.live_test): self.assertTrue(self.client.torrent_add(open(self.test_file_1, "rb").read(), tempfile.gettempdir()))