flexget.plugins.urlrewrite_newtorrents
Covered: 34 lines
Missed: 62 lines
Skipped 29 lines
Percent: 35 %
  1
import urllib
  2
import urllib2
  3
import logging
  4
import re
  5
from plugin_urlrewriting import UrlRewritingError
  6
from flexget.entry import Entry
  7
from flexget.plugin import register_plugin, PluginWarning, internet
  8
from flexget.utils.soup import get_soup
  9
from flexget.utils.tools import urlopener
 10
from flexget.utils.search import StringComparator, torrent_availability
 12
timeout = 10
 13
import socket
 14
socket.setdefaulttimeout(timeout)
 16
log = logging.getLogger('newtorrents')
 19
class NewTorrents:
 20
    """NewTorrents urlrewriter and search plugin."""
 22
    def __init__(self):
 23
        self.resolved = []
 26
    def url_rewritable(self, feed, entry):
 28
        if entry['url'].startswith('http://www.newtorrents.info/down.php?'):
 29
            return False
 30
        return entry['url'].startswith('http://www.newtorrents.info') and not entry['url'] in self.resolved
 33
    def url_rewrite(self, feed, entry):
 34
        url = entry['url']
 35
        if (url.startswith('http://www.newtorrents.info/?q=') or
 36
           url.startswith('http://www.newtorrents.info/search')):
 37
            try:
 38
                url = self.entries_from_search(entry['title'], url=url)[0]['url']
 39
            except PluginWarning, e:
 40
                raise UrlRewritingError(e.value)
 41
        else:
 42
            url = self.url_from_page(url)
 44
        if url:
 45
            entry['url'] = url
 46
            self.resolved.append(url)
 47
        else:
 48
            raise UrlRewritingError('Bug in newtorrents urlrewriter')
 51
    def search(self, query, comparator, config=None):
 52
        return self.entries_from_search(query, comparator=comparator)
 54
    @internet(log)
 55
    def url_from_page(self, url):
 56
        """Parses torrent url from newtorrents download page"""
 57
        try:
 58
            page = urlopener(url, log)
 59
            data = page.read()
 60
        except urllib2.URLError:
 61
            raise UrlRewritingError('URLerror when retrieving page')
 62
        p = re.compile("copy\(\'(.*)\'\)", re.IGNORECASE)
 63
        f = p.search(data)
 64
        if not f:
 66
            raise UrlRewritingError('Failed to get url from download page. Plugin may need a update.')
 67
        else:
 68
            return f.group(1)
 70
    @internet(log)
 71
    def entries_from_search(self, name, url=None, comparator=StringComparator(cutoff=0.9)):
 72
        """Parses torrent download url from search results"""
 73
        comparator.set_seq1(name)
 74
        name = comparator.search_string()
 75
        if not url:
 76
            url = 'http://www.newtorrents.info/search/%s' % urllib.quote(name, safe=':/~?=&%')
 78
        log.debug('search url: %s' % url)
 80
        html = urlopener(url, log).read()
 83
        html = re.sub(r'(</SCR.*?)...(.*?IPT>)', r'\1\2', html)
 85
        soup = get_soup(html)
 87
        torrents = []
 88
        for link in soup.findAll('a', attrs={'href': re.compile('down.php')}):
 89
            torrent_url = 'http://www.newtorrents.info%s' % link.get('href')
 90
            release_name = link.parent.next.get('title')
 92
            seed = link.findNext('td', attrs={'class': re.compile('s')}).renderContents()
 93
            if seed == 'n/a':
 94
                seed = 0
 95
            else:
 96
                try:
 97
                    seed = int(seed)
 98
                except ValueError:
 99
                    log.warning('Error converting seed value (%s) from newtorrents to integer.' % seed)
100
                    seed = 0
103
            if comparator.matches(release_name):
104
                torrents.append(Entry(title=release_name, url=torrent_url, torrent_seeds=seed,
105
                                      search_ratio=comparator.ratio(), search_sort=torrent_availability(seed, 0)))
106
            else:
107
                log.debug('rejecting search result: %s !~ %s' % (release_name, name))
109
        torrents.sort(reverse=True, key=lambda x: x.get('search_sort', 0))
111
        if not torrents:
112
            dashindex = name.rfind('-')
113
            if dashindex != -1:
114
                return self.entries_from_search(name[:dashindex], comparator=comparator)
115
            else:
116
                raise PluginWarning('No matches for %s' % name, log, log_once=True)
117
        else:
118
            if len(torrents) == 1:
119
                log.debug('found only one matching search result.')
120
            else:
121
                log.debug('search result contains multiple matches, sorted %s by most seeders' % torrents)
122
            return torrents
124
register_plugin(NewTorrents, 'newtorrents', groups=['urlrewriter', 'search'])