# -*- coding: utf-8 -*-
import os
import re
import gzip
import time
import json
import urllib
import urllib2
import cookielib
import captcha
from random import randint
from StringIO import StringIO
from xbmcswift2 import xbmc
from xbmcswift2 import Plugin
from xbmcswift2 import xbmcgui
from zhcnkbd import Keyboard

plugin = Plugin()


@plugin.route('/')
def index():
    '''
    show root menu
    '''
    item = [
        {'label': '[登入迅雷] - 白金用户',
         'path': plugin.url_for('login')},
        {'label': '[迅雷云播] - 云播空间',
         'path': plugin.url_for('cloudspace')},
        {'label': '[迅雷离线] - 离线空间',
         'path': plugin.url_for('lxspace', page=1)},
        {'label': '[中文搜索] - BTdigg.org',
         'path': plugin.url_for('btdigg', url='search')},
        {'label': '[英文搜索] - ExtraTorrent.cc',
         'path': plugin.url_for('torrentz', url='search')},
        {'label': '[豆瓣电影] - 标签搜索',
         'path': plugin.url_for('dbsearch', url='search')},
        {'label': '[豆瓣电影] - 分类浏览',
         'path': plugin.url_for('dbmovie')},
        {'label': '[豆瓣电影] - 新片榜',
         'path': plugin.url_for('dbntop')},
        {'label': '[豆瓣电影] - TOP250',
         'path': plugin.url_for('dbtop250', url='dbtop250')},
    ]

    return item


@plugin.route('/login')
def login():
    '''
    login xunlei & lixian space
    '''
    plugin.open_settings()
    user = plugin.get_setting('username')
    passwd = plugin.get_setting('password')
    if not (user and passwd):
        return
    xl = HttpClient()

    # get verify code
    vfcodeurl = 'http://login.xunlei.com/check?u={0}&cachetime={1}'.format(
        user, cachetime)
    xl.urlopen(vfcodeurl)
    vfcode = xl.getcookieatt('.xunlei.com', 'check_result')[2:]

    if not vfcode:
        vfcode = xl.getvfcode('http://verify.xunlei.com/image?cachetime=')
        if not vfcode:
            return

    # encoding password str
    if not re.match(r'^[0-9a-f]{32}$', passwd):
        passwd = xl.md5(xl.md5(passwd))

    passwd = xl.md5(passwd+vfcode.upper())

    data = urllib.urlencode(
        {'u': user,
         'p': passwd,
         'verifycode': vfcode,
         'login_enable': '1',
         'login_hour': '720', }
    )

    xl.urlopen('http://login.xunlei.com/sec2login/', data=data)

    xl.userid = xl.getcookieatt('.xunlei.com', 'userid')
    xl.sid = xl.getcookieatt('.xunlei.com', 'sessionid')

    # login lixian space
    xl.urlopen(
        'http://dynamic.lixian.vip.xunlei.com/login?cachetime=%s' % cachetime)
    urlpre = '%s/%s' % (lxurlpre, 'interface/showtask_unfresh')
    rsp = xl.urlopen('%s?type_id=2&tasknum=1&t=%s' % (urlpre, cachetime))
    data = json.loads(rsp[8:-1])
    gdriveid = data['info']['user']['cookie']

    xl.setcookie('.vip.xunlei.com', 'gdriveid', gdriveid)
    xl.setcookie('.vip.xunlei.com', 'pagenum', '100')
    xl.cookiejar.save(cookiefile, ignore_discard=True)

    blogresult = xl.getcookieatt('.xunlei.com', 'blogresult')
    rst = int(blogresult)
    loginmsgs = ['登入成功', '验证码错误', '密码错误', '用户名不存在']
    plugin.notify(msg=loginmsgs[rst] if rst < 3 else '未知错误')
    # for ck in xl.cookiejar:
    #    print (ck.name, ck.value)
    return


@plugin.route('/cloudspace')
def cloudspace():
    '''
    show xunlei cloud space content
    '''
    dhurl = '%s/%s/?type=all&order=create&t=%s' % (
        cloudurlpre,
        'req_history_play_list/req_num/200/req_offset/0',
        cachetime)
    rsp = xl.urlopen(dhurl)
    vods = json.loads(rsp)['resp']['history_play_list']

    menu = [
        {'label': urllib2.unquote(v['file_name'].encode('utf-8')),
         'path': plugin.url_for('playcloudvideo',
                                vinfo=str((v['src_url'], v['gcid'],
                                           v['cid'], v['file_name'])))}
        for v in vods if 'src_url' in v]
    return menu


@plugin.route('/lxspace/<page>')
def lxspace(page):
    '''
    show xunlei lixian space content

    http://dynamic.cloud.vip.xunlei.com/interface/showtask_unfresh?
    callback=jsonp1392830614727&t=Thu%20Feb%2020%202014%2001:23:35%
    20GMT+0800%20(CST)&type_id=4&page=1&tasknum=30&p=1&interfrom=task
    '''
    urlpre = '%s/%s' % (lxurlpre, 'interface/showtask_unfresh')
    rsp = xl.urlopen(
        '%s?t=%s&type_id=4&page=%s&tasknum=30&p=1' % (urlpre, cachetime, page))
    data = json.loads(rsp[8:-1])

    menus = [
        {'label': '[{0}%][{1}]{2}'.format(i['progress'],
                                          i['openformat'],
                                          i['taskname'].encode('utf-8')),
         'path': plugin.url_for('playlxtid',
                                magnet=i['cid'],
                                lxurl=i['lixian_url'] if i['lixian_url'] else 'bt',
                                title=i['taskname'].encode('utf-8'),
                                taskid=i['id']), }
        for i in data['info']['tasks']]

    total = int(data['info']['user']['total_num'])
    totalpgs = (total+29) // 30
    page = int(page)
    if page-1 > 0:
        menus.append(
            {'label': '上一页', 'path': plugin.url_for('lxspace', page=page-1)})
    if page < totalpgs:
        menus.append(
            {'label': '下一页', 'path': plugin.url_for('lxspace', page=page+1)})
    menus.insert(0, {'label': '【第%s页/共%s页】返回上级菜单' % (page, totalpgs),
                     'path': plugin.url_for('index')})
    return menus


@plugin.route('/playcloudvideo/<vinfo>')
def playcloudvideo(vinfo):
    '''
    resolve xunlei cloud play url, add magnet link to space if it not in here
    '''
    protocol = vinfo[:10]
    if 'bt' in protocol or 'magnet' in protocol:
        if 'magnet' in vinfo:
            ihash = addmagnet(vinfo)
        else:
            _vinfo = eval(vinfo)
            ihash = _vinfo[0][5:]

        subbt = '%s/req_subBT/info_hash/%s/req_num/500/req_offset/0' % (
            cloudurlpre, ihash)
        rsp = xl.urlopen(subbt)
        vfinfo = json.loads(rsp)
        videos = vfinfo['resp']['subfile_list']
        if len(videos) > 1:
            selitem = dialog.select('播放选择',
                                    [urllib2.unquote(v['name'].encode('utf-8'))
                                     for v in videos])
            if selitem is -1:
                return
            video = videos[selitem]
        else:
            video = videos[0]
        gcid = video['gcid']
        cid = video['cid']
        title = urllib2.quote(video['name'].encode('utf-8'))
    elif 'http' in protocol or 'thunder' in protocol or 'ed2k' in protocol:
        _vinfo = eval(vinfo)
        gcid = _vinfo[1]
        cid = _vinfo[2]
        title = urllib2.quote(_vinfo[3].encode('utf-8'))
    else:
        return

    dl = '{0}/vod_dl_all?userid={1}&gcid={2}&filename={3}&t={4}'.format(
        cloudurlpre, xl.userid, gcid, title, cachetime)
    rsp = xl.urlopen(dl)
    vturls = json.loads(rsp)
    typ = {'Full_HD': '1080P', 'HD': '720P', 'SD': '标清'}
    vtyps = [(typ[k], v['url']) for (k, v) in vturls.iteritems() if 'url' in v]

    if not vtyps:
        plugin.notify(msg='视频转码进行中，请稍候尝试从云播空间菜单进入播放')
        return
    if len(vtyps) > 1:
        selitem = dialog.select('清晰度', [v[0] for v in vtyps])
        if selitem is -1:
            return
        vtyp = vtyps[selitem]
    else:
        vtyp = vtyps[0]

    player(vtyp[1], gcid, cid, title, True)


@plugin.route('/playlxvideo/<magnet>', name='playlxmagnet')
@plugin.route('/playlxvideo/<magnet>/<taskid>/<lxurl>/<title>',
              name='playlxtid')
def playlxvideo(magnet, taskid=None, lxurl=None, title=None):
    '''
    resolve lixian space video url, add magnet to space if it not in here.
    support delete space content
    (i['title'], i['size'], i['percent'], i['cid'],
               re.sub(r'.*?&g=', '', i['downurl'])[:40], i['downurl'])
    '''
    urlpre = '%s/%s' % (lxurlpre, 'interface')
    if taskid:
        sel = dialog.select('选项', ['播放', '删除'])
        if sel is -1:
            return
        if sel is 0:
            pass
        if sel is 1:
            data = {'taskids': taskid+',', 'databases': '0,'}
            url = '%s/task_delete?callback=jsonp%s&t=%s' % (
                urlpre, cachetime, cachetime)
            rsp = xl.urlopen(url, data=urllib.urlencode(data))
            if 'result":1' in rsp:
                plugin.notify(msg='删除任务成功')
                from itertools import imap
                imap(lambda x: magnets.pop(x),
                     [k for k, v in magnets.iteritems() if taskid in v])
            else:
                plugin.notify(msg='删除任务失败,请稍候重试')
            return

    # Ugly process, Don't support cloud url
    if lxurl and len(lxurl) > 2:
        cid = magnet
        gcid = re.sub(r'.*?&g=', '', lxurl)[:40]
        title = title
        # video = getcloudvideourl(gcid, lxurl, title)
        # if not video: return
        player(lxurl, gcid, cid, title)
        return
    #if magnet and len(magnet) > 40:
    if magnet and 'torrent' in magnet:
        url = 'http://extratorrent.cc%s' % (magnet)
        rsp = hc.urlopen(url)
        #print url
        magnetid = re.search(r'magnet:\?xt=urn:btih:\S{40}', rsp)
        #print magnetid.group(0)
        tid = gettaskid(magnetid.group(0))
        infoid = magnet[-40:]
    else:
        infoid = magnet
        tid = taskid
    url = '%s/%s&tid=%s&infoid=%s&g_net=1&p=1&uid=%s&noCacheIE=%s' % (
        urlpre, 'fill_bt_list?callback=fill_bt_list', tid, infoid,
        xl.userid, cachetime)
    rsp = xl.urlopen(url)
    if not xl.getcookieatt('dynamic.cloud.vip.xunlei.com', 'PHPSESSID'):
        xl.cookiejar.save(cookiefile, ignore_discard=True)
    try:
        data = json.loads(rsp[13:-1])
    except ValueError:
        magnets.pop(magnet)
        plugin.notify('该离线任务已删除,请重新添加')
        return

    mitems = [(i['title'],
               i['size'],
               i['percent'],
               i['cid'],
               re.sub(r'.*?&g=', '', i['downurl'])[:40],
               i['downurl'],
               i['url'])
              for i in data['Result']['Record'] if 'movie' in i['openformat']
              and i['percent'] == 100]

    if not mitems:
        plugin.notify('离线下载进行中，请稍候从离线空间播放')
        return

    if len(mitems) > 1:
        sel = dialog.select(
            '播放选择',
            ['[%s]%s[%s]' % (i[2], i[0], i[1]) for i in mitems])
        if sel is -1:
            return
        mov = mitems[sel]
    else:
        mov = mitems[0]

    (name, _, _, cid, gcid, downurl, bturl) = mov
    videos = []
    # videos = getcloudvideourl(bturl, name.encode('utf-8'))
    videos.insert(0, ('源码', downurl))
    selitem = dialog.select('清晰度', [v[0] for v in videos])
    if selitem is -1:
        return
    v = videos[selitem]
    player(v[1], gcid, cid, name, True)


def player(url, gcid, cid, title, finalurl=False):
    '''
    play video, add subtitle
    '''
    if not finalurl:
        url = xl.urlopen(url, redirect=False)
    # cks = dict((ck.name, ck.value) for ck in xl.cookiejar)
    cks = ['%s=%s' % (ck.name, ck.value) for ck in xl.cookiejar]
    movurl = '%s|%s&Cookie=%s' % (
        url, urllib.urlencode(xl.headers), urllib2.quote('; '.join(cks)))

    # for ck in xl.cookiejar:
    #    print ck.name, ck.value
    listitem = xbmcgui.ListItem(label=title)
    listitem.setInfo(type="Video", infoLabels={'Title': title})
    player = xbmc.Player()
    player.play(movurl, listitem)

    surl = ''
    subtinfo = '{0}/subtitle/list?gcid={1}&cid={2}&userid={3}&t={4}'.format(
        cloudurlpre, gcid, cid, xl.userid, cachetime)
    subtinfo = '%s|%s&Cookie=%s' % (
        subtinfo, urllib.urlencode(xl.headers), urllib2.quote('; '.join(cks)))
    subtitle = xl.urlopen(subtinfo)
    sinfos = json.loads(subtitle)
    # print sinfos
    surls = ''
    if 'sublist' in sinfos and len(sinfos['sublist']):
        surls = [sinfo['surl'] for sinfo in sinfos['sublist']]
    if surls:
        for _ in xrange(30):
            if player.isPlaying():
                break
            time.sleep(1)
        else:
            raise Exception('No video playing. Aborted after 30 seconds.')
        xl.headers.pop('Accept-encoding')
        for surl in surls:
            player.setSubtitles('%s|%s&Cookie=%s' % (
                surl, urllib.urlencode(xl.headers),
                urllib2.quote('; '.join(cks))))

    # xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)


@plugin.route('/btdigg/<url>')
def btdigg(url, mname=''):
    '''
    magnet linke search engine: btdigg.org
    '''
    if url == 'search':
        url = 'http://btdigg.org/search?q='
        if not mname:
            kb = Keyboard('', u'请输入搜索关键字')
            kb.doModal()
            if not kb.isConfirmed():
                return
            mname = kb.getText()
            if not mname:
                return
        url = url + urllib2.quote(mname)
    else:
        url = 'http://btdigg.org' + url

    rsp = hc.urlopen(url)
    rpat = re.compile(
        r'"idx">.*?>([^<]+)</a>.*?href="(magnet.*?)".*?Size:.*?">(.*?)<')
    items = rpat.findall(rsp)

    menus = [
        {'label': '%d.%s[%s]' % (s+1, v[0], v[2].replace('&nbsp;', '')),
         'path': plugin.url_for('playlxmagnet', magnet=v[1])}
        for s, v in enumerate(items)]
    ppat = re.compile(r'%s%s' % (
        'class="pager".*?(?:href="(/search.*?)")?>←.*?>',
        '(\d+/\d+).*?(?:href="(/search.*?)")?>Next'))

    pgs = ppat.findall(rsp)

    for s, p in enumerate((pgs[0][0], pgs[0][2])):
        if p:
            menus.append({'label': '上一页' if not s else '下一页',
                          'path': plugin.url_for('btdigg', url=p)})
    menus.insert(0, {'label': '[当前页%s页总共]返回上级目录' % pgs[0][1],
                     'path': plugin.url_for('index')})
    return menus


@plugin.route('/torrentz/<url>')
def torrentz(url, mname=''):
    '''
    magnet link search engine: torrentz.eu, torrentz index include eztv.it,
    thepiratebay.org.
    '''
    if url == 'search':
        url = 'http://extratorrent.cc/search/?s_cat='
        sel = dialog.select('选择节目类型', ('电影', '电视'))
        if sel is -1:
            return
        if sel == 0:
            typ = '4'
        if sel == 1:
            typ = '8'
        if (not mname) or (mname and not typ):
            kb = Keyboard('', u'请输入搜索关键字')
            kb.doModal()
            if not kb.isConfirmed():
                return
            _mname = kb.getText()
            if mname:
                mname = _mname + ' ' + mname
            else:
                mname = _mname
        # stxt = '%s%s' % (typ, mstr.replace(' ', '+'))
        url = '%s%s&search=%s&page=1' % (url, typ, urllib.quote_plus(mname))
    #print url
    rsp = hc.urlopen(url)
    mitems = re.findall(
        r'href="(/torrent\/[0-9]+\/\S+html)" title="view (.*?) torrent"', rsp)

    print mitems
    menus = [{'label': i[1],
              'path': plugin.url_for('playlxmagnet', magnet=i[0])
              } for i in mitems]

    #cnt = re.findall(
    #    r'<h2 style="border-bottom: none">([,0-9]+) Torrents', rsp)
    #if cnt:
    #    cnt = int(cnt[0].replace(',', ''))
    #    pages = (cnt + 49) // 50
    #    currpg = int(url.split('=')[-1])
    #    urlpre = '='.join(url.split('=')[:-1])
    #    if currpg > 0:
    #        menus.append({'label': '上一页',
    #                      'path': plugin.url_for(
    #                          'torrentz', url='%s=%s' % (urlpre, currpg-1))})
    #    if (currpg+1) < pages:
    #        menus.append({'label': '下一页',
    #                      'path': plugin.url_for(
    #                          'torrentz', url='%s=%s' % (urlpre, currpg+1))})
    #    menus.insert(0, {'label':
    #                     '【第%s页/共%s页】返回上级菜单' % (currpg+1, pages),
    #                     'path': plugin.url_for('index')})
    return menus


def addmagnet(magnetid):
    '''
    add magnet link to cloud space.
    GET /req_del_list?flag=0&sessionid=sid&t=cachetime&info_hash=ihash
    Host: i.vod.xunlei.com
    '''
    data = {"urls": [{"id": 0, "url": magnetid}]}
    reqvideo = '%s/req_video_name?from=vlist&platform=0' % cloudurlpre
    rsp = xl.urlopen(reqvideo, data=data)
    minfo = json.loads(rsp)
    acdt = minfo['resp']['res'][0]
    data = {"urls": [{'id': acdt['id'],
                      "url": acdt['url'],
                      "name": acdt['name']}, ]}

    addvideo = '{0}/req_add_record?userid={1}&sessionid={2}&{3}'.format(
        cloudurlpre, xl.userid, xl.sid, 'folder_id=0&from=vlist&platform=0')
    rsp = xl.urlopen(addvideo, data=data)
    acinfo = json.loads(rsp)
    ihash = acinfo['resp']['res'][0]['url'][5:]
    return ihash


def gettaskid(magnet):
    '''
    add magnet link to lixian space.
    http://verify.xunlei.com/image?t=MVA&cachetime=1392381968052
    '''
    urlpre = '%s/%s' % (lxurlpre, 'interface')
    if magnet not in magnets:
        url = '%s/url_query?callback=queryUrl&u=%s&random=%s&tcache=%s' % (
            urlpre, urllib2.quote(magnet), randomtime, cachetime)
        print url
        rsp = xl.urlopen(url)
        print rsp
        success = re.search(r'queryUrl(\(1,.*\))\s*$', rsp, re.S)
        if not success:
            already_exists = re.search(r"queryUrl\(-1,'([^']{40})", rsp, re.S)
            if already_exists:
                return already_exists.group(1)
            raise NotImplementedError(repr(rsp))
        args = success.group(1).decode('utf-8')
        args = eval(args.replace('new Array', ''))
        print args
        _, cid, tsize, btname, _, names, sizes_, sizes, _, types, \
            findexes, _, timestamp, _ = args

        def toList(x):
            if type(x) in (list, tuple):
                return x
            else:
                return [x]
        data = {'uid': xl.userid, 'btname': btname, 'cid': cid, 'tsize': tsize,
                'findex': ''.join(x+'_' for x in toList(findexes)),
                'size': ''.join(x+'_' for x in toList(sizes)),
                'from': '0'}
        jsonp = 'jsonp%s' % cachetime
        commiturl = '%s/bt_task_commit?callback=%s' % (urlpre, jsonp)
        rsp = xl.urlopen(commiturl, data=urllib.urlencode(data))
        while '"progress":-11' in rsp or '"progress":-12' in rsp:
            vfcode = xl.getvfcode(
                'http://verify2.xunlei.com/image?t=MVA&cachetime')
            if not vfcode:
                return
            data['verify_code'] = vfcode
            rsp = xl.urlopen(commiturl, data=urllib.urlencode(data))
        tids = re.findall(r'"id":"(\d+)"', rsp)
        if not tids:
            return
        magnets[magnet] = tids[0]
    tid = magnets[magnet]
    return tid


def getcloudvideourl(bturl, title):
    '''
    resolve video url
    '''
    dlpre = '{0}/req_get_method_vod'.format(cloudurlpre)
    # dl = '{0}/vod_dl_all?userid={1}&gcid={2}&filename={3}&t={4}'.format(
    #    cloudurlpre, xl.userid, gcid,
    #    urllib2.quote(title), cachetime)
    dl = '{0}?url={1}&platform=0&userid={2}&sessionid={3}&cache={4}'.format(
        dlpre, urllib.quote(bturl), xl.userid, xl.sid, cachetime)
    rsp = xl.urlopen(dl)

    vturls = json.loads(rsp)
    typ = {'356608': '1080P', '282880': '720P', '225536': '标清'}

    vtyps = [(typ[str(i['spec_id'])], i['vod_url_dt17'])
             for i in vturls['resp']['vodinfo_list']
             if str(i['spec_id']) in typ]
    # vtyps = [(typ[k], v['url'])
    #         for (k, v) in vturls.iteritems() if 'url' in v]
    # vtyps.insert(0, ('源码', surl))
    # selitem = dialog.select('清晰度', [v[0] for v in vtyps])
    # if selitem is -1: return
    # vtyp = vtyps[selitem]
    return vtyps


@plugin.route('/dbmovie')
def dbmovie():
    '''
    get douban movie catetory list
    '''
    if '类型' not in filters:
        rsp = hc.urlopen('http://movie.douban.com/category/')
        fts = re.findall(
            r'class="label">([^>]+?)</h4>\s+<ul>(.*?)</ul>', rsp, re.S)
        typpatt = re.compile(r'<a href="#">([^>]+?)</a>')
        for ft in fts:
            typs = typpatt.findall(ft[1])
            if '类型' not in ft[0]:
                typs.insert(0, '不限')
            filters[ft[0]] = tuple(typs)
    typs = filters['类型']
    menus = [{'label': t,
              'path': plugin.url_for(
                  'dbcate', typ=str({'types[]': t}), page=1),
              } for t in typs]
    return menus


@plugin.route('/dbcate/<typ>/<page>')
def dbcate(typ, page):
    '''
    get catetory content
    '''
    params = {'district': '', 'era': '', 'category': 'all',
              'unwatched': 'false', 'available': 'false', 'sortBy': 'score',
              'page': page, 'ck': 'null', 'types[]': ''}
    typ = eval(typ)
    if 'district' in typ and not typ['district']:
        sel = dialog.select('地区', filters['地区'])
        if sel is -1:
            return
        typ['district'] = filters['地区'][sel]
    if 'era' in typ and not typ['era']:
        sel = dialog.select('年代', filters['年代'])
        if sel is -1:
            return
        typ['era'] = filters['年代'][sel]
    params.update(typ)
    data = urllib.urlencode(params)
    rsp = hc.urlopen('http://movie.douban.com/category/q',
                     data=data.replace(urllib2.quote('不限'), ''))
    minfo = json.loads(rsp)

    menus = [{'label': '[%s].%s[%s][%s]' % (m['release_year'], m['title'],
                                            m['rate'], m['abstract']),
              'path': plugin.url_for(
                  'searchdisp',
                  mname='%s/subject/%s' % (dbapi, m['url'].split('/')[-2])),
              'thumbnail': m['poster'],
              } for m in minfo['subjects']]
    if not menus:
        return
    if int(page) > 1:
        menus.append({'label': '上一页', 'path': plugin.url_for(
            'dbcate', typ=str(typ), page=int(page)-1)})
    menus.append({'label': '下一页', 'path': plugin.url_for(
        'dbcate', typ=str(typ), page=int(page)+1)})
    ntyp = typ.copy()
    ntyp.update({'district': '', 'era': ''})
    menus.insert(0, {
        'label': '【按照条件过滤】【地区】【年代】选择',
        'path': plugin.url_for('dbcate', page=1, typ=str(ntyp)), }
    )
    return menus


@plugin.route('/dbntop')
def dbntop():
    '''
    show douban new movie top list
    img, title, info, rate
    '''
    rsp = hc.urlopen('http://movie.douban.com/chart')
    mstr = r'%s%s' % ('nbg".*?(subject/\d+).*?src="(.*?)" alt="(.*?)"',
                      '.*?class="pl">(.*?)</p>.*?rating_nums">(.*?)<')
    mpatt = re.compile(mstr, re.S)
    mitems = mpatt.findall(rsp)

    menus = [{'label': '{0}. {1}[{2}][{3}]'.format(s, i[2], i[4], i[3]),
              'path': plugin.url_for(
                  'searchdisp',
                  mname='%s/%s' % (dbapi, i[0])),
              'thumbnail': i[1], }
             for s, i in enumerate(mitems)]
    return menus


@plugin.route('/dbsearch/<url>')
def dbsearch(url):
    '''
    douban movie tag search, support multiple tag
    '''
    if url == 'search':
        urlpre = 'http://movie.douban.com/tag'
        kb = Keyboard('', u'请输入搜索关键字')
        kb.doModal()
        if not kb.isConfirmed():
            return
        sstr = kb.getText()
        url = '%s/%s?start=0' % (urlpre, urllib2.quote(sstr))
    rsp = hc.urlopen(url)
    rtxt = r'%s%s' % ('class="nbg".*?(subject/\d+).*?src="(.*?)" alt="(.*?)"',
                      '.*?class="pl">(.*?)</p>.*?rating_nums">(.*?)<')
    patt = re.compile(rtxt, re.S)
    mitems = patt.findall(rsp)
    if not mitems:
        return
    menus = [{'label': '{0}. {1}[{2}][{3}]'.format(s, i[2], i[4], i[3]),
              'path': plugin.url_for(
                  'searchdisp', mname='%s/%s' % (dbapi, i[0])),
              'thumbnail': i[2], }
             for s, i in enumerate(mitems)]

    pages = re.findall(r'class="thispage" data-total-page="(\d+)">(\d+)<', rsp)
    if pages:
        urlpre = '='.join(url.split('=')[:-1])
        currpg = int(pages[0][1])
        totalpg = int(pages[0][0])
        if currpg > 1:
            menus.append({'label': '上一页',
                          'path': plugin.url_for(
                              'dbsearch',
                              url='%s=%s' % (urlpre, (currpg-1)*20))})
        if currpg < totalpg:
            menus.append({'label': '下一页',
                          'path': plugin.url_for(
                              'dbsearch',
                              url='%s=%s' % (urlpre, (currpg+1)*20))})
        menus.insert(0, {'label':
                         '【第%s页/共%s页】返回上级菜单' % (currpg, totalpg),
                         'path': plugin.url_for('index')})
    return menus


# @plugin.route('/dbscraper/<url>', name='dbsearch')
@plugin.route('/dbscraper/<url>', name='dbtop250')
def dbscraper(url):
    '''
    由于豆瓣提供的tag搜索api不支持多tag关联查询，暂时先用dbsearch方法
    '''
    if url == 'search':
        kb = Keyboard('', u'请输入搜索关键字')
        kb.doModal()
        if not kb.isConfirmed():
            return
        sstr = kb.getText()
        url = '%s/search?tag=%s&start=0' % (dbapi, sstr)
    if url == 'dbtop250':
        url = '%s/top250?count=20&start=0' % dbapi
    view = 'dbsearch' if 'search' in url else 'dbtop250'
    rsp = hc.urlopen(url)
    data = json.loads(rsp)
    movs = data['subjects']
    if not movs:
        return
    menus = [{
        'label': '{0}.{1}[{2}年][{3}分][{4}人收藏]'.format(
            s, m['title'].encode('utf-8'), m['year'], m['rating']['average'],
            m['collect_count']
        ),
        'path': plugin.url_for(
            'searchdisp',
            mname=str((m['title'].encode('utf-8'),
                       m['original_title'].encode('utf-8')))
        ),
        'thumbnail': m['images']['large'],
    } for s, m in enumerate(movs)]

    start = data['start']
    urlpre = '='.join(url.split('=')[:-1])
    if start != 0:
        menus.append({'label': '上一页',
                      'path': plugin.url_for(
                          view, url='%s=%s' % (urlpre, start-20))})
    menus.append({'label': '下一页',
                  'path': plugin.url_for(
                      view, url='%s=%s' % (urlpre, start+20))})
    menus.insert(0, {'label': '【当前%s页】返回上级菜单' % str(start//20 + 1),
                     'path': plugin.url_for('index')})
    return menus


@plugin.route('/searchdisp/<mname>')
def searchdisp(mname):
    '''
    magnet link search engine dispatch
    '''
    if 'http' in mname:
        rsp = hc.urlopen(mname)
        data = json.loads(rsp)
        _mname = (data['title'].encode('utf-8'),
                  data['original_title'].encode('utf-8'))
    else:
        _mname = eval(mname)
    sel = dialog.select('选择搜索方式', ('BTdigg(中文)', 'TorrentZ(英文)', 'BTdigg(英文)'))
    if sel is -1:
        return
    if sel is 0:
        menus = btdigg('search', mname=_mname[0])
    elif sel is 1:
        menus = torrentz('search', mname=_mname[1])
    else:
        menus = btdigg('search', mname=_mname[1])
    return menus


class HttpClient(object):
    '''
    http client, support cookie
    '''
    def __init__(self, cookiefile=None):
        self.cookiejar = cookielib.LWPCookieJar()
        if cookiefile and os.path.exists(cookiefile):
            self.cookiejar.load(
                cookiefile, ignore_discard=True, ignore_expires=True)
        self.userid = self.getcookieatt('.xunlei.com', 'userid')
        self.sid = self.getcookieatt('.xunlei.com', 'sessionid')
        self.opener = urllib2.build_opener(
            urllib2.HTTPCookieProcessor(self.cookiejar))

        self.headers = {
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 '
            '(KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36',
            'Accept-encoding': 'gzip,deflate',
        }

    class SmartRedirectHandler(urllib2.HTTPRedirectHandler):
        def http_error_302(self, req, fp, code, msg, headers):
            infourl = urllib.addinfourl(fp, headers, req.get_full_url())
            infourl.status = code
            infourl.code = code
            return infourl
        http_error_301 = http_error_303 = http_error_307 = http_error_302

    def urlopen(self, url, redirect=True, **args):
        if 'data' in args and type(args['data']) == dict:
            args['data'] = json.dumps(args['data'])
            # arg['data'] = urllib.urlencode(args['data'])
            self.headers['Content-Type'] = 'application/json'
        if not redirect:
            self.opener = urllib2.build_opener(
                self.SmartRedirectHandler(),
                urllib2.HTTPCookieProcessor(self.cookiejar))
        rs = self.opener.open(
            urllib2.Request(url, headers=self.headers, **args), timeout=30)
        if 'Location' in rs.headers:
            return rs.headers.get('Location', '')
        if rs.headers.get('content-encoding', '') == 'gzip':
            content = gzip.GzipFile(fileobj=StringIO(rs.read())).read()
        else:
            content = rs.read()
        return content

    def getcookieatt(self, domain, attr):
        if domain in self.cookiejar._cookies and attr in \
           self.cookiejar._cookies[domain]['/']:
            return self.cookiejar._cookies[domain]['/'][attr].value

    def getvfcode(self, url):
        cdg = captcha.CaptchaDialog(url)
        cdg.doModal()
        confirmed = cdg.isConfirmed()
        if not confirmed:
            return
        info = cdg.getText()
        # del cdg
        vfcode, vfcookie = info.split('||')
        k, v = vfcookie.split('; ')[0].split('=')
        self.setcookie('.xunlei.com', k, v)
        return vfcode

    def setcookie(self, domain, k, v):
        c = cookielib.Cookie(
            version=0, name=k, value=v, comment_url=None, port_specified=False,
            domain=domain, domain_specified=True, path='/', secure=False,
            domain_initial_dot=True, path_specified=True, expires=None,
            discard=True, comment=None, port=None, rest={}, rfc2109=False)
        self.cookiejar.set_cookie(c)
        self.cookiejar.save(cookiefile, ignore_discard=True)

    def md5(self, s):
        import hashlib
        return hashlib.md5(s).hexdigest().lower()

dialog = xbmcgui.Dialog()
ppath = plugin.addon.getAddonInfo('path')
cookiefile = os.path.join(ppath, 'cookie.dat')
dbapi = 'https://api.douban.com/v2/movie'
cloudurlpre = 'http://i.vod.xunlei.com'
lxurlpre = 'http://dynamic.cloud.vip.xunlei.com'
filters = plugin.get_storage('ftcache', TTL=1440)
magnets = plugin.get_storage('ftcache')

cachetime = int(time.time()*1000)
randomtime = '%s%06d.%s' % (cachetime, randint(0, 999999),
                            randint(100000000, 9999999999))

xl = HttpClient(cookiefile)
hc = HttpClient()

if __name__ == '__main__':
    plugin.run()
