from __future__ import unicode_literals, division, absolute_import
import logging
import csv
import re
from cgi import parse_header

from flexget.utils import requests
from flexget.utils.imdb import make_url
from flexget.utils.cached_input import cached
from flexget.utils.tools import decode_html
from flexget.plugin import register_plugin, PluginError
from flexget.entry import Entry
from flexget.utils.soup import get_soup

log = logging.getLogger('imdb_list')

USER_ID_RE = r'^ur\d{7,8}$'


class ImdbList(object):
    """"Creates an entry for each movie in your imdb list."""

    def validator(self):
        from flexget import validator
        root = validator.factory('dict')
        root.accept('regexp_match', key='user_id').\
            accept(USER_ID_RE, message='user_id must be in the form urXXXXXXX')
        root.accept('text', key='username')
        root.accept('text', key='password')
        root.accept('text', key='list', required=True)
        return root

    @cached('imdb_list', persist='2 hours')
    def on_task_input(self, task, config):
        sess = requests.Session()
        if config.get('username') and config.get('password'):

            log.verbose('Logging in ...')

            # Log in to imdb with our handler
            params = {'login': config['username'], 'password': config['password']}
            try:
                # First get the login page so we can get the hidden input value
                soup = get_soup(sess.get('https://secure.imdb.com/register-imdb/login').content)

                tag = soup.find('input', attrs={'name': '49e6c'})
                if tag:
                    params['49e6c'] = tag['value']
                else:
                    log.warning('Unable to find required info for imdb login, maybe their login method has changed.')
                # Now we do the actual login with appropriate parameters
                r = sess.post('https://secure.imdb.com/register-imdb/login', data=params, raise_status=False)
            except requests.RequestException as e:
                raise PluginError('Unable to login to imdb: %s' % e.message)

            # IMDb redirects us upon a successful login.
            # removed - doesn't happen always?
            # if r.status_code != 302:
            #     log.warning('It appears logging in to IMDb was unsuccessful.')

            # try to automatically figure out user_id from watchlist redirect url
            if not 'user_id' in config:
                log.verbose('Getting user_id ...')
                response = sess.get('http://www.imdb.com/list/watchlist')
                log.debug('redirected to %s' % response.url)
                user_id = response.url.split('/')[-2]
                if re.match(USER_ID_RE, user_id):
                    config['user_id'] = user_id
                else:
                    raise PluginError('Couldn\'t figure out user_id, please configure it manually.')

        if not 'user_id' in config:
            raise PluginError('Configuration option `user_id` required.')

        log.verbose('Retrieving list %s ...' % config['list'])

        # Get the imdb list in csv format
        try:
            url = 'http://www.imdb.com/list/export'
            params = {'list_id': config['list'], 'author_id': config['user_id']}
            log.debug('Requesting %s' % url)
            opener = sess.get(url, params=params)
            mime_type = parse_header(opener.headers['content-type'])[0]
            log.debug('mime_type: %s' % mime_type)
            if mime_type != 'text/csv':
                raise PluginError('Didn\'t get CSV export as response. Probably specified list `%s` does not exist.'
                                  % config['list'])
            csv_rows = csv.reader(opener.iter_lines())
        except requests.RequestException as e:
            raise PluginError('Unable to get imdb list: %s' % e.message)

        # Create an Entry for each movie in the list
        entries = []
        for row in csv_rows:
            if not row or row[0] == 'position':
                # Don't use blank rows or the headings row
                continue
            try:
                title = decode_html(row[5]).decode('utf-8')
                entries.append(Entry(title=title, url=make_url(row[1]), imdb_id=row[1], imdb_name=title))
            except IndexError:
                log.critical('IndexError! Unable to handle row: %s' % row)
        return entries


register_plugin(ImdbList, 'imdb_list', api_ver=2)

@@ -583,403 +583,466 @@
     
-def validator(self):%0A        from flexget import validator%0A        root = validator.factory('dict')%0A        root.accept('regexp_match', key='user_id').%5C%0A            accept(USER_ID_RE, message='user_id must be in the form urXXXXXXX')%0A        root.accept('text', key='username')%0A        root.accept('text', key='password')%0A        root.accept('text', key='list', required=True)%0A        return root
+schema = %7B%0A        'type': 'object',%0A        'properties': %7B%0A            'user_id': %7B%0A                'type': 'string',%0A                'pattern': USER_ID_RE,%0A                'error_pattern': 'user_id must be in the form urXXXXXXX'%0A            %7D,%0A            'username': %7B'type': 'string'%7D,%0A            'password': %7B'type': 'string'%7D,%0A            'list': %7B'type': 'string'%7D%0A        %7D,%0A        'required': %5B'list'%5D,%0A        'additionalProperties': False%0A    %7D
 %0A%0A  

Add imdb_list schema