flexget.plugins.urlrewrite_isohunt
Covered: 41 lines
Missed: 45 lines
Skipped 29 lines
Percent: 47 %
  1
import logging
  2
import re
  3
import urllib
  4
import feedparser
  5
from flexget.entry import Entry
  6
from flexget.utils.search import torrent_availability
  7
from flexget.plugin import PluginWarning, register_plugin
  9
log = logging.getLogger('isohunt')
 12
class UrlRewriteIsoHunt(object):
 13
    """IsoHunt urlrewriter and search plugin.
 15
    should accept: 
 16
    isohunt: <category>
 18
      categories: 
 19
      empty or -1: All
 20
      0 : Misc.
 21
      1 : Video/Movies
 22
      2 : Audio
 23
      3 : TV
 24
      4 : Games
 25
      5 : Apps
 26
      6 : Pics
 27
      7 : Anime
 28
      8 : Comics
 29
      9 : Books
 30
      10: Music Video
 31
      11: Unclassified
 32
      12: ALL
 33
    """
 35
    def validator(self):
 36
        from flexget import validator
 38
        root = validator.factory('choice')
 39
        root.accept_choices(['misc', 'movies', 'audio', 'tv', 'games', 'apps', 'pics', 'anime', 'comics',
 40
                             'books', 'music video', 'unclassified', 'all'])
 41
        return root
 43
    def url_rewritable(self, feed, entry):
 44
        url = entry['url']
 46
        if url.startswith('http://isohunt.com/torrents/?ihq='):
 47
            return False
 49
        if not 'torrent_details' in url:
 50
            return False
 51
        return url.startswith('http://isohunt.com') and url.find('download') == -1
 53
    def url_rewrite(self, feed, entry):
 54
        entry['url'] = entry['url'].replace('torrent_details', 'download')
 56
    def search(self, query, comparator, config):
 58
        comparator.set_seq1(query)
 59
        name = comparator.search_string()
 60
        optionlist = ['misc', 'movies', 'audio', 'tv', 'games', 'apps', 'pics', 'anime', 'comics', 'books',
 61
                      'music video', 'unclassified', 'all']
 62
        url = 'http://isohunt.com/js/rss/%s?iht=%s&noSL' % (
 63
        urllib.quote(name.encode('utf-8')), optionlist.index(config))
 65
        log.debug('requesting: %s' % url)
 66
        rss = feedparser.parse(url)
 67
        entries = []
 69
        status = rss.get('status', False)
 70
        if status != 200:
 71
            raise PluginWarning('Search result not 200 (OK), received %s' % status)
 73
        ex = rss.get('bozo_exception', False)
 74
        if ex:
 75
            raise PluginWarning('Got bozo_exception (bad feed)')
 77
        for item in rss.entries:
 81
            comparator.set_seq2(item.title)
 82
            log.debug('name: %s' % comparator.a)
 83
            log.debug('found name: %s' % comparator.b)
 84
            log.debug('confidence: %s' % comparator.ratio())
 85
            if not comparator.matches():
 86
                continue
 88
            entry = Entry()
 89
            entry['title'] = item.title
 90
            entry['url'] = item.link
 91
            entry['search_ratio'] = comparator.ratio()
 93
            m = re.search(r'Size: ([\d]+).*Seeds: (\d+).*Leechers: (\d+)', item.description, re.IGNORECASE)
 94
            if not m:
 95
                log.debug('regexp did not find seeds / peer data')
 96
                continue
 97
            else:
 98
                log.debug('regexp found size(%s), Seeds(%s) and Leeches(%s)' % (m.group(1), m.group(2), m.group(3)))
100
                entry['content_size'] = int(m.group(1))
101
                entry['torrent_seeds'] = int(m.group(2))
102
                entry['torrent_leeches'] = int(m.group(3))
103
                entry['search_sort'] = torrent_availability(entry['torrent_seeds'], entry['torrent_leeches'])
105
            entries.append(entry)
107
        if not entries:
108
            raise PluginWarning('No close matches for %s' % name, log, log_once=True)
110
        entries.sort(reverse=True, key=lambda x: x.get('search_sort'))
112
        return entries
114
register_plugin(UrlRewriteIsoHunt, 'isohunt', groups=['urlrewriter', 'search'])