from __future__ import unicode_literals, division, absolute_import
import logging
import re
import urllib
import feedparser

from flexget import plugin
from flexget.entry import Entry
from flexget.event import event
from flexget.utils import requests
from flexget.utils.search import torrent_availability, normalize_unicode

log = logging.getLogger('torrentz')

REGEXP = re.compile(r'https?://torrentz\.(eu|me|ch|in)/(?P<hash>[a-f0-9]{40})')
REPUTATIONS = {  # Maps reputation name to feed address
    'any': 'feed_any',
    'low': 'feed_low',
    'good': 'feed',
    'verified': 'feed_verified'
}


class UrlRewriteTorrentz(object):
    """Torrentz urlrewriter."""

    schema = {
        'oneOf': [
            {
                'title': 'specify options',
                'type': 'object',
                'properties': {
                    'reputation': {'enum': list(REPUTATIONS), 'default': 'good'},
                    'extra_terms': {'type': 'string'}
                },
                'additionalProperties': False
            },
            {'title': 'specify reputation', 'enum': list(REPUTATIONS), 'default': 'good'}
        ]
    }

    def process_config(self, config):
        """Return plugin configuration in advanced form"""
        if isinstance(config, basestring):
            config = {'reputation': config}
        if config.get('extra_terms'):
            config['extra_terms'] = ' ' + config['extra_terms']
        return config

    def url_rewritable(self, task, entry):
        return REGEXP.match(entry['url'])

    def url_rewrite(self, task, entry):
        thash = REGEXP.match(entry['url']).group(2)
        entry['url'] = 'https://torcache.net/torrent/%s.torrent' % thash.upper()
        entry['torrent_info_hash'] = thash

    def search(self, task, entry, config=None):
        config = self.process_config(config)
        feed = REPUTATIONS[config['reputation']]
        entries = set()
        for search_string in entry.get('search_strings', [entry['title']]):
            query = normalize_unicode(search_string + config.get('extra_terms', ''))
            for domain in ['eu', 'me', 'ch', 'in']:
                # urllib.quote will crash if the unicode string has non ascii characters, so encode in utf-8 beforehand
                url = 'http://torrentz.%s/%s?q=%s' % (domain, feed, urllib.quote(query.encode('utf-8')))
                log.debug('requesting: %s' % url)
                try:
                    r = requests.get(url)
                    break
                except requests.RequestException as err:
                    log.warning('torrentz.%s failed. Error: %s' % (domain, err))
            else:
                raise plugin.PluginError('Error getting torrentz search results')

            if not r.content.strip():
                raise plugin.PluginError('No data from %s. Maybe torrentz is blocking the FlexGet User-Agent' % url)

            rss = feedparser.parse(r.content)

            if rss.get('bozo_exception'):
                raise plugin.PluginError('Got bozo_exception (bad rss feed)')

            for item in rss.entries:
                m = re.search(r'Size: ([\d]+) Mb Seeds: ([,\d]+) Peers: ([,\d]+) Hash: ([a-f0-9]+)',
                              item.description, re.IGNORECASE)
                if not m:
                    log.debug('regexp did not find seeds / peer data')
                    continue

                entry = Entry()
                entry['title'] = item.title
                entry['url'] = item.link
                entry['content_size'] = int(m.group(1))
                entry['torrent_seeds'] = int(m.group(2).replace(',', ''))
                entry['torrent_leeches'] = int(m.group(3).replace(',', ''))
                entry['torrent_info_hash'] = m.group(4).upper()
                entry['search_sort'] = torrent_availability(entry['torrent_seeds'], entry['torrent_leeches'])
                entries.add(entry)

        log.debug('Search got %d results' % len(entries))
        return entries


@event('plugin.register')
def register_plugin():
    plugin.register(UrlRewriteTorrentz, 'torrentz', groups=['urlrewriter', 'search'], api_ver=2)

@@ -99,16 +99,17 @@
  urllib%0A
+%0A
 import f
@@ -117,16 +117,32 @@
 edparser
+%0Aimport requests
 %0A%0Afrom f
@@ -230,43 +230,8 @@
 ent%0A
-from flexget.utils import requests%0A
 from
@@ -2434,16 +2434,21 @@
     r = 
+task.
 requests
@@ -2519,32 +2519,142 @@
 sts.
-RequestException a
+ConnectionError as err:%0A                    # The different domains all resolve to the same ip, so only try more if it was a dn
 s err
-:
+or
 %0A   
@@ -2695,16 +2695,27 @@
 entz.%25s 
+connection 
 failed. 
@@ -2742,16 +2742,199 @@
 , err))%0A
+                    continue%0A                except requests.RequestException as err:%0A                    raise plugin.PluginError('Error getting torrentz search results: %25s' %25 err)%0A%0A
         

Stop trying many torrentz domains when the problem isn't with dns. ref gh #505