From be1ad84d5dd1f33648ab15899edf95110891fdd9 Mon Sep 17 00:00:00 2001 From: yfang1644 Date: Thu, 26 Mar 2020 19:15:30 +0800 Subject: [PATCH] add referer to mgtv, remove xbmcswift2 in pptv/sohu/iqiyi/qq/bilivideo --- addons.xml | 11 +- addons.xml.md5 | 2 +- plugin.video.bilivideo/addon.xml | 3 +- plugin.video.bilivideo/default.py | 275 ++++++----- plugin.video.bilivideo/icon.png | Bin 10092 -> 8097 bytes plugin.video.bilivideo/lib/bilibili.py | 23 +- plugin.video.bilivideo/lib/bilivideo.py | 12 +- ...0.zip => plugin.video.bilivideo-0.9.1.zip} | Bin 396038 -> 391354 bytes plugin.video.bilivideo/resources/settings.xml | 2 - plugin.video.mgtv/addon.xml | 2 +- plugin.video.mgtv/default.py | 16 +- plugin.video.mgtv/lib/mgtv.py | 8 +- ...-1.1.5.zip => plugin.video.mgtv-1.1.6.zip} | Bin 14291 -> 14347 bytes plugin.video.pptv/addon.xml | 1 - plugin.video.pptv/default.py | 177 ++++--- plugin.video.pptv/lib/pptv.py | 3 +- plugin.video.pptv/plugin.video.pptv-2.2.1.zip | Bin 146174 -> 146258 bytes plugin.video.qq/addon.xml | 2 +- plugin.video.qq/default.py | 19 +- plugin.video.qq/lib/qq.py | 5 +- ...qq-2.0.0.zip => plugin.video.qq-2.0.1.zip} | Bin 57350 -> 55262 bytes plugin.video.sohuvideo/addon.xml | 1 - plugin.video.sohuvideo/default.py | 454 +++++++++--------- plugin.video.sohuvideo/lib/sohu.py | 4 +- .../plugin.video.sohuvideo-2.6.4.zip | Bin 64461 -> 64445 bytes plugin.video.youku/addon.xml | 3 +- plugin.video.youku/default.py | 225 +++++---- plugin.video.youku/lib/youku.py | 4 +- ...2.0.1.zip => plugin.video.youku-2.0.2.zip} | Bin 85939 -> 86106 bytes 29 files changed, 658 insertions(+), 594 deletions(-) rename plugin.video.bilivideo/{plugin.video.bilivideo-0.9.0.zip => plugin.video.bilivideo-0.9.1.zip} (91%) rename plugin.video.mgtv/{plugin.video.mgtv-1.1.5.zip => plugin.video.mgtv-1.1.6.zip} (56%) rename plugin.video.qq/{plugin.video.qq-2.0.0.zip => plugin.video.qq-2.0.1.zip} (83%) rename plugin.video.youku/{plugin.video.youku-2.0.1.zip => plugin.video.youku-2.0.2.zip} (88%) diff --git a/addons.xml b/addons.xml index 4011d63..8ae3779 100644 --- a/addons.xml +++ b/addons.xml @@ -56,7 +56,6 @@ version="2.2.1" provider-name="yfang1644"> - @@ -131,7 +130,6 @@ version="2.6.4" provider-name="Taxigps,yfang1644"> - @@ -329,7 +327,7 @@ @@ -483,7 +481,7 @@ @@ -530,10 +528,9 @@ - @@ -779,7 +776,7 @@ diff --git a/addons.xml.md5 b/addons.xml.md5 index 58ae42d..51ce6f6 100644 --- a/addons.xml.md5 +++ b/addons.xml.md5 @@ -1 +1 @@ -4deb70e81bfa6ec8e3adfe0dfdd9e238 addons.xml +b30a37c1fc05212a24ad5ddf9e9276f6 addons.xml diff --git a/plugin.video.bilivideo/addon.xml b/plugin.video.bilivideo/addon.xml index 061ce64..7c3d7dd 100644 --- a/plugin.video.bilivideo/addon.xml +++ b/plugin.video.bilivideo/addon.xml @@ -1,10 +1,9 @@ - diff --git a/plugin.video.bilivideo/default.py b/plugin.video.bilivideo/default.py index b678715..b8ee935 100644 --- a/plugin.video.bilivideo/default.py +++ b/plugin.video.bilivideo/default.py @@ -1,7 +1,11 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -from xbmcswift2 import Plugin, xbmc, xbmcgui +import xbmc +from xbmcgui import Dialog, ListItem +from xbmcplugin import addDirectoryItem, endOfDirectory, setContent +import xbmcaddon + from lib.bilibili import Bilibili from lib.subtitle import subtitle_offset from lib.bilivideo import video_from_vid @@ -18,11 +22,10 @@ from common import get_html from json import loads -plugin = Plugin() -url_for = plugin.url_for - bilibili = Bilibili() +__assfile__ = xbmc.translatePath("special://temp/tmp.ass") + class BiliPlayer(xbmc.Player): def __init__(self): self.subtitle = '' @@ -50,92 +53,79 @@ def onPlayBackStarted(self): def previous_page(endpoint, page, total_page, **kwargs): if int(page) > 1: - page = str(int(page) - 1) - return [{'label': u'上一页 - {0}/{1}'.format(page, str(total_page)), 'path': plugin.url_for(endpoint, page=page, **kwargs)}] - else: - return [] + li = ListItem('上一页 - {0}/{1}'.format(page, str(total_page))) + filter = kwargs['filter'] + filter = dict(parse_qsl(filter)) + kwargs.update(filter) + kwargs['mode'] = endpoint + kwargs['page'] = int(page) - 1 + u = sys.argv[0] + '?' + urlencode(kwargs) + addDirectoryItem(int(sys.argv[1]), u, li, True) def next_page(endpoint, page, total_page, **kwargs): if int(page) < int(total_page): - page = str(int(page) + 1) - return [{'label': u'下一页 - {0}/{1}'.format(page, str(total_page)), 'path': plugin.url_for(endpoint, page=page, **kwargs)}] - else: - return [] - -def get_av_item(aid, **kwargs): - result = bilibili.get_av_list(aid) - if not result: - return {'label': '(空)', 'path': plugin.url_for('stay')} - - item = dict(**kwargs) - if len(result) == 1: - vid = result[0].get('vid', '') - #item['icon'] = kwargs.get('thumbnail') - item['is_playable'] = True - if len(vid) > 0: - item['label'] += '(QQ)' - else: - vid = '0' - item['path'] = plugin.url_for('playvideo', cid=result[0]['cid'], vid=vid, name=item['label'].encode('utf-8')) - item['info'] = {'title': item['label']} - else: - item['path'] = plugin.url_for('list_video', aid=aid) - return item - - -@plugin.route('/stay') -def stay(): - pass - + li = ListItem('下一页 - {0}/{1}'.format(page, str(total_page))) + filter = kwargs['filter'] + filter = dict(parse_qsl(filter)) + kwargs.update(filter) + kwargs['mode'] = endpoint + kwargs['page'] = int(page) + 1 + u = sys.argv[0] + '?' + urlencode(kwargs) + addDirectoryItem(int(sys.argv[1]), u, li, True) + + +def playvideo(params): + name = params['name'] + vid = params['vid'] + cid = params['cid'] + level = int(xbmcaddon.Addon().getSetting('resolution')) -@plugin.route('/playvideo////') -def playvideo(cid, vid, name): - level = int(plugin.addon.getSetting('resolution')) if vid != '0': urls = video_from_qq(vid, level=level) else: urls = video_from_vid(cid, level=level) stack_url = 'stack://' + ' , '.join(urls) - danmu = plugin.addon.getSetting('danmu') + danmu = xbmcaddon.Addon().getSetting('danmu') - playlist = xbmc.PlayList(1) + playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() - list_item = xbmcgui.ListItem(name) + list_item = ListItem(name) if danmu == 'true': bilibili.parse_subtitle(cid) - player.setSubtitle(bilibili._get_tmp_dir() + '/tmp.ass') + player.setSubtitle(__assfile__) playlist.add(stack_url, list_item) player.play(playlist) #while(not xbmc.abortRequested): xbmc.sleep(500) - # plugin.set_resolved_url(stack_url) -@plugin.route('/list_video//') -def list_video(aid): - plugin.set_content('TVShows') +def list_video(params): + aid = params['aid'] result = bilibili.get_av_list(aid) - items = [] for x in result: vid = x.get('vid', '') if len(vid) < 1: vid = '0' - items.append({ - 'label': x['pagename'], - 'path': plugin.url_for('playvideo', cid=x['cid'], vid=vid, name=x['pagename'].encode('utf-8')), - 'is_playable': True, - 'info': {'title': x['pagename'], 'type':'video'} - }) - return items + li = ListItem(x['pagename']) + li.setInfo(type='Video', infoLabels={'title': x['pagename']}) + req = { + 'mode': 'playvideo', + 'cid': x['cid'], + 'vid': vid, + 'name': x['pagename'].encode('utf-8') + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, False) + + setContent(int(sys.argv[1]), 'tvshows') + endOfDirectory(int(sys.argv[1])) -@plugin.route('/search') -def search(): - plugin.set_content('TVShows') +def search(params): keyboard = xbmc.Keyboard('', '请输入关键字 (片名/AV)') xbmc.sleep(1500) keyboard.doModal() @@ -151,7 +141,6 @@ def search(): key = 'getMixinFlowList-jump-keyword-' + keyword.decode('utf-8') lists = jsdata['flow'][key]['result'] - items = [] for x in lists: for y in x['data']: title = y.get('title') @@ -174,27 +163,32 @@ def search(): type = y.get('typename', '') type = '(' + type + ')' aid = y.get('aid') + li = ListItem(title + type, thumbnailImage=cover) if aid: - items.append({ - 'label': title + type, - 'path': url_for('list_video', aid=aid), - 'thumbnail': cover, - 'info': {'title': title, 'plot': y.get('description')} - }) + li.setInfo(type='Video', + infoLabels={'title':title, 'plot': y.get('description')}) + req = { + 'mode': 'list_video', + 'aid': aid + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, False) else: - items.append({ - 'label': title + type, - 'path': url_for('season', link=link), - 'thumbnail': cover, - 'info': {'title': title, 'plot': y.get('desc')} - }) + li.setInfo(type='Video', + infoLabels={'title':title, 'plot': y.get('desc')}) + req = { + 'mode': 'season', + 'link': link + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) - return items + setContent(int(sys.argv[1]), 'tvshows') + endOfDirectory(int(sys.argv[1])) -@plugin.route('/season//') -def season(link): - plugin.set_content('TVShows') +def season(params): + link = params['link'] html = get_html(link) data = re.search('__INITIAL_STATE__\s*=\s*({.+?\});', html) jsdata = loads(data.group(1)) @@ -203,11 +197,11 @@ def season(link): title = info['title'] desc = info['evaluate'] - items = [{ - 'label': '[COLOR FFDEB887]%s[/COLOR]' % title, - 'path': url_for('stay'), - 'info': {'title': title, 'plot': desc} - }] + li = ListItem('[COLOR FFDEB887]%s[/COLOR]' % title) + li.setInfo(type='Video', infoLabels={'title': title, 'plot':desc}) + u = sys.argv[0] + addDirectoryItem(int(sys.argv[1]), u, li, False) + for item in jsdata['epList']: title = item.get('titleFormat') if title is None: title = item.get('title') @@ -217,26 +211,30 @@ def season(link): vid = item['vid'] if vid == '': vid = 0 title = title.encode('utf-8') - items.append({ - 'label': title, - 'path': plugin.url_for('playvideo', cid=cid, vid=vid, name=title), - 'thumbnail': cover, - 'is_playable': True, - 'info': {'title': title, 'plot': item['longTitle']} - }) + li = ListItem(title, thumbnailImage=cover) + li.setInfo(type='Video', + infoLabels={'title': title, 'plot': item['longTitle']}) + req = { + 'mode': 'playvideo', + 'cid': cid, + 'vid': vid, + 'name': title, + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, False) - return items + setContent(int(sys.argv[1]), 'tvshows') + endOfDirectory(int(sys.argv[1])) -@plugin.route('/select//') -def select(name): +def select(params): url = 'https://www.bilibili.com/{}/index/' - html = get_html(url.format(name)) + html = get_html(url.format(params['name'])) data = re.search('__INITIAL_STATE__\s*=\s*({.+?\});', html) jsdata = loads(data.group(1)) filters = {} - dialog = xbmcgui.Dialog() + dialog = Dialog() for x in jsdata['filters']: title = x['title'] key = x['key'] @@ -246,30 +244,37 @@ def select(name): sel = dialog.select(title, lst) if sel >=0: filters[key] = item[sel] - return category(name, page=1, filter=urlencode(filters)) + filters['name'] = params['name'] + filters['page'] = 1 + category(filters) + +def category(params): + name = params['name'] + page = params['page'] + li = ListItem('[COLOR yellow][筛选过滤][/COLOR]') + req = { + 'mode': 'select', + 'name': name + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) -@plugin.route('/category////') -def category(name, page, filter): - plugin.set_content('TVShows') type = {'movie': 2, 'tv':5, 'documentary': 3} - req = dict(parse_qsl(filter)) - req['page'] = page + req = params + del (req['name']) req['season_type'] = type[name] req['pagesize'] = 20 - req['type'] = 1 + req['type'] = 1 # unknow function, but required filter = urlencode(req) api = 'https://api.bilibili.com/pgc/season/index/result?' html = get_html(api + filter) data = loads(html) - items = [{'label': '[COLOR yellow][筛选过滤][/COLOR]', - 'path': url_for('select', name=name)}] - total= int(data['data']['total']) total_page = (total + 19) // 20 - items += previous_page('category', page, total_page, name=name, filter=filter) + previous_page('category', page, total_page, name=name, filter=filter) for item in data['data']['list']: title = item['title'] extra = item['index_show'] @@ -278,31 +283,53 @@ def category(name, page, filter): badge = u'[COLOR magenta]({})[/COLOR]'.format(badge) else: badge = '' - items.append({ - 'label': title + '(' + extra + ')' + badge, - 'path': plugin.url_for('season', link=item['link']), + li = ListItem(title + '(' + extra + ')' + badge) + req = { + 'mode': 'season', + 'link': item['link'], 'thumbnail': item['cover'] - }) + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) - items += next_page('category', page, total_page, name=name, filter=filter) - return items + next_page('category', page, total_page, name=name, filter=filter) + setContent(int(sys.argv[1]), 'tvshows') + endOfDirectory(int(sys.argv[1])) -@plugin.route('/') def root(): CATEGORY = {'电影': 'movie', '电视剧': 'tv', '纪录片': 'documentary'} + li = ListItem('[COLOR magenta][搜索][/COLOR]') + u = sys.argv[0] + '?mode=search' + addDirectoryItem(int(sys.argv[1]), u, li, True) - yield { - 'label': '搜索...', - 'path': url_for('search') - } - req = urlencode({'page':1}) for item in CATEGORY: - yield { - 'label': item, - 'path': url_for('category', name=CATEGORY[item], page=1, filter=req) + li = ListItem(item) + req = { + 'mode': 'category', + 'name': CATEGORY[item], + 'page': 1, } - - -if __name__ == '__main__': - plugin.run() + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) + endOfDirectory(int(sys.argv[1])) + +# main programs goes here ######################################### +runlist = { + 'category': 'category(params)', + 'season': 'season(params)', + 'search': 'search(params)', + 'select': 'select(params)', + 'list_video': 'list_video(params)', + 'playvideo': 'playvideo(params)' +} + +params = sys.argv[2][1:] +params = dict(parse_qsl(params)) + +mode = params.get('mode') +if mode: + del (params['mode']) + exec(runlist[mode]) +else: + root() diff --git a/plugin.video.bilivideo/icon.png b/plugin.video.bilivideo/icon.png index befaad9108adda8a3b8adcccaf0d14fe34364353..cccb6a1c606e1821f880e2bb5d00f477823f1fda 100644 GIT binary patch literal 8097 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 LKyL>?IN|>RPyj+q delta 25989 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 shWx)SL}~Gl2f%$0j0%R - - diff --git a/plugin.video.mgtv/addon.xml b/plugin.video.mgtv/addon.xml index ede2183..27f6006 100644 --- a/plugin.video.mgtv/addon.xml +++ b/plugin.video.mgtv/addon.xml @@ -1,7 +1,7 @@ diff --git a/plugin.video.mgtv/default.py b/plugin.video.mgtv/default.py index 89d5fc1..ceb1379 100644 --- a/plugin.video.mgtv/default.py +++ b/plugin.video.mgtv/default.py @@ -4,10 +4,8 @@ from xbmcswift2 import Plugin, xbmcgui from bs4 import BeautifulSoup from json import loads -from urllib import quote_plus -import re from common import get_html, r1 -from lib.mgtv import video_from_vid +from lib.mgtv import video_from_vid, quote_plus plugin = Plugin() url_for = plugin.url_for @@ -81,8 +79,8 @@ def search(): @plugin.route('/changeList//') def changeList(url): html = get_html(url) - tree = BeautifulSoup(html, 'html.parser') - soup = tree.find_all('div', {'class': 'm-tag-type'}) + soup = BeautifulSoup(html, 'html.parser') + tree = soup.findAll('div', {'class': 'm-tag-type'}) surl = url.split('/') purl = surl[-1].split('-') @@ -118,11 +116,10 @@ def changeList(url): def episodelist(url, id, page): if int(id) == 0: url = httphead(url) - print "XXXXXXXXXXXXXXXXXXX", url html = get_html(url) - l = re.compile('window.location = "(.+?)"').findall(html) + l = r1('window.location = "(.+?)"', html) if l: - url = httphead(l[0]) + url = httphead(l) if url[-1] == '/': # is a directory html = get_html(url) id = r1('vid:\s*(\d+)', html) @@ -208,7 +205,7 @@ def mainlist(url, filter): exinfo = '' # pay info - pay = item.find('i', {'class': 'v-mark-v5'}) + pay = item.find('i', {'class': 'mark-v'}) if pay: pay = BANNER_FMT2 % ('(' + pay.text + ')') else: @@ -263,6 +260,7 @@ def root(): 'path': url_for('mainlist', url=url, filter='0'), + 'thumbnail': item.get('channelIcon'), 'info': {'title': item['title'], 'plot': item['vclassName']} } diff --git a/plugin.video.mgtv/lib/mgtv.py b/plugin.video.mgtv/lib/mgtv.py index 48c4830..0444b2a 100644 --- a/plugin.video.mgtv/lib/mgtv.py +++ b/plugin.video.mgtv/lib/mgtv.py @@ -5,7 +5,7 @@ import re from json import loads from os.path import dirname -from random import randrange +from random import choice if sys.version[0]=='3': from urllib.parse import urlsplit, quote_plus maketrans = bytes.maketrans @@ -79,8 +79,7 @@ def video_from_vid(self, vid, **kwargs): content = loads(html) streams = content['data']['stream'] domains = content['data']['stream_domain'] - index = randrange(len(domains)) - domain = domains[index] + domain = choice(domains) level = kwargs.get('level', 0) @@ -91,8 +90,7 @@ def video_from_vid(self, vid, **kwargs): url = domain + url content = loads(get_html(url)) url = content['info'] - - return re.compile("(.*m3u8)").findall(url) + return [url + '|Referer="https://www.mgtv.com"'] def video_from_url(self, url, **kwargs): vid = self.vid_from_url(url) diff --git a/plugin.video.mgtv/plugin.video.mgtv-1.1.5.zip b/plugin.video.mgtv/plugin.video.mgtv-1.1.6.zip similarity index 56% rename from plugin.video.mgtv/plugin.video.mgtv-1.1.5.zip rename to plugin.video.mgtv/plugin.video.mgtv-1.1.6.zip index b8a5fa2103b72a36b0b024588d9327fb7fc94c1c..c7aab396ae4ae255c0642c7728aada92ea57fe04 100644 GIT binary patch delta 4596 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 delta 4545 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 diff --git a/plugin.video.pptv/addon.xml b/plugin.video.pptv/addon.xml index a46d14a..4716cbe 100644 --- a/plugin.video.pptv/addon.xml +++ b/plugin.video.pptv/addon.xml @@ -4,7 +4,6 @@ version="2.2.1" provider-name="yfang1644"> - diff --git a/plugin.video.pptv/default.py b/plugin.video.pptv/default.py index b889568..123136a 100644 --- a/plugin.video.pptv/default.py +++ b/plugin.video.pptv/default.py @@ -1,19 +1,18 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -from xbmcswift2 import Plugin, xbmc, xbmcgui -from xbmcgui import ListItem, Dialog +import xbmc +from xbmcgui import Dialog, ListItem +from xbmcplugin import addDirectoryItem, endOfDirectory, setContent +import xbmcaddon from bs4 import BeautifulSoup import re from json import loads from common import get_html -from lib.pptv import video_from_vid, urlencode +from lib.pptv import video_from_vid, urlencode, parse_qsl # Plugin constants -plugin = Plugin() -url_for = plugin.url_for - PPTV_LIST = 'http://list.pptv.com/' PPTV_TV_LIST = 'http://live.pptv.com/list/tv_list' VIP = '[COLOR FFFF00FF](VIP)[/COLOR]' @@ -21,40 +20,37 @@ def previous_page(endpoint, page, total_page, **kwargs): if int(page) > 1: - page = str(int(page) - 1) - return [{'label': u'上一页 - {0}/{1}'.format(page, str(total_page)), 'path': url_for(endpoint, page=page, **kwargs)}] - else: - return [] - + li = ListItem('上一页 - {0}/{1}'.format(page, str(total_page))) + kwargs['mode'] = endpoint + kwargs['page'] = int(page) - 1 + u = sys.argv[0] + '?' + urlencode(kwargs) + addDirectoryItem(int(sys.argv[1]), u, li, True) def next_page(endpoint, page, total_page, **kwargs): if int(page) < int(total_page): - page = str(int(page) + 1) - return [{'label': u'下一页 - {0}/{1}'.format(page, str(total_page)), 'path': url_for(endpoint, page=page, **kwargs)}] - else: - return [] + li = ListItem('下一页 - {0}/{1}'.format(page, str(total_page))) + kwargs['mode'] = endpoint + kwargs['page'] = int(page) + 1 + u = sys.argv[0] + '?' + urlencode(kwargs) + addDirectoryItem(int(sys.argv[1]), u, li, True) -@plugin.route('/playvideo////') -def playvideo(vid, name, image): - quality = int(plugin.addon.getSetting('movie_quality')) - - urls = video_from_vid(vid, level=quality) +def playvideo(params): + quality = int(xbmcaddon.Addon().getSetting('movie_quality')) + urls = video_from_vid(params['vid'], level=quality) stackurl = 'stack://' + ' , '.join(urls) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() - list_item = ListItem(name, thumbnailImage=image) - list_item.setInfo(type="video", infoLabels={"Title": name}) - playlist.add(stackurl, li) + list_item = ListItem(params['name'], thumbnailImage=params['thumbnail']) + list_item.setInfo(type="video", infoLabels={"Title": params['name']}) + playlist.add(stackurl, list_item) xbmc.Player().play(playlist) xbmc.sleep(500) - #plugin.set_resolved_url(stackurl) -@plugin.route('/search') -def search(): - return [] +def search(params): + return keyboard = xbmc.Keyboard('', '请输入搜索内容') keyboard.doModal() @@ -65,15 +61,14 @@ def search(): xbmc.executebuiltin('Container.Update(%s)' % u) -@plugin.route('/select//') -def select(url): - html = get_html(url) +def select(params): + html = get_html(params['url']) # html has an extra html = re.sub('<\/dt>\n *<\/dt>', '<\/dt>', html) - tree = BeautifulSoup(html, 'html.parser') - filter = tree.find_all('div', {'class': 'sear-menu'}) + soup = BeautifulSoup(html, 'html.parser') + filter = soup.findAll('div', {'class': 'sear-menu'}) - filter = filter[0].find_all('dl') + filter = filter[0].findAll('dl') dialog = Dialog() for item in filter: @@ -108,49 +103,47 @@ def select(url): sel = dialog.select(title, list) if sel >= 0 and sel != sel0: url = u[sel] - return videolist(url, 1) + req = {'url': url, 'page':1} + videolist(req) -@plugin.route('/episodelist//') -def episodelist(url): - plugin.set_content('TVShows') - html = get_html(url) +def episodelist(params): + html = get_html(params['url']) playcfg = re.compile('var webcfg\s?=\s?({.+?);\n').findall(html) if playcfg: jsplay = loads(playcfg[0]) else: - return [] + return - items = [] content = jsplay['share_content'] for item in jsplay['playList']['data']['list']: vip = '' if int(item['vip']) == 0 else VIP new = NEW if item.get('isNew') else '' - items.append({ - 'label': item['title'] + vip + new, - 'path': url_for('playvideo', vid=item['id'], - name=item['title'].encode('utf-8'), - image=item['capture'].encode('utf-8')), - 'thumbnail': item['capture'], - 'is_playable': True, - 'info': {'title': item['title']}, - }) - - return items - - -@plugin.route('/videolist///') -def videolist(url, page): - plugin.set_content('TVShows') - items = [{ - 'label': '[COLOR green]分类过滤[/COLOR]', - 'path': url_for('select', url=url) - }] + li = ListItem(item['title']+vip+new, thumbnailImage=item['capture']) + req = { + 'mode': 'playvideo', + 'name': item['title'].encode('utf-8'), + 'vid': item['id'], + 'thumbnail': item['capture'].encode('utf-8') + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, False) + + setContent(int(sys.argv[1]), 'tvshows') + endOfDirectory(int(sys.argv[1])) + + +def videolist(params): + page = int(params['page']) + url = params['url'] + li = ListItem('[COLOR green]分类过滤[/COLOR]') + u = sys.argv[0] + '?mode=select&url=' + 'url' + addDirectoryItem(int(sys.argv[1]), u, li, True) p = get_html(url) c = re.compile('pageNum.*\/ (\d+)<\/p>').findall(p) total = c[0] - items += previous_page('videolist', page=page, total_page=total, url=url) + previous_page('videolist', page=page, total_page=total, url=url) c = re.compile('.*/(.*).html').findall(url) utype = c[0].split('_') @@ -159,41 +152,67 @@ def videolist(url, page): req[utype[x]] = utype[x+1] data = urlencode(req) html = get_html(PPTV_LIST + 'channel_list.html?' + data) - tree = BeautifulSoup(html, 'html.parser') - soup = tree.find_all('a', {'class': 'ui-list-ct'}) + soup = BeautifulSoup(html, 'html.parser') + tree = soup.findAll('a', {'class': 'ui-list-ct'}) - for item in soup: + for item in tree: text = item.find('span', {'class': 'msk-txt'}) if text: text = '(' + text.text + ')' else: text = '' - items.append({ - 'label': item['title'] + text, - 'path': url_for('episodelist', url=item['href']), - 'thumbnail': item.img['data-src2'], - }) - items += next_page('videolist', page=page, total_page=total, url=url) - return items + li = ListItem(item['title']+text, thumbnailImage=item.img['data-src2']) + req = { + 'mode': 'episodelist', + 'url': item['href'] + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) + + next_page('videolist', page=page, total_page=total, url=url) + setContent(int(sys.argv[1]), 'tvshows') + endOfDirectory(int(sys.argv[1])) -@plugin.route('/') def root(): data = get_html(PPTV_LIST) soup = BeautifulSoup(data, 'html.parser') - menu = soup.find_all('div', {'class': 'detail_menu'}) - tree = menu[0].find_all('li') + menu = soup.findAll('div', {'class': 'detail_menu'}) + tree = menu[0].findAll('li') for item in tree: url = item.a['href'] t = re.compile('type_(\d+)').findall(url) if len(t) < 1: continue - yield { - 'label': item.a.text, - 'path': url_for('videolist', url=url, page=1) + li = ListItem(item.a.text) + req = { + 'mode': 'videolist', + 'url': url, + 'page': 1 } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) + + endOfDirectory(int(sys.argv[1])) + + +# main programs goes here ######################################### +runlist = { + 'videolist': 'videolist(params)', + 'episodelist': 'episodelist(params)', + 'search': 'search(params)', + 'select': 'select(params)', + 'playvideo': 'playvideo(params)', + +} +params = sys.argv[2][1:] +params = dict(parse_qsl(params)) -if __name__ == '__main__': - plugin.run() +mode = params.get('mode') +if mode: + del (params['mode']) + exec(runlist[mode]) +else: + root() diff --git a/plugin.video.pptv/lib/pptv.py b/plugin.video.pptv/lib/pptv.py index 90e9305..d042307 100644 --- a/plugin.video.pptv/lib/pptv.py +++ b/plugin.video.pptv/lib/pptv.py @@ -5,9 +5,10 @@ import re import time if sys.version[0]=='3': - from urllib.parse import urlencode + from urllib.parse import urlencode, parse_qsl else: from urllib import urlencode + from urlparse import parse_qsl from random import random import binascii from xml.dom.minidom import parseString diff --git a/plugin.video.pptv/plugin.video.pptv-2.2.1.zip b/plugin.video.pptv/plugin.video.pptv-2.2.1.zip index 73d74743ce3b71a7dc78e6c18f8f05984c6014a2..22bc9fde074615b08e14b55ebb9f3a0675fad043 100644 GIT binary patch delta 5730 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 A*Z=?k delta 5624 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 O0kL4!O57U;z<&Vs?rNF< diff --git a/plugin.video.qq/addon.xml b/plugin.video.qq/addon.xml index 4ccdd73..54ac005 100644 --- a/plugin.video.qq/addon.xml +++ b/plugin.video.qq/addon.xml @@ -1,7 +1,7 @@ diff --git a/plugin.video.qq/default.py b/plugin.video.qq/default.py index eac4473..4d5affb 100644 --- a/plugin.video.qq/default.py +++ b/plugin.video.qq/default.py @@ -13,11 +13,6 @@ PAGESIZE = 20 -# Plugin constants -__addon__ = xbmcaddon.Addon() -__addonid__ = __addon__.getAddonInfo('id') -__addonname__ = __addon__.getAddonInfo('name') - BANNER_FMT = '[COLOR FFDEB887]【%s】[/COLOR]' HOST_URL = 'https://v.qq.com' @@ -85,7 +80,7 @@ def select(params): mainlist(req) def playvideo(params): - sel = int(__addon__.getSetting('resolution')) + sel = int(xbmcaddon.Addon().getSetting('resolution')) if sel == 4: list = ['流畅(270P)', '高清(360P)', '超清(720P)', '蓝光(1080P)'] sel = Dialog().select('清晰度选择', list) @@ -101,10 +96,13 @@ def playvideo(params): stackurl = 'stack://' + ' , '.join(urls) title = params['title'] - li = ListItem(title, thumbnailImage='') + li = ListItem(title, thumbnailImage=params['thumbnail']) li.setInfo(type='Video', infoLabels={'Title': title}) - - xbmc.Player().play(stackurl, li) + playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) + playlist.clear() + for url in urls: + playlist.add(url, li) + xbmc.Player().play(playlist) def search(params): @@ -164,7 +162,8 @@ def search(params): req = { 'title': subtitle, 'mode': 'playvideo', - 'url': href.encode('utf-8') + 'url': href.encode('utf-8'), + 'thumbnail': '' } u = sys.argv[0] + '?' + urlencode(req) addDirectoryItem(int(sys.argv[1]), u, li, False) diff --git a/plugin.video.qq/lib/qq.py b/plugin.video.qq/lib/qq.py index ce427d8..264e628 100644 --- a/plugin.video.qq/lib/qq.py +++ b/plugin.video.qq/lib/qq.py @@ -10,6 +10,7 @@ from json import loads from common import get_html, match1 +origin = [10901, 4100201] # some VIP availablePLAYER_PLATFORMS = [11, 2, 1] PLAYER_PLATFORMS = [10901, 4100201] # some VIP availablePLAYER_PLATFORMS = [11, 2, 1] PLAYER_VERSION = '3.2.19.333' @@ -57,6 +58,7 @@ def get_streams_info(self, vid, profile='shd'): if 'msg' in data: assert data['msg'] not in ('vid is wrong', 'vid status wrong'), 'wrong vid' + PLAYER_PLATFORMS.remove(PLAYER_PLATFORM) continue if PLAYER_PLATFORMS and \ @@ -71,7 +73,6 @@ def get_streams_info(self, vid, profile='shd'): assert 'msg' not in data, data['msg'] video = data['vl']['vi'][0] fn = video['fn'] - title = video['ti'] td = float(video['td']) fvkey = video.get('fvkey') self.vip = video['drm'] @@ -142,6 +143,8 @@ def get_streams_info(self, vid, profile='shd'): yield urls, size def video_from_vid(self, vid, **kwargs): + global PLAYER_PLATFORMS + PLAYER_PLATFORMS = origin[:] videos = {} for _ in range(2): for urls, size in self.get_streams_info(vid): diff --git a/plugin.video.qq/plugin.video.qq-2.0.0.zip b/plugin.video.qq/plugin.video.qq-2.0.1.zip similarity index 83% rename from plugin.video.qq/plugin.video.qq-2.0.0.zip rename to plugin.video.qq/plugin.video.qq-2.0.1.zip index 058a6be836825a642992f7684625b37e17a8cdcc..d76b0e7c20c356981ca1b712bf6e54e417ca6bdd 100644 GIT binary patch delta 6090 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 b_WuwBH6?^M-~a%iy?r2f0APCQpXk2;Y4}f? diff --git a/plugin.video.sohuvideo/addon.xml b/plugin.video.sohuvideo/addon.xml index 7715297..0fb3cad 100644 --- a/plugin.video.sohuvideo/addon.xml +++ b/plugin.video.sohuvideo/addon.xml @@ -4,7 +4,6 @@ version="2.6.4" provider-name="yfang1644"> - diff --git a/plugin.video.sohuvideo/default.py b/plugin.video.sohuvideo/default.py index 7f2caf3..cefe31a 100644 --- a/plugin.video.sohuvideo/default.py +++ b/plugin.video.sohuvideo/default.py @@ -1,13 +1,15 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +import xbmc from xbmcgui import Dialog, ListItem -from xbmcswift2 import Plugin, xbmc +from xbmcplugin import addDirectoryItem, endOfDirectory, setContent +import xbmcaddon import re from json import loads from bs4 import BeautifulSoup from common import get_html -from lib.sohu import video_from_url, urlparse, quote_plus +from lib.sohu import video_from_url, urlparse, quote_plus, parse_qsl, urlencode from iqiyi import video_from_url as video_from_iqiyi from qq import video_from_url as video_from_qq from funshion import video_from_url as video_from_fun @@ -17,21 +19,14 @@ # 搜狐视频 tv.sohu.com ######################################################################## -plugin = Plugin() -url_for = plugin.url_for - # Plugin constants -LIVEID_URL = 'http://live.tv.sohu.com/live/player_json.jhtml?lid=%s&type=1' -HOST_URL = 'https://tv.sohu.com' LIST_URL = 'https://so.tv.sohu.com' -PROGRAM_URL = 'http://poll.hd.sohu.com/live/stat/menu-segment.jsonp?num=8&sid=%d' BANNER_FMT = '[COLOR FFDEB887] %s [/COLOR]' INDENT_FMT0 = '[COLOR FFDEB887] %s[/COLOR]' INDENT_FMT1 = '[COLOR FFDEB8FF] %s[/COLOR]' EXTRA = '[COLOR FF8080FF] %s[/COLOR]' - def httphead(url): if len(url) < 2: return url @@ -43,28 +38,20 @@ def httphead(url): return url -@plugin.route('/stay') -def stay(): - pass - +def playvideo(params): + name = params['name'] + level = int(xbmcaddon.Addon().getSetting('resolution')) -@plugin.route('/playvideo////') -def playvideo(url, name, image): - level = int(plugin.addon.getSetting('resolution')) - - urls = video_from_url(url, level=level) + urls = video_from_url(params['url'], level=level) stackurl = 'stack://' + ' , '.join(urls) - playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) - playlist.clear() - list_item = ListItem(name, thumbnailImage=image) + list_item = ListItem(name, thumbnailImage=params['thumbnail']) list_item.setInfo('video', {'title': name}) - playlist.add(stackurl, list_item) - xbmc.Player().play(playlist) + xbmc.Player().play(stackurl, list_item) - #plugin.set_resolved_url(stackurl) -@plugin.route('/playvideo_other//') -def playvideo_other(url, site): +def playvideo_other(params): + site = params['site'] + url = params['url'] if site == 'qq': resolver = video_from_qq elif site == 'fun': @@ -76,107 +63,19 @@ def playvideo_other(url, site): else: return - urls = resolver(httphead(url)) + level = int(xbmcaddon.Addon().getSetting('resolution')) + urls = resolver(httphead(url), level=level) stackurl = 'stack://' + ' , '.join(urls) - plugin.set_resolved_url(stackurl) - - -@plugin.route('/videolist//') -def videolist(name, url): - plugin.set_content('TVShows') - html = get_html(url) - tree = BeautifulSoup(html, 'html.parser') - - surl = url.split('/') - lurl = re.compile('(.+?).html').findall(surl[-1]) - lurl = lurl[0].split('_') - p10 = lurl[10] - page = int(p10[3:]) if len(p10) > 3 else 1 - items = [] - items.append({ - 'label': BANNER_FMT % ('【第%d页】(分类过滤)' % (page)), - 'path': url_for('select', name=name, url=url) - }) - - vlists = tree.find_all('ul', {'class': 'st-list'}) - lists = [] if len(vlists) == 0 else vlists[0].find_all('li') - - for item in lists: - pic = item.find('div', {'class': 'st-pic'}) - href = pic.a.get('href') - href = httphead(href) - img = pic.img.get('src') - img = httphead(img) - try: - hover = item.find('div', {'class': 'list-hover'}) - title = hover.a.text - except: - title = pic.img.get('alt') - if len(title) == 0: - title = pic.a.get('title', '') - - try: - info = item.find('p', {'class': 'lh-info'}).text - except: - info = '' - - try: - mask = item.find('span', {'class': 'maskTx'}).text - except: - mask = '' - extra = '' - auth = item.find('span', {'class': 'rl-hyuan'}) - if auth: - extra += EXTRA % u'会员 ' - auth = item.find('span', {'class': 'rl-dbo'}) - if auth: - extra += EXTRA % u'独播' - - if name in ('电视剧', '动漫', '综艺', '娱乐', '纪录片', '明星', '体育'): - mode = 'episodelist1' - elif name in ('搞笑', '游戏', '做饭', '科技', '学习考试', '自媒体'): - mode = 'episodelist2' - else: - mode = 'playvideo' - - if mode == 'playvideo': - items.append({ - 'label': title + ' ' + mask + extra, - 'path': url_for(mode, url=href, name=title, image=img), - 'thumbnail': img, - 'is_playable': True, - 'info': {'title': title, 'plot': info} - }) - else: - items.append({ - 'label': title + ' ' + mask + extra, - 'path': url_for(mode, url=href), - 'thumbnail': img, - 'info': {'title': title, 'plot': info} - }) - - items.append({ - 'label': INDENT_FMT0 % '分页', - 'path': url_for('stay') - }) - - pages = tree.find_all('div', {'class': 'ssPages area'}) - pages = [] if len(pages) == 0 else pages[0].find_all('a') - for page in pages: - items.append({ - 'label': page['title'].encode('utf-8'), - 'path': url_for('videolist', name=name, url=httphead(page['href'])) - }) - - return items + list_item = ListItem(name, thumbnailImage=params['thumbnail']) + list_item.setInfo('video', {'title': name}) + xbmc.Player().play(stackurl, list_item) -@plugin.route('/select//') -def select(name, url): - html = get_html(url) - tree = BeautifulSoup(html, 'html.parser') - filter = tree.find_all('dl', {'class': 'cfix'}) +def select(params): + html = get_html(params['url']) + soup = BeautifulSoup(html, 'html.parser') + filter = soup.findAll('dl', {'class': 'cfix'}) dialog = Dialog() @@ -186,7 +85,7 @@ def select(name, url): for item in filter: title = item.dt.text.strip() - si = item.find_all('a') + si = item.findAll('a') list = [] for x in si: if x.get('class') == ['aon']: @@ -208,7 +107,8 @@ def select(name, url): surl[-1] = '_'.join(lurl) + '.html' url = '/'.join(surl) - return videolist(name, url) + params['url'] = url + videolist(params) def sohuvideolist(playlistid): @@ -219,26 +119,23 @@ def sohuvideolist(playlistid): link = get_html(listapi % playlistid, decoded=False) videos = loads(link.decode('gbk'))['videos'] - items = [] for item in videos: p_name = item['showName'].encode('utf-8') p_thumb = item['largePicUrl'].encode('utf-8') p_url = item['pageUrl'].encode('utf-8') p_vid = str(item['vid']).encode('utf-8') p_tvId = str(item['tvId']).encode('utf-8') - items.append({ - 'label': p_name, - 'path': url_for('playvideo', url=p_url, name=p_name, image=p_thumb), - 'thumbnail': p_thumb, - 'is_playable': True, - 'info': { - 'title': p_name, - 'duration': int(item['playLength']), - 'plot': item['videoDesc'], - 'episode': int(item['order']) - } - }) - return items + li = ListItem(p_name, thumbnailImage=p_thumb) + li.setInfo(type='Video', + infoLabels={'title':p_name, 'duration': int(item['playLength']), 'plot': item['videoDesc'], 'episode': int(item['order'])}) + req = { + 'mode': 'playvideo', + 'url': p_url, + 'name': p_name, + 'thumbnail': p_thumb + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, False) def othersite(link): @@ -247,7 +144,6 @@ def othersite(link): tree = BeautifulSoup(link, 'html.parser') soups = tree.findAll('div', {'class': 'episode cfix'}) - items = [] for soup in soups: lists = soup.findAll('a') for item in lists: @@ -257,35 +153,35 @@ def othersite(link): siteinfo = sitemap[site] except: continue - items.append({ - 'label': item.text.encode('utf-8') + '(' + siteinfo + ')', - 'path': url_for('playvideo_other', url = item['href'], site=site), - 'is_playable': True, - 'info': {'title': item.text.encode('utf-8')} - }) - return items + title = item.text.encode('utf-8') + li = ListItem(title + '(' + siteinfo + ')') + req = { + 'mode': 'playvideo_other', + 'url': item['href'], + 'site': site, + 'name': title, + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) -@plugin.route('/episodelist1/') -def episodelist1(url): - plugin.set_content('TVShows') - link = get_html(url) +def episodelist1(params): + link = get_html(params['url']) match0 = re.compile('var playlistId\s*=\s*["|\'](.+?)["|\'];', re.DOTALL).findall(link) match0 += re.compile('var PLAYLIST_ID\s*=\s*["|\'](.+?)["|\'];', re.DOTALL).findall(link) - items = [] if len(match0) > 0: if match0[0] != '0': - items = sohuvideolist(match0[0]) + sohuvideolist(match0[0]) else: - items = othersite(link) + othersite(link) else: - tree = BeautifulSoup(link, 'html.parser') - soup2 = tree.find_all('ul', {'class': 'list list-120 cfix'}) + soup = BeautifulSoup(link, 'html.parser') + tree = soup.findAll('ul', {'class': 'list list-120 cfix'}) - for part in soup2: - drama = part.find_all('li') + for part in tree: + drama = part.findAll('li') for item in drama: img = httphead(item.img['src']) @@ -293,20 +189,22 @@ def episodelist1(url): title = item.strong.a['title'] except: title = item.a.text - items.append({ - 'label': title, - 'path': url_for('episodelist1', url=httphead(item.a['href'])), - 'thumbnail': httphead(item.img['src']) - }) + li = ListItem(title, thumbnailImage=img) + req = { + 'mode': 'episodelist1', + 'url': httphead(item.a['href']), + 'thumbnail': img + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) - return items + setContent(int(sys.argv[1]), 'tvshows') + endOfDirectory(int(sys.argv[1])) -@plugin.route('/episodelist2/') -def episodelist2(url): - plugin.set_content('TVShows') - link = get_html(url) - tree = BeautifulSoup(link, 'html.parser') +def episodelist2(params): + link = get_html(params['url']) + #soup = BeautifulSoup(link, 'html.parser') listapi = 'http://my.tv.sohu.com/play/getvideolist.do?playlistid=%s&pagesize=30&order=1' @@ -314,32 +212,32 @@ def episodelist2(url): link = get_html(listapi % match0[0]) videos = loads(link)['videos'] - items = [] + for item in videos: length = item['playLength'] p_date = item['publishTime'].encode('utf-8') p_order = int(item['order']) vid = item['vid'] title = item['subName'].encode('utf-8') - items.append({ - 'label': title, - 'path': url_for('playvideo', name=title, - url=item['pageUrl'], - image=item['largePicUrl']), - 'thumbnail': item['largePicUrl'], - 'is_playable': True, - 'info': {'title': title}, - }) + img = item['largePicUrl'] + li = listing(title, thumbnailImage=img) + req = { + 'mode': 'playvideo', + 'url': item['pageUrl'], + 'name': title, + 'thumbnail': img + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, False) - return items + setContent(int(sys.argv[1]), 'tvshows') + endOfDirectory(int(sys.argv[1])) ########################################################################### # Get user input for Sohu site search ############################################################################ -@plugin.route('/search') -def search(): - plugin.set_content('TVShows') +def search(params): keyboard = xbmc.Keyboard('', '请输入搜索内容') xbmc.sleep(1500) keyboard.doModal() @@ -357,12 +255,11 @@ def search(): ######################################################################### # Video listing for all found related episode title - tree = BeautifulSoup(link, 'html.parser') - soup = tree.find_all('div', {'class': 'ssItem cfix'}) + soup = BeautifulSoup(link, 'html.parser') + tree = soup.findAll('div', {'class': 'ssItem cfix'}) ######################################################################### - items = [] - for page in soup[0]: + for page in tree[0]: try: p_url = httphead(page.a['href']) except: @@ -374,48 +271,169 @@ def search(): info = infop.text except: info = '' - items.append({ - 'label': p_name, - 'path': url_for('episodelist1', url=p_url), - 'thumbnail': httphead(page.img['src']), - 'info': {'title': p_name, 'plot': info} - }) - - album = page.find_all('a', {'class': 'ts'}) + li = ListItem(p_name, thumbnailImage=httphead(page.imag['src'])) + li.setInfo(type='Video', infoLabels={'title': p_name, 'plot': info}) + req = { + 'mode': 'episodelist1', + 'url': p_url + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) + + album = page.findAll('a', {'class': 'ts'}) for series in album: - items.append({ - 'label': series['title'], - 'path': url_for('playvideo', name=series['title'], - url=httphead(series['href']), - image=httphead(page.img['src'])), - 'is_playable': True, - 'info': {'title': series['title']}, - }) + img = httphead(page.img['src']) + li = ListItem(series['title'], thumbnailImage=img) + req = { + 'mode': 'playvideo', + 'url': p_url, + 'name': series['title'], + 'thumbnail': img + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) - return items + setContent(int(sys.argv[1]), 'tvshows') + endOfDirectory(int(sys.argv[1])) -@plugin.route('/') -def root(): - plugin.set_content('videos') - yield { - 'label': '[COLOR FF00FF00] 【搜狐视频 - 搜索】[/COLOR]', - 'path': url_for('search') +def videolist(params): + url = params['url'] + name = params['name'] + html = get_html(url) + soup = BeautifulSoup(html, 'html.parser') + + surl = url.split('/') + lurl = re.compile('(.+?).html').findall(surl[-1]) + lurl = lurl[0].split('_') + p10 = lurl[10] + page = int(p10[3:]) if len(p10) > 3 else 1 + + li = ListItem(BANNER_FMT % ('【第%d页】(分类过滤)' % (page))) + req = { + 'mode': 'select', + 'name': name, + 'url': url } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) + + vlists = soup.findAll('ul', {'class': 'st-list'}) + lists = [] if len(vlists) == 0 else vlists[0].findAll('li') + + for item in lists: + pic = item.find('div', {'class': 'st-pic'}) + href = pic.a.get('href') + href = httphead(href) + img = pic.img.get('src') + img = httphead(img) + try: + hover = item.find('div', {'class': 'list-hover'}) + title = hover.a.text + except: + title = pic.img.get('alt') + if len(title) == 0: + title = pic.a.get('title', '') + + try: + info = item.find('p', {'class': 'lh-info'}).text + except: + info = '' + + try: + mask = item.find('span', {'class': 'maskTx'}).text + except: + mask = '' + extra = '' + auth = item.find('span', {'class': 'rl-hyuan'}) + if auth: + extra += EXTRA % u'会员 ' + auth = item.find('span', {'class': 'rl-dbo'}) + if auth: + extra += EXTRA % u'独播' + + if name in ('电视剧', '动漫', '综艺', '娱乐', '纪录片', '明星', '体育'): + mode = 'episodelist1' + elif name in ('搞笑', '游戏', '做饭', '科技', '学习考试', '自媒体'): + mode = 'episodelist2' + else: + mode = 'playvideo' + + li = ListItem(title + ' ' + mask + extra) + li.setInfo(type='Video', infoLabels={'title': title, 'plot': info}) + req = { + 'mode': mode, + 'url': href, + 'name': title.encode('utf-8'), + 'thumbnail': img + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, isFolder=(mode!='playvideo')) + + li = ListItem(INDENT_FMT0 % '分页') + u = sys.argv[0] + addDirectoryItem(int(sys.argv[1]), u, li, True) + + pages = soup.findAll('div', {'class': 'ssPages area'}) + pages = [] if len(pages) == 0 else pages[0].findAll('a') + for page in pages: + li = ListItem(page['title'].encode('utf-8')) + req = { + 'mode': 'videolist', + 'name': name, + 'url': httphead(page['href']) + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) + + setContent(int(sys.argv[1]), 'tvshows') + endOfDirectory(int(sys.argv[1])) + + +def root(): + li = ListItem('[COLOR FF00FF00] 【搜狐视频 - 搜索】[/COLOR]') + u = sys.argv[0] + '?mode=search' + addDirectoryItem(int(sys.argv[1]), u, li, True) url = '/list_p1_p2_p3_p4_p5_p6_p7_p8_p9_p10_p11_p12_p13.html' html = get_html(LIST_URL + url) - tree = BeautifulSoup(html, 'html.parser') - soup = tree.find_all('div', {'class': 'sort-nav cfix'}) + soup = BeautifulSoup(html, 'html.parser') + tree = soup.findAll('div', {'class': 'sort-nav cfix'}) - grp = soup[0].find_all('a') + grp = tree[0].findAll('a') for prog in grp[1:]: title = prog.text.strip().encode('utf-8') - yield { - 'label': title, - 'path': url_for('videolist', name=title, url=httphead(prog['href'])) + li = ListItem(title) + req = { + 'mode': 'videolist', + 'name': title, + 'url': httphead(prog['href']) } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) + + endOfDirectory(int(sys.argv[1])) + + +# main programs goes here ######################################### +runlist = { + 'videolist': 'videolist(params)', + 'episodelist1': 'episodelist1(params)', + 'episodelist2': 'episodelist2(params)', + 'search': 'search(params)', + 'select': 'select(params)', + 'playvideo': 'playvideo(params)', + 'playvideo_other': 'playvideo_other(params)' +} + +params = sys.argv[2][1:] +params = dict(parse_qsl(params)) + +mode = params.get('mode') +if mode: + del (params['mode']) + exec(runlist[mode]) +else: + root() -if __name__ == '__main__': - plugin.run() diff --git a/plugin.video.sohuvideo/lib/sohu.py b/plugin.video.sohuvideo/lib/sohu.py index 5981484..1669e0d 100644 --- a/plugin.video.sohuvideo/lib/sohu.py +++ b/plugin.video.sohuvideo/lib/sohu.py @@ -5,10 +5,10 @@ from json import loads import time if sys.version[0]=='3': - from urllib.parse import urlencode, quote_plus, urlparse + from urllib.parse import urlencode, quote_plus, urlparse, parse_qsl else: from urllib import urlencode, quote_plus - from urlparse import urlparse + from urlparse import urlparse, parse_qsl import re from common import get_html, r1 diff --git a/plugin.video.sohuvideo/plugin.video.sohuvideo-2.6.4.zip b/plugin.video.sohuvideo/plugin.video.sohuvideo-2.6.4.zip index d052ac9d7754dacf877efb1c70a6dbb4015020f9..f3f93f87270dc4b34d06a35f93b2cc4eb1421ba3 100644 GIT binary patch delta 6307 zcmZX31yEc;m-R5X4estva1R=S2Mr;?o#5^;fk1E_G+1zVm*5f@f(`EOfk2SKm*lU1 zYroyD>RY!?pRW6=UcXa)&-;0e`289YTSEmA2?OwVtfcrRU~{1&MEV;&MEEDjkR#?l zBSyTa2@(EA&*(FfP$P#Z!uFgI5)eM`Km$B8H13ETFT{}nfJO)v0yp?C`S0}b#snZB z?IQvJ|3ag#zSEKrVc=Y~i8*7E*}JBC&v`7go>`>*PnE1~9)5~ga<%*6m`v=9JN;a@ zYhIwz_N+=a9x1);jn+U3l2{{EmC7PviJUrrmB=h5%afQNP*|!37eV$Kx8g^k7hvhg zy|aq=5nS+h*y`)y==(~`H|%-wE_rsKKK|V^Y}YUPMFOceGxlWi7vgQd(e5j}OGDO$ zP4PH>+6qdWi>6r-xEd?>>4vgiA`PcF$R1mJREG|QSotkJzEzL&vGG&~dlaN$dUDlQ zU|*-CzqRG#rL#TpNzyu1Bj0OQ{h_}HlVB|69WVon2`*_s8?a=08aQ!_O9SUs$F2U% z)t_2d7j+Ft-~^cs{7$V$#V1*|z3d1Mue7# zuCRbhfSiAX`mN=!yL<%cNm5Ux3_5QP;-HwlZgmmOT6hcJqdt8a>^%DEK$nDCg=O38 zh(5QSHM-CXl%l7hBg)mof}+`ktC(s;1p)0Hhmdojy}N4!-Yx5CHpj2D(|{ zK~0X}PjR}tO517>kj|u(}B*;KlDik6BDl^Z^GFxzYpPltp*R+&R;ecr;Tq3}+ znzpLNd!N!H0wsdf@fYIXU=aLN7c!^`kL55l_XU=j#=XQ4^0E&L^Qw8Zcc4eH)5i{w zUBLBr^ru9pd%Wp6@E6KJ{$ZB45YZN~+i*5kVt7>6F05U)97ED|(k6+7hxCq6(tV+( zen^mGRK{gVDXisfjcLf~CYG<%D;NS8gS#3<8Bt5ge$$x)5})DGGFIFn;ZN&e;GW$NIYx#r@(LfO@^@MV zw^K~U=%$1+7F*Sl?Eq|gA-huedCB;6>8CXnam<*IGCXL2MEnoG>+ zh5Vs`we3l3MKcHjQoCs-I+P?}hg`HK%kbEGJfNavqX2GZqvmRcA%a2j1_!j(9+CRj z+QH3wtJ`leg*2?=NmiS5tyVhG?QUanU2KVrG$~wk54x7KIAR4EmYC~X)Nx__VA2a5 zFO{nAH0B{P>z9A_R+-QujWsI*N`Ocf5v$@rNz4jgRjHwmqPJJV$yFp^yz~WBx%yD` zwYlocIa{<~C)vg)gVJ$O{A;JB2nRt$bHR9FyVIiF6a@fKB&bk z50GQ8Ax)}l9;-AYI>midN3EPM@6RGp{9fX|^~>Hx>G68OUMRejMPsX94~@|Cb2I=s+D| z(u9V>#-=~Z3{9@_-lB7&N62ufeJ;Pf_|U zSb3>?NWi?ABQU6z%AmM_wf?KP+jy(>iTQS`yc`MfH%o?KZ4>28Bw#;T9$lsiIA|#D zWTg!oDWgnJ+auT%gD@9+Hz}mTmb?czrPV#1McKOvoT9~ZNc0M(QbhANomnSsp1iP) ziSpd3YZQ8nU-n||U1B|M5aD3%2puC@`$M!hH6E3$$peM6e7L&gNveWUu?gU6?8 zrb(xf1oRw~WhTPT6BQ$bX?U>ej)=9XQSzf#$ubX+xsWR|Ol{M8a8mUXsh{htV9_XI zuz#Z`2aHF9xbdx55fGWksSH@LXp3JfSW(&UiP}qhV!crLoE*PFA3E<9y{{I`qZTyK zkbnnK44?+<)+9?OaLRicOB0^81)C=H$qt&Gt6ijQ{GjE^LntjP)rsM#r|Mg046eG> z2J&j$R}p8!#X^6_)J=P};azd!B*86OE-zOPu1!TAcfU~t1iho9F`+VLMH;RRt&qnG z;zmMbwF;+G;hhGzRvrCrvs-&LuDOBG^3SM_Wj7ff3R=;mwUUQFw zu4Xt@-0gHU5T<8_zg>FA!jkj;y7FDX&7FN{WzxzbLh+^qrAO<`dA8T`Pn>&pq}yHJ zp{2kLA(fLsx+RC}p!TKXp@h3f0x9cDF9W9Xx%t-VJNp zE_yMth1sks-T5Tutto%qliG&`Hmmf36^#z!S$Tz+<>chs@Hb9({lzQHy@@C=4GZ6! zkwumr`LjNLcmjoTB2!f`J_7!p{C_tN$X1~2zoX9z_Ci9m5%qh%i$Iz_Yy88|Lr4++ zC5)l!<{$)nUyUJdaJ3Hz0MHbI1nqNzH6{IxX8!MYv7-Ovv@}TcWC%tU?~^P`upB-} z)yW_(P~#(Yg9x}pVVBWPY$}<_B?$PqAA6wGVXIAf?k9R82b;~$IvPe+txTB8cNH$t zz~Cy6QQy717*7>PQdR^gn7c7Nu2%zmt~>o#w=8!Pz@Z`-B)U{ibn_MrYvrS)f8xd{ z0@ge`OrhZmCXYx>I_zU2zvZm#D`M}GW%lE4U_72!3oeVb24Fq@l&o+rUa_%opfI(V zk*xK?)kl_sfZebR#drKA);Tl<4uTAM$7E~f)8>Z--KbCqHXTu47var8ca_sZf{jrO zwaSMaaFOn4rp&R?`Ihv>)x(*HIfd3NMQts|t$}qT^-aFWfuWcE;dM~(Se6S@NHn0pf!w*X0(RBF;p9)sIjqBWOf$mhW08i0rJbn zn3wTdCPoSUoPo&PN;_S3 z>W5b^LHsr)mAmpHyQ{^%0h`Z^GyDT4W`gm%U6$k#Sn*hvxLd8))dCUYk%U{|&At5A z@dC^`The87xQds8EDL#co+-J|t#~|BUuN+&TP?!2<@8VB>j_jl@<)%o|&%I;}R(s2#+T++b3+ZAA+aHAV z1YewGkH7BD9exQ^mOp`Oj~E^s6THon2u2U7Z+fl6gm_jB(?}I=DcAASl5|!;<;#Pz zySjpXXsdsh$vd9FK-dp!RPV&i4g~^dx%#e()OncL3PZ~4~hq9w{Gq`fR6~YlC zZK2BfA&MZz4;I1+EnmiLk7s?rBA|$G)FRwldy)2+L0b#O26K!}(CZ1WO4i_)@sHgL zwE9}3LPLDr4AL>_ipGl6okyDMVxvfNEIW+8vXPpM&IY#l^?}D0jj=~`ZzU^{VVh`K zH&*YqTti=|4Ibl(u5{yI2m0d<^mFrJZ`UbQ_SM(E&zi*6jnmslvJzwhM`ni5uQbWm zIZEKr?z_W?GhGmiqcZK;KORz)K#K_Vh+<0QI5l>v-lSt0GzSAdWu^C5=bkPa>datw z>P{~RM89psbJyme(8i)G>=z#4(#ZT^XiJnDuOSvXwebO!w>DQDffXTIplC5|)0@5+ zaeM_t7V0kDc9TD6gQE)ozez9sBuT)fiF|2KDUlH~asFl6el~j7e5RLom^ZWP3=JM` zGRr(zv61vcTdR>jR(04VVBgGlshKdoZC8mDf(o+)=nmN-Zvwtt=A z1z=s}05K;BCzk74=yO*^w^Htp-rgV9mzO-src1#4{X)6vO3B-KFvJ4iZ+%vwsW+1+ zdvw=P%HzItD945}=Z{>*mtTVhYv#Xpmx;n+QUadNk>`0IL9(|%SL0~IMaRTxOX|SR zh43HFo8GB!pHi`e?JTAR`-;-c=6}@_ld1?3ym(EJjhZg<#xOqJqQ#d?_KgDkB-}mf zQU1ch7XN|~BnOm61T#F1h{pCG(zo-Xt78*AVEIb;7I0P(few(1pCrn9Bn@QakkkP^ z`?S7#Z0uZ^YCVWubUeq+6_-p|h!j`mE>wah7)pe4Me|i7$%BebWD`O@GDsuAJGoiF znYu=d?5eCUlNQuwL%9PovQg$3Y-A$$mWS92Xu6UWY* zz8LG6*e>z9)0>eFIclN`(Ix55c#};}?MLQFw%1R_`~}HqUVXVQHl-cuG2m4C;p|4c z8nd+HFHzyN;GhVURe^zu$gx*Wou89mtD3;t>5-m5vG=ndadfc1bq-n2~? zBXIB)*BWHJMpmWdQsV>D3Ctj)8EGgG%$uo^0tmuEKNTAJRAlnbC zCpK15s&0@+2x>Ut`ZY(#1(Jg4uPBoizh+4$ZY(d|dhqXnZUnsHZ_)!#|L7_A;82y@ zOnflA0NYSJimlz;l#u1@*)%YJ4cf{Aa-zw&p zhm!KD%)oOa#dFmg^7rv71r^861uT-LtWdQ=Mnq3_6Wdd))Csci0}Ci%REn9<9B;lL z<3B$KzMN$K{w#@tVzqDXEDQm5QH`I$;Ud)`=Rpdf_IJ{27UTQig~mG?&u&(bMqbuFRSC2=R_EBo)m9iAx4H9{v*K5)i_?Ed;lBJt z$-LL6?3yBH$;PeF|Ni#dCkrNo8m<&eKA8>-C|RWlDkHyvPF+Q@`F@h31-&w{)`u*F zae`{E(}`m@0cvH?F&Nmokb0!g~oq!k;t+9{sxSs z!0+74+xXMgM~2F#8t!k%M&g}Fg!a{Sw7@DJ{_25hwKq+k<&L5G<}(_E$V7?7o(95oj5a=F;z%F0OgqXxKKab=!ik+?;Ho1a9%I2!+1} zmy;9X1oK*X?<;R9^dxMfHYxd1QRBhX)uj?XU4AnY`C(z$Y_@9?MP=t zTH_6|Dbe(2TL`(*IUQJCW+>#0TY2tu?nl9mA73?di>N5&$(3PbErbmtWGge?71ZSwvo;7Bj+a?`CXLP!KJ@`&+YH$4n*j4hcM_F?Fkh z5NO(_rQ@-)I$mL#=v1}3{IH+@{_e3oC(!LOr8Qt{@r1?r*TdcI*gJ5Q*~G4{PVyVh z>dVq5%z|$vzIpw=F$U~`n?512)Uv{H1(2hi&<%e>7PCK!X(E{+r7$(H1;^mVix3Lg z&OBtC%7UbN^;%Kq+rzsGZ6!D|=#%92jhbRxy6Rn@Rlgy9Watj#&DR$y;+ za7_6?bHqB`(nnB0OTG`dAV`fGMPD`B*N5=> z2K1HReNQ2Sx54qFmV$1;Yu?A&COXHfpX9vH+MV@Fzd1%u-KP3hA>Hx%GR|}LKFubT z&f5T>EiioIB(>7+=5RM7?tQgX9Z=(TT@7!zn=$my4|SmNcRdA1Wpw<4;xu;!`d!Z) z!Oi!sD8!qeKB-@K2HKsbKGC*{qwiyCR*+wf6r9*b&9~m%t;9K=nMytR?+rS^JG#90 z9`9)W_?#{;`ut*dx`V&C?u2ix&OE=82Z!t`qbKLPK4DV??a|JXvFz#`mJ6~s!~KFA zh4Dc~=|?bLx=V0Az5e@IQDDsgSb2lfw>{uc_=a;ET%5i2$~u4~Dw+A@S3;93?TqdF zd)?E`vEbn47L;6l-`-{RIBI?$E|0HCS3s5qSzD$rUu&#_Ak8H%5Mdirejk-`tD4L* zK^eAMH?vq#%fuvlsQ(w8NJAYv7IsQi*tg}pp?PYpfg##o^6<4-dbAnh%)9v5@k-~_6*a2{P& zXVN=#bM;k4qD`It;t{@KuR>K1gM{+4W4ZRUe8W+ga=jgs`aodzQsH}}PAN=1+XZv_ zDGh|vEZ{A|BN z8m^^~{u=IoVF(u775hIu`6#%=|6itn?82#mStyXnYcdGU4JYk?I!6EiEr9gjp8$mC z*br3V_m8;bhlz>|K>TYbJ(r+>YzN|F|4-TsWa8!{f)*tAmJwofD~nM1oVfz0L;h{% nzT>9-&psRgp!<(17W@B*+51>1&sClqbV%_XEsDtX-v{|G6LQ&U delta 6354 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 gTY=(W`@Me?GxxAjpTGRPro+ - diff --git a/plugin.video.youku/default.py b/plugin.video.youku/default.py index 3194298..60bf0eb 100644 --- a/plugin.video.youku/default.py +++ b/plugin.video.youku/default.py @@ -1,11 +1,15 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -from xbmcswift2 import Plugin, xbmcgui, xbmc +import xbmc +from xbmcgui import Dialog, ListItem +from xbmcplugin import addDirectoryItem, endOfDirectory, setContent +import xbmcaddon from json import loads import re from common import get_html -from lib.youku import video_from_vid, video_from_url, urlencode, quote_plus +from lib.youku import video_from_vid, video_from_url, urlencode, quote_plus, parse_qsl + HOST = 'http://tv.api.3g.youku.com' BASEIDS = { @@ -20,9 +24,6 @@ BANNER_FMT = '[COLOR gold][%s][/COLOR]' -plugin = Plugin() -url_for = plugin.url_for - def httphead(url): if len(url) < 2: return url @@ -105,39 +106,37 @@ def httphead(url): ############################################################################ def previous_page(endpoint, page, total_page, **kwargs): if int(page) > 1: - page = str(int(page) - 1) - return [{'label': u'上一页 - {0}/{1}'.format(page, str(total_page)), 'path': plugin.url_for(endpoint, page=page, **kwargs)}] - else: - return [] + li = ListItem('上一页 - {0}/{1}'.format(page, str(total_page))) + kwargs['mode'] = endpoint + kwargs['page'] = int(page) - 1 + u = sys.argv[0] + '?' + urlencode(kwargs) + addDirectoryItem(int(sys.argv[1]), u, li, True) def next_page(endpoint, page, total_page, **kwargs): if int(page) < int(total_page): - page = str(int(page) + 1) - return [{'label': u'下一页 - {0}/{1}'.format(page, str(total_page)), 'path': plugin.url_for(endpoint, page=page, **kwargs)}] - else: - return [] - - -@plugin.route('/playvideo///') -def playvideo(vid, name): - level = int(plugin.addon.getSetting('resolution')) - - urls = video_from_vid(vid, level=level) - if len(urls) > 1: - stackurl = 'stack://' + ' , '.join(urls) - playlist = xbmc.PlayList(1) - playlist.clear() - list_item = xbmcgui.ListItem(name) - list_item.setInfo(type="video", infoLabels={"Title": name}) - playlist.add(stackurl, list_item) - xbmc.Player().play(playlist) - xbmc.sleep(500) - else: - plugin.set_resolved_url(urls[0]) - - -@plugin.route('/select//') -def select(cid): + li = ListItem('下一页 - {0}/{1}'.format(page, str(total_page))) + kwargs['mode'] = endpoint + kwargs['page'] = int(page) + 1 + u = sys.argv[0] + '?' + urlencode(kwargs) + addDirectoryItem(int(sys.argv[1]), u, li, True) + +def playvideo(params): + level = int(xbmcaddon.Addon().getSetting('resolution')) + + urls = video_from_vid(params['vid'], level=level) + if not urls: + Dialog().ok(xbmcaddon.Addon().getAddonInfo('name'), '无法播放此视频') + return + + stackurl = 'stack://' + ' , '.join(urls) + name = params['name'] + li = ListItem(name, thumbnailImage=params['thumbnail']) + li.setInfo(type="video", infoLabels={"Title": name}) + xbmc.Player().play(stackurl, li) + + +def select(params): + cid = params['cid'] for item in category: title = item.keys()[0] if str(item[title][1]) == cid: @@ -145,15 +144,16 @@ def select(cid): g = item[title][2] break - dialog = xbmcgui.Dialog() + dialog = Dialog() sel = dialog.select('类型', g) - group = g[sel] if sel >= 0 else '0' + if sel >= 0: + params['group'] = g[sel] + + mainlist(params) - return mainchannel(type=type, cid=cid, group=group, page=1) -@plugin.route('/search') -def search(): +def search(params): keyboard = xbmc.Keyboard('', '请输入搜索内容') xbmc.sleep(1500) keyboard.doModal() @@ -199,91 +199,114 @@ def search(): return items -@plugin.route('/episodelist//') -def episodelist(vid): - plugin.set_content('TVShows') +def episodelist(params): + vid = params['vid'] url = 'http://v.youku.com/v_show/id_{0}.html'.format(vid) - page = get_html(url) + html = get_html(url) - m = re.search('__INITIAL_DATA__\s*=({.+?\});', page) + m = re.search('__INITIAL_DATA__\s*=({.+?\});', html) p = loads(m.group(1)) - series = p['data']['data']['nodes'][0]['nodes'][2]['nodes'] + try: + series = p['data']['data']['nodes'][0]['nodes'][2]['nodes'] + except: + series = p['data']['data']['nodes'][0]['nodes'][1]['nodes'] content = p['data']['data']['nodes'][0]['nodes'][0]['nodes'][0]['data']['desc'] items = [] for film in series: vid = film['data']['action']['value'] title = film['data']['title'].encode('utf-8') - - items.append({ - 'label': title, - 'path': url_for('playvideo', vid=vid, name=title), - 'thumbnail': film['data']['img'], - 'is_playable': True, - 'info': {'title': title, 'plot': content} - }) - - return items - -series = (97, 85, 100, 177, 87, 84, 98, 178, 86, 99) - -@plugin.route('/mainchannel/////') -def mainchannel(type, cid, group, page): - plugin.set_content('TVShows') + li = ListItem(title, thumbnailImage=film['data']['img']) + li.setInfo(type='video', infoLabels={'title': title, 'plot': content}) + req = { + 'mode': 'playvideo', + 'vid': vid, + 'name': title, + 'thumbnail': film['data']['img'] + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, False) + + setContent(int(sys.argv[1]), 'tvshows') + endOfDirectory(int(sys.argv[1])) + + +def mainlist(params): + cid = params['cid'] + type = params['type'] + group = params.get('group', '') + page = params.get('page', 1) + previous_page('mainlist', page, 300, type=type, cid=cid, group=group) + c = '分类' + '|' + group if group else '分类' + li = ListItem('[COLOR yellow][{0}][/COLOR]'.format(c)) + u = sys.argv[0] + '?mode=select&' + urlencode(params) + addDirectoryItem(int(sys.argv[1]), u, li, True) + api = 'https://list.youku.com/category/page?' req = { 'type': type, 'c': cid, - 'p': page, - 'g': '' if group == '0' else group + 'p': params.get('page', 1), + 'g': group } html = get_html(api + urlencode(req)) data = loads(html) - items = previous_page('mainchannel', page, 300, type=type, cid=cid, group=group) - if group == '0': c = '分类' - else: c = '分类' + '|' + group - items.append({ - 'label': '[COLOR yellow][{0}][/COLOR]'.format(c), - 'path': url_for('select', cid=cid) - }) + series = (97, 85, 100, 177, 87, 84, 98, 178, 86, 99) for item in data['data']: - items.append({ - 'label': item['title'] + '(' + item['summary'] +')', + li = ListItem(item['title'] + '(' + item['summary'] +')', + thumbnailImage=httphead(item['img'])) + li.setInfo(type='Video', + infoLabels={'title': item['title'], 'plot': item.get('subTitle', '')}) + req = { + 'mode': 'episodelist' if int(cid) in series else 'playvideo', + 'vid': item['videoId'], 'thumbnail': httphead(item['img']), - 'info': {'title': item['title'], 'plot': item.get('subTitle', '')} - }) - if int(cid) in series: - items[-1]['path'] = url_for('episodelist', vid=item['videoId']) - else: - items[-1]['path'] = url_for('playvideo', vid=item['videoId'], - name=item['title'].encode('utf-8')) - items[-1]['is_playable'] = True + 'name': item['title'].encode('utf-8') + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, + isFolder=True if int(cid) in series else False) - items += next_page('mainchannel', page, 300, type=type, cid=cid, group=group) + next_page('mainlist', page, 300, type=type, cid=cid, group=group) + setContent(int(sys.argv[1]), 'tvshows') + endOfDirectory(int(sys.argv[1])) - return items -@plugin.route('/') -def index(): - items = [] - items.append({ - 'label': '[COLOR magenta][搜索][/COLOR]', - 'path': url_for('search') - }) +def root(): + li = ListItem('[COLOR magenta][搜索][/COLOR]') + u = sys.argv[0] + '?mode=search' + addDirectoryItem(int(sys.argv[1]), u, li, True) + for item in category: title = item.keys()[0] - items.append({ - 'label': title, - 'path': url_for('mainchannel', - type=item[title][0], - cid=item[title][1], - group=0, - page=1) - }) - return items + li = ListItem(title) + req = { + 'title': title, + 'mode': 'mainlist', + 'type': item[title][0], + 'cid': item[title][1], + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) + endOfDirectory(int(sys.argv[1])) + +# main programs goes here ######################################### +runlist = { + 'mainlist': 'mainlist(params)', + 'episodelist': 'episodelist(params)', + 'search': 'search(params)', + 'select': 'select(params)', + 'playvideo': 'playvideo(params)' +} +params = sys.argv[2][1:] +params = dict(parse_qsl(params)) -if __name__ == '__main__': - plugin.run() +mode = params.get('mode') +if mode: + del (params['mode']) + exec(runlist[mode]) +else: + root() diff --git a/plugin.video.youku/lib/youku.py b/plugin.video.youku/lib/youku.py index d5f8d3c..7838a88 100644 --- a/plugin.video.youku/lib/youku.py +++ b/plugin.video.youku/lib/youku.py @@ -171,8 +171,8 @@ def video_from_vid(self, vid, **kwargs): size = int(s['size']) info[size] = urls videos = sorted(info) - level = kwargs.get('level', -1) - if level > len(videos): level = -1 + level = kwargs.get('level', 0) + level = min(level, len(videos)-1) urls = info[videos[level]] return urls diff --git a/plugin.video.youku/plugin.video.youku-2.0.1.zip b/plugin.video.youku/plugin.video.youku-2.0.2.zip similarity index 88% rename from plugin.video.youku/plugin.video.youku-2.0.1.zip rename to plugin.video.youku/plugin.video.youku-2.0.2.zip index d685f4170b95d0403662c3696aabaf60cd0f2f34..4e81feb6625b15b2443c0604ce0cea803edfcd79 100644 GIT binary patch delta 8044 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 Z;c;MpD-{C*c>m)K)&g*YKc5EIdxRZ> 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