def execute(self, topics, engine): """ :param topics: result of get_topics func :type engine: Engine :return: None """ for topic in topics: topic_name = topic.display_name try: engine.log.info(u"Check for changes <b>%s</b>" % topic_name) prepared_request = self._prepare_request(topic) download_kwargs = {} if isinstance(prepared_request, tuple) and len(prepared_request) >= 2: download_kwargs = prepared_request[1] or download_kwargs prepared_request = prepared_request[0] download_kwargs.setdefault( 'timeout', self.tracker_settings.requests_timeout) response, filename = download(prepared_request, **download_kwargs) if hasattr(self, 'check_download'): status = self.check_download(response) if topic.status != status: self.save_topic(topic, None, status) if status != Status.Ok: engine.log.failed( u"Torrent status changed: {}".format(status)) continue elif response.status_code != 200: raise Exception("Can't download url. Status: {}".format( response.status_code)) if not filename: filename = topic_name engine.log.info(u"Downloading <b>%s</b> torrent" % filename) torrent_content = response.content torrent = Torrent(torrent_content) old_hash = topic.hash if torrent.info_hash != old_hash: engine.log.downloaded( u"Torrent <b>%s</b> was changed" % topic_name, torrent_content) last_update = engine.add_torrent(filename, torrent, old_hash) topic.hash = torrent.info_hash topic.last_update = last_update self.save_topic(topic, last_update, Status.Ok) else: engine.log.info(u"Torrent <b>%s</b> not changed" % topic_name) except Exception as e: engine.log.failed(u"Failed update <b>%s</b>.\nReason: %s" % (topic_name, html.escape(str(e))))
def get_hash(self, url): download_url = self.get_download_url(url) if not download_url: return None r = requests.get(download_url, allow_redirects=False, timeout=self.tracker_settings.requests_timeout) content_type = r.headers.get('content-type', '') if content_type.find('bittorrent') == -1: raise Exception( 'Expect torrent for download from url: {0}, but was {1}'. format(url, content_type)) t = Torrent(r.content) return t.info_hash
def add_torrent(self, torrent_content): path = self.check_connection() if not path: return False try: try: torrent = Torrent(torrent_content) except Exception as e: return False filename = torrent.info_hash + ".torrent" with open(os.path.join(path, filename), "wb") as f: f.write(torrent.raw_content) return True except OSError: return False
def test_find_torrent_failed_os_error(self): torrent_filename = 'Hell.On.Wheels.S05E02.720p.WEB.rus.LostFilm.TV.mp4.torrent' torrent_filepath = self.get_httpretty_filename(torrent_filename) torrent = Torrent.from_file(torrent_filepath) plugin = DownloaderPlugin() settings = {'path': self.downloader_dir} plugin.set_settings(settings) downloaded_filepath = os.path.join(self.downloader_dir, torrent_filename) if not os.path.exists(self.downloader_dir): os.makedirs(self.downloader_dir) shutil.copy(torrent_filepath, downloaded_filepath) with patch('monitorrent.plugins.clients.downloader.os.path.getctime') as access: access.side_effect = OSError self.assertFalse(plugin.find_torrent(torrent.info_hash))
def find_torrent(self, torrent_hash): path = self.check_connection() if not path: return False files = os.listdir(path) for torrent_file in files: file_path = os.path.join(path, torrent_file) if torrent_file.endswith(".torrent") and os.path.isfile(file_path): try: try: torrent = Torrent.from_file(file_path) except: continue if torrent.info_hash == torrent_hash: date_added = datetime.fromtimestamp(os.path.getctime(file_path))\ .replace(tzinfo=reference.LocalTimezone()).astimezone(utc) return {"name": torrent_file, "date_added": date_added} except OSError: continue return False
def test_remove_torrent(self): torrent_filename = 'Hell.On.Wheels.S05E02.720p.WEB.rus.LostFilm.TV.mp4.torrent' torrent_filepath = self.get_httpretty_filename(torrent_filename) torrent = Torrent.from_file(torrent_filepath) plugin = DownloaderPlugin() self.assertFalse(plugin.remove_torrent(torrent.info_hash)) settings = {'path': self.downloader_dir} plugin.set_settings(settings) self.assertFalse(plugin.remove_torrent(torrent.info_hash)) downloaded_filepath = os.path.join(self.downloader_dir, torrent_filename) if not os.path.exists(self.downloader_dir): os.makedirs(self.downloader_dir) shutil.copy(torrent_filepath, downloaded_filepath) self.assertFalse(plugin.remove_torrent("RANDOM_HASH")) self.assertTrue(plugin.remove_torrent(torrent.info_hash)) self.assertFalse(os.path.exists(downloaded_filepath))
def test_find_torrent(self): torrent_filename = 'Hell.On.Wheels.S05E02.720p.WEB.rus.LostFilm.TV.mp4.torrent' torrent_filepath = self.get_httpretty_filename(torrent_filename) torrent = Torrent.from_file(torrent_filepath) plugin = DownloaderPlugin() settings = {'path': self.downloader_dir} self.assertFalse(plugin.find_torrent(torrent.info_hash)) plugin.set_settings(settings) self.assertFalse(plugin.find_torrent(torrent.info_hash)) downloaded_filepath = os.path.join(self.downloader_dir, torrent_filename) if not os.path.exists(self.downloader_dir): os.makedirs(self.downloader_dir) shutil.copy(torrent_filepath, downloaded_filepath) find_torrent = plugin.find_torrent(torrent.info_hash) self.assertNotEqual(False, find_torrent) date_added = datetime.fromtimestamp(os.path.getctime(downloaded_filepath))\ .replace(tzinfo=reference.LocalTimezone()).astimezone(utc) expected = {'name': torrent_filename, 'date_added': date_added} self.assertEqual(expected, find_torrent)
def execute(self, topics, engine): """ :param topics: result of get_topics func :type engine: engine.Engine :rtype: None """ if not self._execute_login(engine): return for topic in topics: try: display_name = topic.display_name episodes = self._prepare_request(topic) status = Status.Ok if isinstance(episodes, Response): status = self.check_download(episodes) if topic.status != status: self.save_topic(topic, None, status) if status != Status.Ok: engine.log.failed(u"Torrent status changed: {}".format(status)) continue if episodes is None or len(episodes) == 0: engine.log.info(u"Series <b>{0}</b> not changed".format(display_name)) continue for episode in episodes: info = episode['season_info'] download_info = episode['download_info'] if download_info is None: engine.log.failed(u'Failed get quality "{0}" for series: {1}' .format(topic.quality, html.escape(display_name))) # Should fail to get quality be treated as NotFound? self.save_topic(topic, None, Status.Error) break try: response, filename = download(download_info['download_url'], timeout=self.tracker_settings.requests_timeout) if response.status_code != 200: raise Exception("Can't download url. Status: {}".format(response.status_code)) except Exception as e: engine.log.failed(u"Failed to download from <b>{0}</b>.\nReason: {1}" .format(download_info['download_url'], html.escape(str(e)))) self.save_topic(topic, None, Status.Error) continue if not filename: filename = display_name torrent_content = response.content torrent = Torrent(torrent_content) engine.log.downloaded(u'Download new series: {0} ({1}, {2})' .format(display_name, info[0], info[1]), torrent_content) topic.season = info[0] topic.episode = info[1] last_update = engine.add_torrent(filename, torrent, None) self.save_topic(topic, last_update, Status.Ok) except Exception as e: engine.log.failed(u"Failed update <b>lostfilm</b> series: {0}.\nReason: {1}" .format(topic.search_name, html.escape(str(e))))