diff --git a/CHANGES.md b/CHANGES.md index a6338c24..5e8481c1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -38,6 +38,7 @@ * Fix halting in mid flow of Add Existing Show which resulted in failure to scan statuses and filesizes * Change default de-referrer url to blank * Change javascript urls in templates to allow proper caching +* Change downloads to prevent cache misfiring with "Result is not a valid torrent file" ### 0.10.0 (2015-08-06 11:05:00 UTC) diff --git a/sickbeard/providers/generic.py b/sickbeard/providers/generic.py index ee00b065..348e30e5 100644 --- a/sickbeard/providers/generic.py +++ b/sickbeard/providers/generic.py @@ -32,10 +32,11 @@ import requests.cookies from sickbeard import helpers, classes, logger, db, tvcache, encodingKludge as ek from sickbeard.common import Quality, MULTI_EP_RESULT, SEASON_RESULT, USER_AGENT from sickbeard.exceptions import SickBeardException, AuthException, ex -from sickbeard.helpers import maybe_plural +from sickbeard.helpers import maybe_plural, _remove_file_failed as remove_file_failed from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException from sickbeard.show_name_helpers import allPossibleShowNames -from hachoir_parser import createParser +from hachoir_parser import guessParser +from hachoir_core.stream import FileInputStream class HaltParseException(SickBeardException): @@ -160,7 +161,7 @@ class GenericProvider: urls = ['http%s://%s/%s.torrent' % (u + (torrent_hash,)) for u in (('s', 'torcache.net/torrent'), ('s', 'getstrike.net/torrents/api/download'), - ('', 'thetorrent.org'))] + ('s', 'itorrents.org/torrent'))] except: urls = [result.url] @@ -170,53 +171,64 @@ class GenericProvider: else: return + ref_state = 'Referer' in self.session.headers and self.session.headers['Referer'] + saved = False for url in urls: cache_dir = sickbeard.CACHE_DIR or helpers._getTempDir() base_name = '%s.%s' % (helpers.sanitizeFileName(result.name), self.providerType) cache_file = ek.ek(os.path.join, cache_dir, base_name) + self.session.headers['Referer'] = url if helpers.download_file(url, cache_file, session=self.session): - logger.log(u'Downloaded a result from %s at %s' % (self.name, url)) if self._verify_download(cache_file): - if GenericProvider.TORRENT == self.providerType: - final_dir, link_type = (sickbeard.TORRENT_DIR, 'magnet') - else: - final_dir, link_type = (sickbeard.NZB_DIR, 'nzb') + logger.log(u'Downloaded %s result from %s' % (self.name, url)) + final_dir, link_type = ((sickbeard.TORRENT_DIR, 'magnet'), (sickbeard.NZB_DIR, 'nzb') + )[GenericProvider.NZB == self.providerType] final_file = ek.ek(os.path.join, final_dir, base_name) + try: + helpers.moveFile(cache_file, final_file) + msg = 'moved' + except: + msg = 'copied cached file' + logger.log(u'Saved %s link and %s to %s' % (link_type, msg, final_file)) + saved = True + break - helpers.moveFile(cache_file, final_file) - if not ek.ek(os.path.isfile, cache_file) and ek.ek(os.path.isfile, final_file): - logger.log(u'Saved %s link to %s' % (link_type, final_file), logger.MESSAGE) - return True + remove_file_failed(cache_file) - if ek.ek(os.path.isfile, cache_file): - ek.ek(os.remove, cache_file) + if 'Referer' in self.session.headers: + if ref_state: + self.session.headers['Referer'] = ref_state + else: + del(self.session.headers['Referer']) - logger.log(u'Failed to download result', logger.ERROR) - return False + if not saved: + logger.log(u'All torrent cache servers failed to return a downloadable result', logger.ERROR) + + return saved def _verify_download(self, file_name=None): """ Checks the saved file to see if it was actually valid, if not then consider the download a failure. """ - + result = True # primitive verification of torrents, just make sure we didn't get a text file or something if GenericProvider.TORRENT == self.providerType: - parser = createParser(file_name) - if parser: - mime_type = parser._getMimeType() - try: - parser.stream._input.close() - except: - pass - if 'application/x-bittorrent' == mime_type: - return True + parser = stream = None + try: + stream = FileInputStream(file_name) + parser = guessParser(stream) + except: + pass + result = parser and 'application/x-bittorrent' == parser.mime_type - logger.log(u'Result is not a valid torrent file', logger.WARNING) - return False + try: + stream._input.close() + except: + pass - return True + return result def search_rss(self, episodes): return self.cache.findNeededEpisodes(episodes)