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 befaad9..cccb6a1 100644 Binary files a/plugin.video.bilivideo/icon.png and b/plugin.video.bilivideo/icon.png differ diff --git a/plugin.video.bilivideo/lib/bilibili.py b/plugin.video.bilivideo/lib/bilibili.py index fd5b070..848e51c 100644 --- a/plugin.video.bilivideo/lib/bilibili.py +++ b/plugin.video.bilivideo/lib/bilibili.py @@ -8,16 +8,16 @@ if sys.version[0] == '3': from urllib.parse import urlencode, quote_plus, urlparse from urllib.request import Request, urlopen + from urllib.request import build_opener, HTTPCookieProcessor, install_opener else: from urllib import urlencode, quote_plus from urlparse import urlparse from urllib2 import Request, urlopen + from urllib2 import build_opener, HTTPCookieProcessor, install_opener -import urllib2 import re import time import os -import tempfile from random import random from xml.dom.minidom import parseString from cookielib import MozillaCookieJar @@ -26,6 +26,9 @@ from bilibili_config import * from niconvert import create_website +import xbmc +__assfile__ = xbmc.translatePath("special://temp/tmp.ass") +__captcha__ = xbmc.translatePath("special://temp/captcha.jpg") def url_locations(url): response = urlopen(Request(url)) return response.url @@ -69,20 +72,14 @@ def __init__(self, appkey=APPKEY, appsecret=APPSECRET, if key is not None: self.is_login = True self.mid = str(key) - opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj)) - urllib2.install_opener(opener) + opener = build_opener(HTTPCookieProcessor(self.cj)) + install_opener(opener) try: - os.remove(self._get_tmp_dir() + '/tmp.ass') + os.remove(__assfile__) except: pass - def _get_tmp_dir(self): - try: - return tempfile.gettempdir() - except: - return '' - def get_captcha(self, path = None): key = None for ck in self.cj: @@ -96,7 +93,7 @@ def get_captcha(self, path = None): result = get_html(LOGIN_CAPTCHA_URL.format(random()), decoded=False, headers = {'Referer':'https://passport.bilibili.com/login'}) if path is None: - path = tempfile.gettempdir() + '/captcha.jpg' + path = __captcha__ with open(path, 'wb') as f: f.write(result) return path @@ -348,7 +345,7 @@ def parse_subtitle(self, cid): bottom_margin=0, tune_seconds=0 ) - f = open(self._get_tmp_dir() + '/tmp.ass', 'w') + f = open(__assfile__, 'w') f.write(text.encode('utf8')) f.close() return 'tmp.ass' diff --git a/plugin.video.bilivideo/lib/bilivideo.py b/plugin.video.bilivideo/lib/bilivideo.py index 2e36d26..59dc656 100644 --- a/plugin.video.bilivideo/lib/bilivideo.py +++ b/plugin.video.bilivideo/lib/bilivideo.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- import sys -from common import get_html +from common import get_html, match1 from json import loads import time import re @@ -20,16 +20,6 @@ def get_location(url, headers={}): # not to do that return response.geturl() -def match1(text, *patterns): - for pattern in patterns: - try: - match = re.search(pattern, text) - except(TypeError): - match = re.search(pattern, str(text)) - if match: - return match.group(1) - - def matchall(text, patterns): ret = [] for pattern in patterns: diff --git a/plugin.video.bilivideo/plugin.video.bilivideo-0.9.0.zip b/plugin.video.bilivideo/plugin.video.bilivideo-0.9.1.zip similarity index 91% rename from plugin.video.bilivideo/plugin.video.bilivideo-0.9.0.zip rename to plugin.video.bilivideo/plugin.video.bilivideo-0.9.1.zip index 08ca492..0b93f3a 100644 Binary files a/plugin.video.bilivideo/plugin.video.bilivideo-0.9.0.zip and b/plugin.video.bilivideo/plugin.video.bilivideo-0.9.1.zip differ diff --git a/plugin.video.bilivideo/resources/settings.xml b/plugin.video.bilivideo/resources/settings.xml index 37cf433..c3d2479 100644 --- a/plugin.video.bilivideo/resources/settings.xml +++ b/plugin.video.bilivideo/resources/settings.xml @@ -1,7 +1,5 @@ - - 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 b8a5fa2..c7aab39 100644 Binary files a/plugin.video.mgtv/plugin.video.mgtv-1.1.5.zip and b/plugin.video.mgtv/plugin.video.mgtv-1.1.6.zip differ 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 73d7474..22bc9fd 100644 Binary files a/plugin.video.pptv/plugin.video.pptv-2.2.1.zip and b/plugin.video.pptv/plugin.video.pptv-2.2.1.zip differ 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 058a6be..d76b0e7 100644 Binary files a/plugin.video.qq/plugin.video.qq-2.0.0.zip and b/plugin.video.qq/plugin.video.qq-2.0.1.zip differ 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 d052ac9..f3f93f8 100644 Binary files a/plugin.video.sohuvideo/plugin.video.sohuvideo-2.6.4.zip and b/plugin.video.sohuvideo/plugin.video.sohuvideo-2.6.4.zip differ diff --git a/plugin.video.youku/addon.xml b/plugin.video.youku/addon.xml index f3bcd22..15d9610 100644 --- a/plugin.video.youku/addon.xml +++ b/plugin.video.youku/addon.xml @@ -1,9 +1,8 @@ - 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 d685f41..4e81feb 100644 Binary files a/plugin.video.youku/plugin.video.youku-2.0.1.zip and b/plugin.video.youku/plugin.video.youku-2.0.2.zip differ