Skip to content

Instantly share code, notes, and snippets.

@ypchen
Last active April 7, 2019 07:35
Show Gist options
  • Save ypchen/b31d56a0eefcefbd36fc4538c9b40289 to your computer and use it in GitHub Desktop.
Save ypchen/b31d56a0eefcefbd36fc4538c9b40289 to your computer and use it in GitHub Desktop.
Auto-update for plugin.video.hdp_ims
def my_gist_hash ():
return 'b31d56a0eefcefbd36fc4538c9b40289'
def my_version ():
return '1.0.0-gist-r93'
# priv: revision 93
sites = [
{
'title': '楓林網',
'action': 'list_items',
'callback': 'maplestage_top()',
'isFolder': True
},
{
'title': '劇迷 gimy.tv',
'action': 'list_items',
'callback': 'gimy_id()',
'isFolder': True
},
{
'title': '酷播 99KUBO',
'action': 'list_items',
'callback': 'kubo_id()',
'isFolder': True
},
{
'title': '全景中国 (即:众遥、不卡、网星)',
'action': 'list_items',
'callback': 'aibuka_level_1()',
'isFolder': True
}
]
def kubo_id ():
# hard-coded top level menu items
# link is the -id-- in the search criteria
return [
{
'title': '電視劇', 'link': 'http://www.99kubo.tv/vod-search-id-2-cid--area--tag--year--wd--actor--order-vod_addtime%20desc.html', 'action': 'list_items',
'callback': 'kubo_cid_skip_area(params)', 'isFolder': True
},
{
'title': '電影', 'link': 'http://www.99kubo.tv/vod-search-id-1-cid--area--tag--year--wd--actor--order-vod_addtime%20desc.html', 'action': 'list_items',
'callback': 'kubo_cid(params)', 'isFolder': True
},
{
'title': '動漫', 'link': 'http://www.99kubo.tv/vod-search-id-3-cid--area--tag--year--wd--actor--order-vod_addtime%20desc.html', 'action': 'list_items',
'callback': 'kubo_area(params)', 'isFolder': True
},
{
'title': '電視秀', 'link': 'http://www.99kubo.tv/vod-search-id-41-cid--area--tag--year--wd--actor--order-vod_addtime%20desc.html', 'action': 'list_items',
'callback': 'kubo_cid(params)', 'isFolder': True
},
{
'title': '紀錄片', 'link': 'http://www.99kubo.tv/vod-search-id-27-cid--area--tag--year--wd--actor--order-vod_addtime%20desc.html', 'action': 'list_items',
'callback': 'kubo_area(params)', 'isFolder': True
},
{
'title': '體育', 'link': 'http://www.99kubo.tv/vod-search-id-5-cid--area--tag--year--wd--actor--order-vod_addtime%20desc.html', 'action': 'list_items',
'callback': 'kubo_cid(params)', 'isFolder': True
},
{
'title': '教育', 'link': 'http://www.99kubo.tv/vod-search-id-49-cid--area--tag--year--wd--actor--order-vod_addtime%20desc.html', 'action': 'list_items',
'callback': 'kubo_cid(params)', 'isFolder': True
},
{
'title': '其他', 'link': 'http://www.99kubo.tv/vod-search-id-20-cid--area--tag--year--wd--actor--order-vod_addtime%20desc.html', 'action': 'list_items',
'callback': 'kubo_cid(params)', 'isFolder': True
}
]
def kubo_filter (params, url, explodeStart, nextCallback):
html = get_link_contents(url)
if ('' == html):
return []
htmlToExplode = str_between(html, explodeStart, '</dl>')
videos = htmlToExplode.split('<a ')
videos.pop(0)
siteURLprefix = 'http://www.99kubo.tv'
items = []
prevTitle = ''
for video in videos:
title = str_between(video, '>', '</a').strip()
# order asc
if ((prevTitle == '2018') and (title == '全部')):
items.append({'title': '2019', 'link': link.replace('-year-2018-', '-year-2019-'), 'action': 'list_items', 'callback': nextCallback, 'isFolder': True})
link = siteURLprefix + str_between(video, 'href="', '"').strip()
# order desc
if ((prevTitle == '全部') and (title == '2018')):
items.append({'title': '2019', 'link': link.replace('-year-2018-', '-year-2019-'), 'action': 'list_items', 'callback': nextCallback, 'isFolder': True})
items.append({'title': title, 'link': link, 'action': 'list_items', 'callback': nextCallback, 'isFolder': True})
prevTitle = title
return items
def kubo_cid (params):
return kubo_filter (params, params['link'], '<dl><dt>子分類', 'kubo_area(params)')
def kubo_cid_skip_area (params):
return kubo_filter (params, params['link'], '<dl><dt>子分類', 'kubo_year(params)')
def kubo_area (params):
return kubo_filter (params, params['link'], '<dl><dt>地區', 'kubo_year(params)')
def kubo_year (params):
return kubo_filter (params, params['link'], '<dl><dt>年份', 'kubo_videos(params)')
kubo_order_description = {
'vod_addtime': '更新時間',
'vod_hits_day': '本日人氣',
'vod_hits_week': '本週人氣',
'vod_hits_month': '本月人氣',
'vod_hits': '總人氣',
'vod_gold': '得分',
'vod_golder': '評分人數',
'vod_up': '按讚數'
}
def kubo_order (params):
items = []
order = str_between(params['link'], '-order-', ' ').strip()
for kod in kubo_order_description:
title = '依' + kubo_order_description[kod] + '排序'
link = params['link'].replace(order, kod)
items.append({'title': title, 'link': link, 'action': 'list_items', 'callback': 'kubo_videos(params)', 'isFolder': True})
return items
def kubo_videos (params):
data = json.loads(base64.b64decode(params['data']), 'utf-8')
try:
page = int(data['page'])
except:
page = 1
order = str_between(params['link'], '-order-', ' ').strip()
html = get_link_contents(params['link'].replace('.html', '-p-' + str(page) + '.html' ))
if ('' == html):
return []
pageInfo = str_between(html, '當前:', '頁')
pages = pageInfo.split('/')
htmlToExplode = str_between(html, '<div class="listlf">', '<div class="footer">')
videos = htmlToExplode.split('<li>')
videos.pop(0)
siteURLprefix = 'http://www.99kubo.tv'
items = []
items.append({'title': '第 [COLOR limegreen]' + pages[0] + '[/COLOR] 頁/共 [COLOR limegreen]' + pages[1] + '[/COLOR] 頁 目前排序方式:[COLOR limegreen]' + kubo_order_description[order] + '[/COLOR] (可按此處變更)', 'link': params['link'], 'action': 'list_items', 'callback': 'kubo_order(params)', 'isFolder': True})
if (page > 1):
items.append({'title': '上一頁 (回第' + str(page-1) + '頁)', 'link': params['link'], 'action': 'list_items', 'callback': 'kubo_videos(params)', 'isFolder': True, 'page': (page-1)})
for video in videos:
title = str_between(video, 'title="', '"').strip()
link = siteURLprefix + str_between(video, 'href="', '"').strip()
image = str_between(video, 'data-original="', '"').strip()
updateAt = str_between(video, '<p>更新:', '</p>').strip()
score = str_between(video, '<p>得分:', '</p>').strip()
items.append({'title': '[COLOR goldenrod]' + score + '[/COLOR] ' + title + ' (' + updateAt + ' 更新)', 'link': link, 'action': 'list_items', 'callback': 'kubo_episodes(params)', 'isFolder': True, 'image': image})
if ((-1) != html.find('>下一页&gt;</a>')):
items.append({'title': '下一頁 (到第' + str(page+1) + '頁)', 'link': params['link'], 'action': 'list_items', 'callback': 'kubo_videos(params)', 'isFolder': True, 'page': (page+1)})
return items
def kubo_episodes (params):
html = get_link_contents(params['link'])
if ('' == html):
return []
# video_id = int(str_between(params['link'], '-id-', '.html').strip())
htmlToExplode = str_between(html, '<td class="flvtd"', '</ul>')
videos = htmlToExplode.split('<li>')
videos.pop(0)
items = []
for video in videos:
title = str_between(video, '">', '</a>').strip()
link = str_between(video, 'href="', '"').strip()
video_id = str_between(link, '-id-', '-').strip()
episode_id = str_between(link, '-pid-', '-').strip()
link = build_url_dict({'action': 'kubo_episode', 'vid': video_id, 'pid': episode_id})
items.append({'title': title, 'link': link, 'isFolder': False, 'IsPlayable': 'True'})
return items
# Should merge with get_link_contents() later
def get_link_redir (url, data_to_post=None, http_header=None, user_agent=None):
contents = ''
if data_to_post is None:
request = urllib2.Request(url)
else:
request = urllib2.Request(url, data_to_post)
if user_agent is None:
user_agent = 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.1 (KHTML, like Gecko) Ubuntu/11.04 Chromium/14.0.825.0 Chrome/14.0.825.0 Safari/535.1'
request.add_header('User-Agent', user_agent)
if http_header is not None:
for key, val in http_header.iteritems():
request.add_header(key, val)
try:
response = urllib2.urlopen(request)
# not sure why 200 (should be 302 here)
if (200 == response.getcode()):
url_redir = response.geturl()
finally:
return url_redir
def kubo_episode (params):
vid = params['vid']
pid = params['pid']
link = 'http://www.99tw.net/redirect?mode=xplay&id={0}&pid={1}'.format(vid, pid)
# a 302 redirect here
link = get_link_redir(link)
html = get_link_contents(link)
if ('' == html):
return []
htmlToExplode = str_between(html, 'var videoDetail = ', ';')
videos = htmlToExplode.split('{')
videos.pop(0)
items = {}
for video in videos:
bps = str_between(video, "bps: '", "'")
src = str_between(video, "src: '", "'")
items[bps] = src
# seems that 720P is actually 360P for 99KUBO
bpsPref = ['1080P', '480P', '720P', '360P']
for bps in bpsPref:
if bps in items:
link = items[bps]
break
playitem = xbmcgui.ListItem(path=link)
xbmcplugin.setResolvedUrl(addon_handle, True, playitem)
def gimy_id ():
# hard-coded top level menu items
# link is the -id-- in the search criteria
return [
{
'title': '戲劇', 'link': 'https://v.gimy.tv/list/drama-----addtime.html', 'action': 'list_items',
'callback': 'gimy_drama_category(params)', 'isFolder': True
},
{
'title': '電影', 'link': 'https://v.gimy.tv/list/movies-----addtime.html', 'action': 'list_items',
'callback': 'gimy_movie_category(params)', 'isFolder': True
},
{
'title': '動漫', 'link': 'https://v.gimy.tv/list/anime-----addtime.html', 'action': 'list_items',
'callback': 'gimy_area2(params)', 'isFolder': True
},
{
'title': '綜藝', 'link': 'https://v.gimy.tv/list/tvshow-----addtime.html', 'action': 'list_items',
'callback': 'gimy_area2(params)', 'isFolder': True
}
]
def gimy_filter (params, url, explodeStart, nextCallback):
html = get_link_contents(url)
if ('' == html):
return []
htmlToExplode = str_between(html, explodeStart, '</ul>')
videos = htmlToExplode.split('<a ')
videos.pop(0)
siteURLprefix = 'http://v.gimy.tv'
items = []
prevTitle = ''
for video in videos:
title = str_between(video, '>', '</a').strip()
# order asc
if ((prevTitle == '2018') and (title == '全部')):
items.append({'title': '2019', 'link': link.replace('-2018-', '-2019-'), 'action': 'list_items', 'callback': nextCallback, 'isFolder': True})
link = siteURLprefix + str_between(video, 'href="', '"').strip()
# order desc
if ((prevTitle == '全部') and (title == '2018')):
items.append({'title': '2019', 'link': link.replace('-2018-', '-2019-'), 'action': 'list_items', 'callback': nextCallback, 'isFolder': True})
items.append({'title': title, 'link': link, 'action': 'list_items', 'callback': nextCallback, 'isFolder': True})
prevTitle = title
return items
def gimy_year (params):
return gimy_filter (params, params['link'], '<span class="text-muted">按年份', 'gimy_videos(params)')
def gimy_area (params):
return gimy_filter (params, params['link'], '<span class="text-muted">按地區', 'gimy_year(params)')
def gimy_area2 (params):
return gimy_filter (params, params['link'], '<span class="text-muted">選擇地區', 'gimy_year(params)')
def gimy_drama_category (params):
return gimy_filter (params, params['link'], '<span class="text-muted">按分類', 'gimy_year(params)')
def gimy_movie_category (params):
return gimy_filter (params, params['link'], '<span class="text-muted">按分類', 'gimy_area(params)')
def gimy_videos (params):
data = json.loads(base64.b64decode(params['data']), 'utf-8')
try:
page = int(data['page'])
except:
page = 1
#html = get_link_contents(params['link'].replace('.html', str(page) + '.html' ))
html = get_link_contents(params['link'])
if ('' == html):
return []
pageHtml = str_between(str_between(html, '<div class="box-page', 'iv>'), '<ul>', '</d')
pages = []
pages.append(str_between(pageHtml, 'active"><span>', '</span>'))
pages.append(str_between(str_between(pageHtml, '下一頁</a>', '</ul>'), 'pagegbk" data="p-', '">尾頁</a>'))
if ('' == pages[1]):
pages[1] = str(page)
htmlToExplode = str_between(html, '<div class="box-video-list">', '<div class="box-page')
videos = htmlToExplode.split('<li ')
videos.pop(0)
siteURLprefix = 'http://v.gimy.tv'
items = []
items.append({'title': '第 [COLOR limegreen]' + pages[0] + '[/COLOR] 頁/共 [COLOR limegreen]' + pages[1] + '[/COLOR] 頁', 'link': '', 'action': '', 'callback': '', 'isFolder': False})
pageBlocks = pageHtml.split('</li>')
if (page > 1):
for pageBlock in pageBlocks:
if ('上一頁' == str_between(pageBlock, '">', '</a').strip()):
link = siteURLprefix + str_between(pageBlock, 'href="', '"').strip()
items.append({'title': '上一頁 (回第' + str(page-1) + '頁)', 'link': link, 'action': 'list_items', 'callback': 'gimy_videos(params)', 'isFolder': True, 'page': (page-1)})
break
for video in videos:
title = str_between(video, 'title="', '"').strip()
link = siteURLprefix + str_between(video, 'href="', '"').strip()
image = str_between(video, 'data-original="', '"').strip()
note = str_between(video, 'note text-bg-r">', '</span>').strip()
items.append({'title': title + ' -- ' + note, 'link': link, 'action': 'list_items', 'callback': 'gimy_sources(params)', 'isFolder': True, 'image': image})
if (int(page) < int(pages[1])):
for pageBlock in pageBlocks:
if ('下一頁' == str_between(pageBlock, '">', '</a').strip()):
link = siteURLprefix + str_between(pageBlock, 'href="', '"').strip()
items.append({'title': '下一頁 (到第' + str(page+1) + '頁)', 'link': link, 'action': 'list_items', 'callback': 'gimy_videos(params)', 'isFolder': True, 'page': (page+1)})
break
return items
def gimy_sources (params):
html = get_link_contents(params['link'])
if ('' == html):
return []
htmlToExplode = str_between(html, '<div class="details-play-title">', '</div>')
videos = htmlToExplode.split('class="gico')
videos.pop(0)
items = []
items.append({'title': '選擇來源:', 'link': '', 'action': '', 'callback': '', 'isFolder': False})
for video in videos:
title = str_between(video, '">', '</a>').strip()
playlist_id = str_between(video, 'href="#', '"').strip()
items.append({'title': title, 'link': params['link'], 'action': 'list_items', 'callback': 'gimy_episodes(params)', 'isFolder': True, 'playlist_id': playlist_id, 'html': str_between(html, '<div class="playlist">', '<div class="layout-box clearfix"')})
return items
def gimy_episodes (params):
data = json.loads(base64.b64decode(params['data']), 'utf-8')
try:
playlist_id = data['playlist_id']
except:
playlist_id = 'con_playlist_1'
html = data['html']
htmlToExplode = str_between(html, 'id="' + playlist_id + '"', '</ul>')
videos = htmlToExplode.split('<li>')
videos.pop(0)
siteURLprefix = 'http://v.gimy.tv'
items = []
for video in videos:
title = str_between(video, '">', '<').strip()
link = siteURLprefix + str_between(video, 'href="', '"').strip()
link = build_url_dict({'action': 'gimy_episode', 'link': link})
items.append({'title': title, 'link': link, 'isFolder': False, 'IsPlayable': 'True'})
return items
def gimy_episode (params):
html = get_link_contents(params['link'])
if ('' == html):
return []
htmlToExplode = str_between(html, '_player = ', '</script>')
link = str_between(htmlToExplode, '"url":"', '"').replace('\\/', '/')
playitem = xbmcgui.ListItem(path=link)
playitem.setProperty('inputstreamaddon','inputstream.adaptive')
playitem.setProperty('inputstream.adaptive.manifest_type','hls')
playitem.setMimeType('application/vnd.apple.mpegurl')
playitem.setContentLookup(False)
xbmcplugin.setResolvedUrl(addon_handle, True, playitem)
def maplestage_sources (params):
data = json.loads(base64.b64decode(params['data']))
html = get_link_contents(params['link'], http_header={'Referer': 'http://maplestage.com/show/' + data['slug']})
if ('' == html):
return []
if ((-1) == html.find('var pageData = {')):
return []
results = json.loads('{' + str_between(html, 'var pageData = {', '};').strip() + '}')
items = []
sources = results['props'][2]['value']['videoSources']
iSourceNo = 0;
addon_list = get_installed_addon_list ()
addons = addon_list['result']['addons']
for source in sources:
videoProvider = source['name'].lower()
if videoProvider in supported_providers:
provider_info = supported_providers[videoProvider]
videos = source['videos']
iSourceNo += 1;
for resolver in provider_info['resolvers']:
addon_found = map(lambda addon: 1 if addon['addonid'] == resolver['addonid'] else 0, addons)
if 1 in addon_found:
if 1 == len(videos):
vid = videos[0]['id']
image = provider_info['image_url'].format(urllib.quote(vid), addon_url)
title = '來源 #{0}: {1} -- 共 {2} 段 [直接播放] [{3}]'.format(iSourceNo, source['name'], len(videos), resolver['description'])
link = resolver['plugin_url'].format(urllib.quote(vid), addon_url)
if ('' == image):
items.append({'title': title, 'link': link, 'vid': vid, 'isFolder': False, 'IsPlayable': 'True'})
else:
items.append({'title': title, 'link': link, 'vid': vid, 'image': image, 'isFolder': False, 'IsPlayable': 'True'})
else:
title = '來源 #{0}: {1} -- 共 {2} 段 [進入播放] [{3}]'.format(iSourceNo, source['name'], len(videos), resolver['description'])
link = json.dumps({'videos': videos, 'resolver': resolver, 'image_url': provider_info['image_url']}).encode('utf-8')
items.append({'title': title, 'link': link, 'action': 'list_items', 'callback': 'maplestage_videos(params)', 'isFolder': True})
elif 'html' == videoProvider:
videos = source['videos']
iSourceNo += 1;
if 1 == len(videos):
vid = str_between(videos[0]['id'], '?ref=', '"').strip()
# try alternatives
if ('' == vid):
vid = str_between(videos[0]['id'], 'video=', '&').strip()
if ('' == vid):
vid = str_between(videos[0]['id'], 'src="', '"').strip()
# unquote twice
vid = urllib.unquote(vid).decode('utf-8')
vid = urllib.unquote(vid).decode('utf-8')
image = results['props'][2]['value']['thumb']
title = '來源 #{0}: {1} -- 共 {2} 段 [直接播放] [{3}]'.format(iSourceNo, source['name'], len(videos), vid)
link = build_url_dict({'action': 'maplestage_html', 'link': vid})
if ('' == image):
items.append({'title': title, 'link': link, 'vid': vid, 'isFolder': False, 'IsPlayable': 'True'})
else:
items.append({'title': title, 'link': link, 'vid': vid, 'image': image, 'isFolder': False, 'IsPlayable': 'True'})
return items
def maplestage_html (params):
link = params['link']
xbmc.log('[%s] %s' % ('hdp_ims', 'html: link={' + link + '}'), xbmc.LOGNOTICE)
if ((-1) != link.find('rapidvideo')):
if ((-1) != link.find('?')):
connector = '&'
else:
connector = '?'
resolutionAttempts = [connector+'q=720p', connector+'q=480p', '']
for resAtt in resolutionAttempts:
xbmc.log('[%s] %s' % ('hdp_ims', 'resAtt={' + resAtt + '}'), xbmc.LOGNOTICE)
html = get_link_contents(link + resAtt)
if ('' == html):
return []
if ((-1) != html.find('source src="')):
break
# It may still fail after the listed attempts
link = str_between(html, 'source src="', '"')
xbmc.log('[%s] %s' % ('hdp_ims', 'playing: link={' + link + '}'), xbmc.LOGNOTICE)
playitem = xbmcgui.ListItem(path=link)
xbmcplugin.setResolvedUrl(addon_handle, True, playitem)
elif ((-1) != link.find('meeu.net')):
if ((-1) == link.find('http:')):
link = 'http:' + link
xbmc.log('[%s] %s' % ('hdp_ims', 'get: link={' + link + '}'), xbmc.LOGNOTICE)
html = get_link_contents(link)
if ('' == html):
return []
link = re.sub(r".+\|([0-9a-z]{100,240})\|.+", "\g<1>", html)
if ('' == link):
return []
link = 'http://meeu.net/player?url=' + link
xbmc.log('[%s] %s' % ('hdp_ims', 'get: link={' + link + '}'), xbmc.LOGNOTICE)
html = get_link_contents(link)
if ('' == html):
return []
link = 'http://meeu.net' + str_between(html, 'source src="', '"')
xbmc.log('[%s] %s' % ('hdp_ims', 'playing: link={' + link + '}'), xbmc.LOGNOTICE)
playitem = xbmcgui.ListItem(path=link)
xbmcplugin.setResolvedUrl(addon_handle, True, playitem)
else:
if ((-1) != link.find('baidu')) and ((-1) != link.find('share')) and ((-1) == link.find('.m3u8')):
html = get_link_contents(link)
if ('' == html):
return []
parsed = urlparse.urlparse(link)
replaced = parsed._replace(path=str_between(html, 'var main = "', '"').strip())
link = replaced.geturl()
xbmc.log('[%s] %s' % ('hdp_ims', '+baidu+share-.m3u8: link={' + link + '}'), xbmc.LOGNOTICE)
xbmc.log('[%s] %s' % ('hdp_ims', 'playing: link={' + link + '}'), xbmc.LOGNOTICE)
playitem = xbmcgui.ListItem(path=link)
playitem.setProperty('inputstreamaddon','inputstream.adaptive')
playitem.setProperty('inputstream.adaptive.manifest_type','hls')
playitem.setMimeType('application/vnd.apple.mpegurl')
playitem.setContentLookup(False)
xbmcplugin.setResolvedUrl(addon_handle, True, playitem)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment