diff --git a/addons.xml b/addons.xml index 36e9fa5..37b80e2 100644 --- a/addons.xml +++ b/addons.xml @@ -201,7 +201,7 @@ @@ -331,7 +331,7 @@ diff --git a/addons.xml.md5 b/addons.xml.md5 index ab35b5f..2ea7751 100644 --- a/addons.xml.md5 +++ b/addons.xml.md5 @@ -1 +1 @@ -38a1f7db1b5f7b0b57b3191be91fc243 addons.xml +f89cb90ade67477b5819e3688194a3d9 addons.xml diff --git a/plugin.video.huya/addon.xml b/plugin.video.huya/addon.xml index 1c2dd28..3cef3ab 100644 --- a/plugin.video.huya/addon.xml +++ b/plugin.video.huya/addon.xml @@ -1,7 +1,7 @@ diff --git a/plugin.video.huya/default.py b/plugin.video.huya/default.py index d345a60..5e65257 100644 --- a/plugin.video.huya/default.py +++ b/plugin.video.huya/default.py @@ -1,10 +1,18 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +import sys from xbmcswift2 import Plugin from common import get_html, r1 from json import loads import random +if sys.version[0] == '3': + from html import unescape +else: + import HTMLParser + def unescape(s): + html_parser = HTMLParser.HTMLParser() + return html_parser.unescape(s) HOST = 'https://www.huya.com/' playurl = 'https://al.hls.huya.com/huyalive' @@ -54,7 +62,7 @@ def playvideo(room): sHlsAntiCode = stream_info['sHlsAntiCode'] hls_url = u'{0}/{1}.{2}?{3}'.format(sHlsUrl, sStreamName, sHlsUrlSuffix, sHlsAntiCode) - plugin.set_resolved_url(hls_url) + plugin.set_resolved_url(unescape(hls_url)) @plugin.route('/categorylist///') diff --git a/plugin.video.huya/plugin.video.huya-0.9.3.zip b/plugin.video.huya/plugin.video.huya-0.9.4.zip similarity index 92% rename from plugin.video.huya/plugin.video.huya-0.9.3.zip rename to plugin.video.huya/plugin.video.huya-0.9.4.zip index d100cba..b0786d8 100644 Binary files a/plugin.video.huya/plugin.video.huya-0.9.3.zip and b/plugin.video.huya/plugin.video.huya-0.9.4.zip differ diff --git a/plugin.video.meiju/default.py b/plugin.video.meiju/default.py index 314794f..bd25253 100644 --- a/plugin.video.meiju/default.py +++ b/plugin.video.meiju/default.py @@ -49,13 +49,22 @@ def ttcategory(url): tree = soup.findAll('li', {'class': 'subject-item'}) items = [] for item in tree: + try: + info = u'[COLOR pink]({})[/COLOR]'.format(item.span.text) + except: + info = '' items.append({ - 'label': item.img['title'], + 'label': item.img['title'] + info, 'path': url_for('ttepisodes' ,url=item.a['href']), - 'thumbnail': item.img['data-src'] + 'thumbnail': item.img['data-src'], + 'info': {'title': item.img['title'], 'plot': item.p.text} }) # 分页 + items.append({ + 'label': BANNER.format('分页'), + 'path': url_for('stay') + }) tree = soup.findAll('div', {'class': 'page_navi'}) pages = tree[0].findAll('a') for page in pages: @@ -110,6 +119,8 @@ def yyepisodes(url): soup = BeautifulSoup(html, 'html.parser') tree = soup.findAll('div', {'class':'tab_set_info'}) + info = r1(' diff --git a/plugin.video.mgtv/default.py b/plugin.video.mgtv/default.py index ceb1379..95094a8 100644 --- a/plugin.video.mgtv/default.py +++ b/plugin.video.mgtv/default.py @@ -10,11 +10,6 @@ plugin = Plugin() url_for = plugin.url_for -# Plugin constants -__addonid__ = plugin.addon.getAddonInfo('id') -__addonname__ = plugin.addon.getAddonInfo('name') -__cwd__ = plugin.addon.getAddonInfo('path') - BANNER_FMT = '[COLOR FFDEB887]%s[/COLOR]' BANNER_FMT2 = '[COLOR FFDE0087]%s[/COLOR]' INDENT_FMT0 = '[COLOR FFDEB887] %s[/COLOR]' @@ -60,7 +55,7 @@ def search(): url = p_url + quote_plus(keyword) html = get_html(url) tree = BeautifulSoup(html, 'html.parser') - soup = tree.find_all('div', {'class': 'result-content'}) + soup = tree.findAll('div', {'class': 'result-content'}) items = [] for x in soup: try: @@ -82,34 +77,23 @@ def changeList(url): soup = BeautifulSoup(html, 'html.parser') tree = soup.findAll('div', {'class': 'm-tag-type'}) - surl = url.split('/') - purl = surl[-1].split('-') - dialog = xbmcgui.Dialog() - filter = '' - for iclass in soup: - title = iclass.find('h5', {'class': 'u-title'}).text - si = iclass.find_all('a') - list = [] - for subitem in si: - list.append(subitem.text) - sel = dialog.select(title, list) - - if sel < 0: - continue - - filter += u'|' + title + u'(' + si[sel].text + u')' - seurl = si[sel]['onclick'].split('/')[-1] - seurl = seurl.split('-') + item = tree[0] + title = item.find('h5', {'class': 'u-title'}).text + si = item.findAll('a') - for i in range(0, len(purl)): - if seurl[i] != '': - purl[i] = seurl[i] + content = [x.text for x in si] + sel = dialog.select(title, content) + if sel >= 0: + urlstr = str(si[sel]) + surl = r1("'(/.+?)'", urlstr) + if surl: + url = surl + filter = si[sel].text.encode('utf-8') - surl[-1] = '-'.join(purl) - url = '/'.join(surl) - mainlist(url, filter) + url = httphead(url) + return mainlist(url, filter) @plugin.route('/episodelist////') @@ -184,17 +168,17 @@ def mainlist(url, filter): plugin.set_content('TVShows') filtitle = '' if filter == '0' else filter items = [{ - 'label': BANNER_FMT % (u'[分类过滤]' + filtitle), + 'label': BANNER_FMT % ('[分类过滤]' + filtitle), 'path': url_for('changeList', url=url) }] html = get_html(url) - tree = BeautifulSoup(html, 'html.parser') + soup = BeautifulSoup(html, 'html.parser') - soups = tree.find_all('div', {'class': 'm-result-list'}) + tree = soup.findAll('div', {'class': 'm-result-list'}) - soup= soups[0].find_all('li', {'class': 'm-result-list-item'}) - for item in soup: + tree = tree[0].findAll('li', {'class': 'm-result-list-item'}) + for item in tree: t = item.find('a', {'class': 'u-title'}) title = t.text href = t['href'] @@ -222,25 +206,24 @@ def mainlist(url, filter): }) # multiple pages - setpage = tree.find_all('div', {'class': 'w-pages'}) + setpage = soup.findAll('div', {'class': 'w-pages'}) try: - pages = setpage[0].find_all('li') - for page in pages: - try: - title = page.a['title'] - except: - continue - href = page.a['href'] - if href == 'javascript:;': - continue - else: - href = httphead(href) - items.append({ - 'label': BANNER_FMT % title, - 'path': url_for('mainlist', url=href, filter=filter) - }) + pages = setpage[0].findAll('li') except: - pass + return items + + for page in pages: + title = page.a.get('title', '') + href = page.a.get('href') + print "XXXXXXXXXXXXXXXXX", href + if href == 'javascript:;' or title == '': + continue + href = httphead(href) + items.append({ + 'label': BANNER_FMT % title, + 'path': url_for('mainlist', url=href, filter=filter) + }) + return items @plugin.route('/') diff --git a/plugin.video.mgtv/lib/mgtv.py b/plugin.video.mgtv/lib/mgtv.py index 0444b2a..1bbda47 100644 --- a/plugin.video.mgtv/lib/mgtv.py +++ b/plugin.video.mgtv/lib/mgtv.py @@ -44,7 +44,7 @@ def vid_from_url(self, url, **kwargs): def get_mgtv_real_url(self, m3u_url, **kwargs): """str->list of str Give you the real URLs.""" - split = urlparse.urlsplit(m3u_url) + split = urlsplit(m3u_url) base_url = "{scheme}://{netloc}{path}/".format(scheme=split[0], netloc=split[1], diff --git a/plugin.video.mgtv/plugin.video.mgtv-1.1.6.zip b/plugin.video.mgtv/plugin.video.mgtv-1.1.7.zip similarity index 57% rename from plugin.video.mgtv/plugin.video.mgtv-1.1.6.zip rename to plugin.video.mgtv/plugin.video.mgtv-1.1.7.zip index c7aab39..6fc5a90 100644 Binary files a/plugin.video.mgtv/plugin.video.mgtv-1.1.6.zip and b/plugin.video.mgtv/plugin.video.mgtv-1.1.7.zip differ diff --git a/plugin.video.youku/addon.xml b/plugin.video.youku/addon.xml index 15d9610..f91e5d6 100644 --- a/plugin.video.youku/addon.xml +++ b/plugin.video.youku/addon.xml @@ -3,6 +3,7 @@ name="优酷视频" version="2.0.2" provider-name="yfang1644"> + diff --git a/plugin.video.youku/default.py b/plugin.video.youku/default.py index 60bf0eb..2229ac0 100644 --- a/plugin.video.youku/default.py +++ b/plugin.video.youku/default.py @@ -6,8 +6,8 @@ from xbmcplugin import addDirectoryItem, endOfDirectory, setContent import xbmcaddon from json import loads -import re -from common import get_html +from bs4 import BeautifulSoup +from common import get_html, r1 from lib.youku import video_from_vid, video_from_url, urlencode, quote_plus, parse_qsl @@ -35,89 +35,51 @@ def httphead(url): return url category = [ - {'剧集':['show', 97, - ['古装','武侠','警匪','军事','神话','科幻','悬疑','历史','儿童', - '农村','都市','家庭','搞笑','偶像','时装','优酷出品']]}, - {'电影':['show', 96, - ['武侠','警匪','犯罪','科幻','战争','恐怖','惊悚','纪录片','西部', - '戏曲','歌舞','奇幻','冒险','悬疑','历史','动作','传记','动画','儿童', - '喜剧','爱情','剧情','运动','短片','优酷出品']]}, - {'综艺':['show', 85, - ['热门','网综','优酷','牛人','脱口秀','真人秀','选秀','美食','旅游', - '汽车','访谈','纪实','搞笑','时尚','晚会','理财','演唱会','曲艺', - '益智','音乐','舞蹈','游戏','生活']]}, - {'动漫':['show', 100, - ['热血','格斗','恋爱','美少女','校园','搞笑','LOLI','神魔','机战', - '科幻','真人','青春','魔法','神话','冒险','运动','竞技','童话','亲子', - '教育','励志','剧情','社会','历史','战争']]}, - {'少儿':['show', 177, - ['动画','儿歌','绘本','故事','玩具','早教','艺术','探索纪实','少儿综艺', - '亲子','英语','国学','课程辅导','人际交往','情商','认知启蒙','科普', - '冒险','幽默','友情','益智','战斗','科幻','魔法','亲情','数学', - '动物','热血']]}, - {'音乐':['show', 95, - ['流行','摇滚','舞曲','电子','R&B','HIP-HOP','乡村','民族','民谣', - '拉丁','爵士','雷鬼','新世纪','古典','音乐剧','轻音乐']]}, - {'教育':['show', 87, - ['公开课','名人名嘴','文化','艺术','伦理','社会','理工','历史','心理学', - '经济','政治','管理学','外语','法律','计算机','哲学','职业培训', - '家庭教育']]}, - {'纪实':['show', 84, - ['人物','军事','历史','自然','古迹','探险','科技','文化','刑侦', - '社会','旅游']]}, - {'体育':['show', 98, - ['奥运会','世界杯','格斗','足球','篮球','健身','跑步','广场舞', - '综合','棋牌','电竞','冰壶','冰球','滑雪','滑冰','雪车雪撬','射击']]}, - {'文化':['show', 178, []]}, - - {'娱乐':['show', 86, ['明星资讯','电影资讯','电视资讯','音乐资讯']]}, - {'游戏':['show', 99, []]}, - {'资讯':['video', 91, - ['社会资讯','科技资讯','生活资讯','军事资讯','财经资讯','时政资讯', - '法制']]}, - {'搞笑':['video', 94, - ['恶搞短片','搞笑自拍','萌宠奇趣','搞笑达人','影视剧吐槽','恶搞配音', - '欢乐街访','鬼畜']]}, - {'生活':['video', 103, - ['休闲','美食','聚会','宠物','居家','健康','家居','女性','婚恋', - '潮品','记录','生活达人']]}, - {'汽车':['video', 104, []]}, - {'科技':['video', 105, - ['数码','IT','手机','笔记本','DC/DV','MP3/MP4','数字家电','GPS', - '游戏机','App','平板','科技达人']]}, - {'时尚':['video', 89, - ['美容','修身','服装服饰','时尚购物','潮人','情感星座','时尚达人', - '美容达人']]}, - {'亲子':['video', 90, - ['怀孕','育儿','早教','宝宝秀','搞笑儿童','妈妈']]}, - {'旅游':['video', 88, - ['国内游','出境游','旅游业界','交通住宿','旅游用品','城市','乡村古镇', - '游轮岛屿','人文景点','自然景点','节庆活动','户外运动', - '攻略指南','旅游达人']]}, - {'微电影':['video', 171, []]}, - {'网剧':['video', 172, []]}, - {'拍客':['video', 174, []]}, - {'创意视频':['video', 175, []]}, - {'自拍':['video', 176, []]}, - {'广告':['video', 102, []]}, -] + {'剧集':['show', 97]}, + {'电影':['show', 96]}, + {'综艺':['show', 85]}, + {'动漫':['show', 100]}, + {'少儿':['show', 177]}, + {'音乐':['show', 95]}, + {'教育':['show', 87]}, + {'纪实':['show', 84]}, + {'体育':['show', 98]}, + {'文化':['show', 178]}, + {'娱乐':['show', 86]}, + {'游戏':['show', 99]}, + {'资讯':['video', 91]}, + {'搞笑':['video', 94]}, + {'生活':['video', 103]}, + {'汽车':['video', 104]}, + {'科技':['video', 105]}, + {'时尚':['video', 89]}, + {'亲子':['video', 90]}, + {'旅游':['video', 88]}, + {'微电影':['video', 171]}, + {'网剧':['video', 172]}, + {'拍客':['video', 174]}, + {'创意视频':['video', 175]}, + {'自拍':['video', 176]}, + {'广告':['video', 102]}] ############################################################################ -def previous_page(endpoint, page, total_page, **kwargs): +def previous_page(endpoint, page, total_page, params): if int(page) > 1: li = ListItem('上一页 - {0}/{1}'.format(page, str(total_page))) - kwargs['mode'] = endpoint - kwargs['page'] = int(page) - 1 - u = sys.argv[0] + '?' + urlencode(kwargs) + params = dict(parse_qsl(params)) + params['mode'] = endpoint + params['p'] = int(page) - 1 + u = sys.argv[0] + '?' + urlencode(params) addDirectoryItem(int(sys.argv[1]), u, li, True) -def next_page(endpoint, page, total_page, **kwargs): +def next_page(endpoint, page, total_page, params): if int(page) < int(total_page): li = ListItem('下一页 - {0}/{1}'.format(page, str(total_page))) - kwargs['mode'] = endpoint - kwargs['page'] = int(page) + 1 - u = sys.argv[0] + '?' + urlencode(kwargs) + params = dict(parse_qsl(params)) + params['mode'] = endpoint + params['p'] = int(page) + 1 + u = sys.argv[0] + '?' + urlencode(params) addDirectoryItem(int(sys.argv[1]), u, li, True) def playvideo(params): @@ -136,20 +98,28 @@ def playvideo(params): def select(params): - cid = params['cid'] - for item in category: - title = item.keys()[0] - if str(item[title][1]) == cid: - type= item[title][0] - g = item[title][2] - break + type = params['type'] + cid = params['c'] + url = 'https://list.youku.com/category/{}/c_{}.html'.format(type, cid) + html = get_html(url) + soup = BeautifulSoup(html, 'html.parser') + tree = soup.findAll('div', {'class':'item'}) dialog = Dialog() - sel = dialog.select('类型', g) - if sel >= 0: - params['group'] = g[sel] - + ntype = {} + for item in tree[1:]: + c = item.findAll('li') + lst = [x.text for x in c] + sel = dialog.select(item.label.text, lst) + if sel >= 0: + try: + surl = c[sel].a['href'].split('_') + ntype[surl[-2]] = surl[-1].replace('.html', '').encode('utf-8') + except: + pass + + params.update(ntype) mainlist(params) @@ -167,13 +137,16 @@ def search(params): req.update(BASEIDS) link = get_html(searchapi + urlencode(req)) results = loads(link)['results'] - items = [] + for item in results: - items.append({ - 'label': item['showname'], - 'path': url_for('episodelist', vid=item['showid']), - 'thumbnail': item['show_vthumburl_hd'] - }) + li = ListItem(item['showname'], thumbnailImage=item['show_vthumburl_hd']) + req = { + 'mode': 'episodelist', + 'vid': item['showid'] + } + u = sys.argv[0] + '?' + urlencode(req) + addDirectoryItem(int(sys.argv[1]), u, li, True) + searchapi = HOST + '/openapi-wireless/videos/search/{}?' req = {'pz': 500} @@ -188,15 +161,19 @@ def search(params): for t in item['duration'].split(':'): duration = duration*60 + int(t) - items.append({ - 'label': item['title'], - 'path': url_for('playvideo', vid=item['videoId'], name=item['title']), - 'thumbnail': item['img'], - 'is_playable': True, - 'info': {'title': item['title'], 'plot': item['desc'], - 'duration': duration} - }) - return items + li = ListItem(item['title'], thumbnailImage=item['img']) + li.setInfo(type='Video', + infoLabels={'title': item['title'], 'plot': item['desc'], 'duration': duration}) + req = { + 'mode': 'playvideo', + 'vid': item['videoId'], + 'name': item['title'], + } + 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 episodelist(params): @@ -204,9 +181,9 @@ def episodelist(params): url = 'http://v.youku.com/v_show/id_{0}.html'.format(vid) html = get_html(url) - m = re.search('__INITIAL_DATA__\s*=({.+?\});', html) + m = r1('__INITIAL_DATA__\s*=({.+?\});', html) - p = loads(m.group(1)) + p = loads(m) try: series = p['data']['data']['nodes'][0]['nodes'][2]['nodes'] except: @@ -232,24 +209,23 @@ def episodelist(params): def mainlist(params): - cid = params['cid'] + cid = params['c'] 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 '分类' + page = params.get('p', 1) + previous_page('mainlist', page, 300, params=urlencode(params)) + c = '分类' li = ListItem('[COLOR yellow][{0}][/COLOR]'.format(c)) - u = sys.argv[0] + '?mode=select&' + urlencode(params) + req = { + 'mode': 'select', + 'c': params['c'], + 'type': params['type'] + } + u = sys.argv[0] + '?' + urlencode(req) addDirectoryItem(int(sys.argv[1]), u, li, True) api = 'https://list.youku.com/category/page?' - req = { - 'type': type, - 'c': cid, - 'p': params.get('page', 1), - 'g': group - } - + req = params.copy() + req['p'] = page html = get_html(api + urlencode(req)) data = loads(html) @@ -269,7 +245,7 @@ def mainlist(params): addDirectoryItem(int(sys.argv[1]), u, li, isFolder=True if int(cid) in series else False) - next_page('mainlist', page, 300, type=type, cid=cid, group=group) + next_page('mainlist', page, 300, params=urlencode(params)) setContent(int(sys.argv[1]), 'tvshows') endOfDirectory(int(sys.argv[1])) @@ -283,10 +259,10 @@ def root(): title = item.keys()[0] li = ListItem(title) req = { - 'title': title, 'mode': 'mainlist', + 'title': title, 'type': item[title][0], - 'cid': item[title][1], + 'c': item[title][1], } u = sys.argv[0] + '?' + urlencode(req) addDirectoryItem(int(sys.argv[1]), u, li, True)