The branch, frodo has been updated
via e8d312ac937f519c932e01a603cf7d816d148f19 (commit)
via b3b7ef23f916b8d3f45eadce53a43c08ce6fa2d7 (commit)
via a3b677436e56ddee88725dc43708c089dfa343c8 (commit)
from 96e5a13b6ccff28ef3fa433062fff6ba96b8f1bb (commit)
- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=e8d312ac937f519c932e01a603cf7d816d148f19
commit e8d312ac937f519c932e01a603cf7d816d148f19
Author: beenje <bee...@xbmc.org>
Date: Sun Mar 17 22:14:12 2013 +0100
[plugin.video.twit] updated to version 2.0.1
diff --git a/plugin.video.twit/addon.xml b/plugin.video.twit/addon.xml
index 4e34268..efd34ef 100644
--- a/plugin.video.twit/addon.xml
+++ b/plugin.video.twit/addon.xml
@@ -1,21 +1,24 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<addon id="plugin.video.twit"
- name="TWiT"
- version="2.0.0"
- provider-name="divingmule">
- <requires>
- <import addon="xbmc.python" version="2.1.0"/>
- <import addon="script.module.beautifulsoup" version="3.0.8"/>
- <import addon="script.common.plugin.cache" version="1.0.0"/>
- <import addon="script.module.simplejson" version="2.0.10"/>
- </requires>
- <extension point="xbmc.python.pluginsource" library="default.py">
- <provides>audio video</provides>
- </extension>
- <extension point="xbmc.addon.metadata">
- <summary>TWiT</summary>
- <description>Videos from the TWiT Network</description>
- <platform>all</platform>
- <language>en</language>
- </extension>
-</addon>
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<addon id="plugin.video.twit"
+ name="TWiT"
+ version="2.0.1"
+ provider-name="divingmule">
+ <requires>
+ <import addon="xbmc.python" version="2.1.0"/>
+ <import addon="script.module.beautifulsoup" version="3.0.8"/>
+ <import addon="script.common.plugin.cache" version="1.0.0"/>
+ <import addon="script.module.simplejson" version="2.0.10"/>
+ <import addon="script.module.pyamf" version="0.6.1"/>
+ </requires>
+ <extension point="xbmc.python.pluginsource" library="default.py">
+ <provides>audio video</provides>
+ </extension>
+ <extension point="xbmc.addon.metadata">
+ <summary>TWiT</summary>
+ <description>Videos from the TWiT Network</description>
+ <platform>all</platform>
+ <language>en</language>
+ <license>GNU GENERAL PUBLIC LICENSE. Version 2, June 1991</license>
+ <source>https://code.google.com/p/twit-xbmc/</source>
+ </extension>
+</addon>
diff --git a/plugin.video.twit/changelog.txt b/plugin.video.twit/changelog.txt
index 9a9909a..cb5e1f2 100644
--- a/plugin.video.twit/changelog.txt
+++ b/plugin.video.twit/changelog.txt
@@ -1,77 +1,80 @@
-Version 2.0.0
-major version bump for frodo
-fix latest episodes, we now scrape the web-page as the rss isn't viable anymore
-added set-content-type as tv-shows, episodes; this enables more view modes
-added flowsoft hls strems for twit live
-added add-on setting "TWiT Live", select from the various live streams here
instead of adding a directory
-
-Version 1.1.0
-fix for website changes
-added support for 'content_type' parameter, when launched as a music add-on,
the playback setting is ignored and audio will be selected
-
-Version 1.0.9
-added scraping and caching of shows
-
-Version 1.0.8
-fix show listings for "The Tech Guy" and "Before You Buy"
-
-Version 1.0.7
-fix for website changes
-
-Version 1.0.6
-fix for UnicodeDecodeError
-added Trey's Variety Hour
-
-Version 1.0.5
-fix for site changes
-new playback settings
-
-Version 1.0.4
-added new shows - Game On, Before You Buy
-added new category - Latest Episodes, this scrapes http://twit.tv/node/feed
-fix for episodes that don't yet have video links
-
-Version 1.0.3
-updated shows
-new icon and fanart
-added TWiT Live via Justin.tv - 1 Mbs
-
-Version 1.0.2
-added TWiT Live via Ustream - 1.5 Mbs
-
-Version 1.0.1
-show updates
-
-Version 1.0.0
-new for eden-pre
-
-Version 0.0.9
-added new shows: Triangulation, Mostly Photo, All About Android
-added links for the live stream
-
-Version 0.0.8
-fixed an issue with TNT
-
-Version 0.0.7
-twit live no longer ask if you want to resume
-resume working again for most shows
-
-Version 0.0.6
-now if video isn't up on the web site, we get the latest episode from the rss:
feed
-
-Version 0.0.5
-added five new shows
-added addon settings for video quality
-
-Version 0.0.4
-fixed an issue with TNT
-
-Version 0.0.3
-added release date to title
-added subtitle as plot
-
-Version 0.0.2
-updated icon.png
-
-Version 0.0.1
+Version 2.0.1
+fix ustream live stream
+
+Version 2.0.0
+major version bump for frodo
+fix latest episodes, we now scrape the web-page as the rss isn't viable anymore
+added set-content-type as tv-shows, episodes; this enables more view modes
+added flowsoft hls strems for twit live
+added add-on setting "TWiT Live", select from the various live streams here
instead of adding a directory
+
+Version 1.1.0
+fix for website changes
+added support for 'content_type' parameter, when launched as a music add-on,
the playback setting is ignored and audio will be selected
+
+Version 1.0.9
+added scraping and caching of shows
+
+Version 1.0.8
+fix show listings for "The Tech Guy" and "Before You Buy"
+
+Version 1.0.7
+fix for website changes
+
+Version 1.0.6
+fix for UnicodeDecodeError
+added Trey's Variety Hour
+
+Version 1.0.5
+fix for site changes
+new playback settings
+
+Version 1.0.4
+added new shows - Game On, Before You Buy
+added new category - Latest Episodes, this scrapes http://twit.tv/node/feed
+fix for episodes that don't yet have video links
+
+Version 1.0.3
+updated shows
+new icon and fanart
+added TWiT Live via Justin.tv - 1 Mbs
+
+Version 1.0.2
+added TWiT Live via Ustream - 1.5 Mbs
+
+Version 1.0.1
+show updates
+
+Version 1.0.0
+new for eden-pre
+
+Version 0.0.9
+added new shows: Triangulation, Mostly Photo, All About Android
+added links for the live stream
+
+Version 0.0.8
+fixed an issue with TNT
+
+Version 0.0.7
+twit live no longer ask if you want to resume
+resume working again for most shows
+
+Version 0.0.6
+now if video isn't up on the web site, we get the latest episode from the rss:
feed
+
+Version 0.0.5
+added five new shows
+added addon settings for video quality
+
+Version 0.0.4
+fixed an issue with TNT
+
+Version 0.0.3
+added release date to title
+added subtitle as plot
+
+Version 0.0.2
+updated icon.png
+
+Version 0.0.1
inital
\ No newline at end of file
diff --git a/plugin.video.twit/default.py b/plugin.video.twit/default.py
index 1c9f378..a08e46d 100644
--- a/plugin.video.twit/default.py
+++ b/plugin.video.twit/default.py
@@ -1,381 +1,407 @@
-import urllib
-import urllib2
-import re
-import os
-import xbmcplugin
-import xbmcgui
-import xbmcaddon
-import StorageServer
-from datetime import datetime
-from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup
-try:
- import json
-except:
- import simplejson as json
-
-addon = xbmcaddon.Addon(id='plugin.video.twit')
-__language__ = addon.getLocalizedString
-addon_version = addon.getAddonInfo('version')
-home = xbmc.translatePath(addon.getAddonInfo('path'))
-fanart = os.path.join(home, 'fanart.jpg')
-icon = os.path.join(home, 'icon.png')
-live_icon = os.path.join(home, 'resources', 'live.png')
-cache = StorageServer.StorageServer("twit", 2)
-debug = addon.getSetting('debug')
-first_run = addon.getSetting('first_run')
-
-
-def addon_log(string):
- if debug == 'true':
- xbmc.log("[addon.TWiT-%s]: %s" %(addon_version, string))
-
-
-def cache_shows_file():
- show_file = os.path.join(home, 'resources', 'shows')
- cache.set("shows", open(show_file, 'r').read())
-
-
-def make_request(url):
- try:
- headers = {'User-agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64;
rv:6.0) Gecko/20100101 Firefox/6.0',
- 'Referer' : 'http://twit.tv'}
- req = urllib2.Request(url,None,headers)
- response = urllib2.urlopen(req)
- data = response.read()
- response.close()
- return data
- except urllib2.URLError, e:
- addon_log( 'We failed to open "%s".' % url)
- if hasattr(e, 'reason'):
- addon_log('We failed to reach a server.')
- addon_log('Reason: ', e.reason)
- if hasattr(e, 'code'):
- addon_log('We failed with error code - %s.' % e.code)
-
-
-def shows_cache(shows):
- url = 'http://twit.tv/shows'
- soup = BeautifulSoup(make_request(url),
convertEntities=BeautifulSoup.HTML_ENTITIES)
- show_items = soup.findAll('div', attrs={'class' :
'item-list'})[2]('li')
- for i in show_items:
- name = str(i('a')[-1].string)
- try:
- show = shows[name]
- except:
- addon_log('Show not in cache: '+name)
- show_url =
('http://twit.tv/show/'+name.replace("'",'').replace('.','').replace('
','-').lower()
-
.replace('-for-the','').replace('the-giz-wiz','weekly-daily-giz-wiz'))
- new_show = cache_show(name, show_url)
- if new_show:
- addon_log('Cached new show: '+name)
- return "True"
-
-
-def cache_show(name, url):
- shows = eval(cache.get('shows'))
- soup = BeautifulSoup(make_request(url),
convertEntities=BeautifulSoup.HTML_ENTITIES)
- try:
- desc = soup.find('div', attrs={'class': "field-content"}).getText()
- if desc == None: raise
- except:
- addon_log('description exception: '+name)
- desc = ''
- try:
- thumb = soup.find('div', attrs={'class' : "views-field
views-field-field-cover-art-fid"})('img')['src']
- if thumb == None: raise
- except:
- addon_log('thumb exception: '+name)
- thumb = icon
- shows[name] = {'show_url': url, 'thumb': thumb, 'description': desc}
- cache.set("shows", repr(shows))
- return True
-
-
-def get_shows(shows):
- addDir(__language__(30000),'latest_episodes',4,icon)
- addLink(__language__(30001),'twit_live','','',3,live_icon)
- cache_shows = eval(cache.cacheFunction(shows_cache, shows))
- if not cache_shows:
- addon_log('shows_cache FAILED')
- for i in shows.keys():
- if i == 'Radio Leo': continue
- addDir(i, shows[i]['show_url'], 1, shows[i]['thumb'],
shows[i]['description'])
-
-
-def index(url,iconimage):
- soup = BeautifulSoup(make_request(url),
convertEntities=BeautifulSoup.HTML_ENTITIES)
- items = soup.findAll('div', attrs={'id' : "primary"})[0]('div',
attrs={'class' : 'field-content'})
- for i in items:
- url = i.a['href']
- if url.startswith('http://twit.tv/show/'):
- name = i.a.string.encode('ascii', 'ignore')
- try:
- description = i.p.string
- except:
- description = ''
- try:
- date = i.findPrevious('span').string
- except:
- date = ''
- addLink(name,url,description,date,2,iconimage)
- try:
- page = 'http://twit.tv'+soup('li', attrs={'class' :
"pager-next"})[0].a['href']
- addDir('Next Page',page,1,iconimage)
- except:
- pass
-
-
-def cache_latest_episods():
- shows = eval(cache.get('shows'))
- url = 'http://twit.tv/'
- soup = BeautifulSoup(make_request(url),
convertEntities=BeautifulSoup.HTML_ENTITIES)
- h_tag = soup.find('h2', attrs={'class': 'block-title'}, text='Most
Recent Episodes')
- items_string = str(h_tag.findNext('div', attrs={'class':
"view-content"})('div'))
- items_string = items_string.replace('\n','').replace('>
<','><').replace('>, <','><')
- pattern = (
- '<span class="field-content">(.+?)</span></div><div
class=".+?"><span class=".+?">'
- '<div class="coverart"><img src="(.+?)" alt="" title=""
width=".+?" height=".+?" class=".+?" />'
- '</div><div class="show-info"><a href="(.+?)">(.+?)</a>(.+?)
</div></span></div><div class=".+?">'
- '<div class="field-content"><p>(.+?)</p>'
- )
- items_list = re.findall(pattern, items_string)
- episode_list = []
- episodes = ''
- for show, thumb, href, episode, date, desc in items_list:
- if episode in episodes:
- addon_log('episode already in list')
- continue
- name = '%s - %s' %(show, episode)
- try:
- thumbnail = shows[show]['thumb']
- except:
- addon_log('thumbnail exception: '+show)
- thumbnail = thumb
- episode_list.append((name,href,desc,date,thumbnail))
- episodes += episode+', '
- return episode_list
-
-
-def get_latest_episodes():
- episodes = cache.cacheFunction(cache_latest_episods)
- for i in episodes:
- addLink(i[0], i[1], i[2], i[3], 2, i[4])
-
-
-def set_media_url(url):
- playback_settings = {
- '0': 'hd download',
- '1': 'sd download',
- '2': 'download',
- '3': 'audio download'
- }
- soup = BeautifulSoup(make_request(url),
convertEntities=BeautifulSoup.HTML_ENTITIES)
- media_urls = {}
- for i in soup('span', attrs={'class' : "download"}):
- media_urls[i.a['class']] = i.a['href']
- if content_type == 'audio':
- playback_setting = '3'
- playback_type = 'audio download'
- else:
- playback_setting = addon.getSetting('playback')
- playback_type = playback_settings[playback_setting]
- playback_url = None
- if media_urls.has_key(playback_type):
- playback_url = media_urls[playback_type]
- else:
- p_set = int(playback_setting)
- if (p_set + 1) <= 3:
- for i in range(len(playback_settings)):
- p_set += 1
- if p_set < 3:
- try:
- playback_url =
media_urls[playback_settings[str(p_set)]]
- break
- except: continue
- if not playback_url:
- dialog = xbmcgui.Dialog()
- ret = dialog.select(__language__(30002), media_urls.keys())
- playback_url = media_urls.values()[ret]
-
- if playback_url:
- success = True
- else:
- success = False
- playback_url = ''
- item = xbmcgui.ListItem(path=playback_url)
- xbmcplugin.setResolvedUrl(int(sys.argv[1]), success, item)
-
-
-def twit_live():
- live_streams = [
-
'http://twit.live-s.cdn.bitgravity.com/cdn-live-s1/_definst_/twit/live/high/playlist.m3u8',
-
'http://twit.live-s.cdn.bitgravity.com/cdn-live-s1/_definst_/twit/live/low/playlist.m3u8',
- 'http://bglive-a.bitgravity.com/twit/live/high?noprefix',
- 'http://bglive-a.bitgravity.com/twit/live/low?noprefix',
- 'ustream',
- 'justintv',
-
'http://hls.twit.tv:1935/flosoft/_definst_/mp4:twitStreamHi_1628/playlist.m3u8',
-
'http://hls.twit.tv:1935/flosoft/_definst_/mp4:twitStream_1128/playlist.m3u8',
-
'http://hls.twit.tv:1935/flosoft/_definst_/mp4:twitStream_696/playlist.m3u8',
-
'http://hls.twit.tv:1935/flosoft/_definst_/mp4:twitStream_496/playlist.m3u8',
- 'http://twit.am/listen'
- ]
- if content_type == 'audio':
- link = 'http://twit.am/listen'
- else:
- link = live_streams[int(addon.getSetting('twit_live'))]
- if link == 'justintv':
- link = get_jtv()
- elif link == 'ustream':
- link = get_ustream()
- item = xbmcgui.ListItem(path=link)
- xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, item)
-
-
-def get_ustream():
- def getSwf():
- url = 'http://www.ustream.tv/flash/viewer.swf'
- req = urllib2.Request(url)
- response = urllib2.urlopen(req)
- swfUrl = response.geturl()
- return swfUrl
- data =
make_request('http://cgw.ustream.tv/Viewer/getStream/1/1524.amf')
- match = re.compile('.*(rtmp://.+?)\x00.*').findall(data)
- rtmp = match[0]
- sName = re.compile('.*streamName\W\W\W(.+?)[/]*\x00.*').findall(data)
- playpath = ' playpath='+sName[0]
- swf = ' swfUrl='+getSwf()
- pageUrl = ' pageUrl=http://live.twit.tv'
- url = rtmp + playpath + swf + pageUrl + ' swfVfy=1 live=true'
- return url
-
-
-def get_jtv():
- soup =
BeautifulSoup(make_request('http://usher.justin.tv/find/twit.xml?type=live'))
- token = ' jtv='+soup.token.string.replace('\\','\\5c').replace('
','\\20').replace('"','\\22')
- rtmp = soup.connect.string+'/'+soup.play.string
- Pageurl = ' Pageurl=http://www.justin.tv/twit'
- swf = '
swfUrl=http://www.justin.tv/widgets/live_embed_player.swf?channel=twit
live=true'
- url = rtmp+token+swf+Pageurl
- return url
-
-
-def get_params():
- param=[]
- paramstring=sys.argv[2]
- if len(paramstring)>=2:
- params=sys.argv[2]
- cleanedparams=params.replace('?','')
- if (params[len(params)-1]=='/'):
- params=params[0:len(params)-2]
- pairsofparams=cleanedparams.split('&')
- param={}
- for i in range(len(pairsofparams)):
- splitparams={}
- splitparams=pairsofparams[i].split('=')
- if (len(splitparams))==2:
- param[splitparams[0]]=splitparams[1]
- return param
-
-
-def addLink(name,url,description,date,mode,iconimage):
-
u=(sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)+
-
"&iconimage="+urllib.quote_plus(iconimage)+"&content_type="+content_type)
- ok=True
- episode = None
- try: episode = int(re.findall('#(.+?):', name)[0])
- except:
- try: episode = int(name.split(' ')[-1])
- except: pass
- liz=xbmcgui.ListItem(name, iconImage=iconimage,
thumbnailImage=iconimage)
- liz.setInfo(type="Video", infoLabels={"Title": name,
"Plot":description, "Aired": date, "episode": episode})
- liz.setProperty("Fanart_Image", fanart)
- liz.setProperty('IsPlayable', 'true')
-
ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz)
- return ok
-
-
-def addDir(name,url,mode,iconimage,description=None):
-
u=(sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)+
-
"&iconimage="+urllib.quote_plus(iconimage)+"&content_type="+content_type)
- ok=True
- liz=xbmcgui.ListItem(name, iconImage=iconimage,
thumbnailImage=iconimage)
- liz.setInfo(type="Video", infoLabels={"Title": name,
"Plot":description})
- liz.setProperty( "Fanart_Image", fanart )
-
ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=True)
- return ok
-
-
-if debug == 'true':
- cache.dbg = True
-
-if first_run == 'true':
- cache_shows_file()
- addon_log('first_run, caching shows file')
- xbmc.sleep(1000)
- addon.setSetting('first_run', 'false')
-
-params=get_params()
-url=None
-name=None
-mode=None
-content_type='video'
-
-try:
- url=urllib.unquote_plus(params["url"])
-except:
- pass
-try:
- name=urllib.unquote_plus(params["name"])
-except:
- pass
-try:
- iconimage=urllib.unquote_plus(params["iconimage"])
-except:
- pass
-try:
- mode=int(params["mode"])
-except:
- pass
-try:
- content_type=str(params["content_type"])
-except:
- pass
-
-addon_log("Mode: "+str(mode))
-addon_log("URL: "+str(url))
-addon_log("Name: "+str(name))
-
-if mode==None:
- try:
- shows = eval(cache.get('shows'))
- if isinstance(shows, dict):
- get_shows(shows)
- else: raise
- except:
- addon_log('"shows" cache missing')
- cache_shows_file()
- addon_log('caching shows file, this should only happen if common cache
db is reset')
- xbmc.sleep(1000)
- shows = eval(cache.get('shows'))
- if isinstance(shows, dict):
- get_shows(shows)
- else:
- addon_log('"shows" cache ERROR')
- xbmcplugin.setContent(int(sys.argv[1]), 'tvshows')
-
-elif mode==1:
- index(url,iconimage)
- xbmcplugin.setContent(int(sys.argv[1]), 'episodes')
-
-elif mode==2:
- set_media_url(url)
-
-elif mode==3:
- twit_live()
-
-elif mode==4:
- get_latest_episodes()
- xbmcplugin.setContent(int(sys.argv[1]), 'episodes')
-
-xbmcplugin.endOfDirectory(int(sys.argv[1]))
\ No newline at end of file
+import urllib
+import urllib2
+import re
+import os
+import xbmcplugin
+import xbmcgui
+import xbmcaddon
+import StorageServer
+from datetime import datetime
+from pyamf import remoting
+from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup
+try:
+ import json
+except:
+ import simplejson as json
+
+addon = xbmcaddon.Addon(id='plugin.video.twit')
+__language__ = addon.getLocalizedString
+addon_version = addon.getAddonInfo('version')
+home = xbmc.translatePath(addon.getAddonInfo('path'))
+fanart = os.path.join(home, 'fanart.jpg')
+icon = os.path.join(home, 'icon.png')
+live_icon = os.path.join(home, 'resources', 'live.png')
+cache = StorageServer.StorageServer("twit", 2)
+debug = addon.getSetting('debug')
+first_run = addon.getSetting('first_run')
+
+
+def addon_log(string):
+ if debug == 'true':
+ xbmc.log("[addon.TWiT-%s]: %s" %(addon_version, string))
+
+
+def cache_shows_file():
+ show_file = os.path.join(home, 'resources', 'shows')
+ cache.set("shows", open(show_file, 'r').read())
+
+
+def make_request(url):
+ try:
+ headers = {'User-agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64;
rv:6.0) Gecko/20100101 Firefox/6.0',
+ 'Referer' : 'http://twit.tv'}
+ req = urllib2.Request(url,None,headers)
+ response = urllib2.urlopen(req)
+ data = response.read()
+ response.close()
+ return data
+ except urllib2.URLError, e:
+ addon_log( 'We failed to open "%s".' % url)
+ if hasattr(e, 'reason'):
+ addon_log('We failed to reach a server.')
+ addon_log('Reason: ', e.reason)
+ if hasattr(e, 'code'):
+ addon_log('We failed with error code - %s.' % e.code)
+
+
+def shows_cache(shows):
+ url = 'http://twit.tv/shows'
+ soup = BeautifulSoup(make_request(url),
convertEntities=BeautifulSoup.HTML_ENTITIES)
+ show_items = soup.findAll('div', attrs={'class' :
'item-list'})[2]('li')
+ for i in show_items:
+ name = str(i('a')[-1].string)
+ try:
+ show = shows[name]
+ except:
+ addon_log('Show not in cache: '+name)
+ show_url =
('http://twit.tv/show/'+name.replace("'",'').replace('.','').replace('
','-').lower()
+
.replace('-for-the','').replace('the-giz-wiz','weekly-daily-giz-wiz'))
+ new_show = cache_show(name, show_url)
+ if new_show:
+ addon_log('Cached new show: '+name)
+ return "True"
+
+
+def cache_show(name, url):
+ shows = eval(cache.get('shows'))
+ soup = BeautifulSoup(make_request(url),
convertEntities=BeautifulSoup.HTML_ENTITIES)
+ try:
+ desc = soup.find('div', attrs={'class': "field-content"}).getText()
+ if desc == None: raise
+ except:
+ addon_log('description exception: '+name)
+ desc = ''
+ try:
+ thumb = soup.find('div', attrs={'class' : "views-field
views-field-field-cover-art-fid"})('img')['src']
+ if thumb == None: raise
+ except:
+ addon_log('thumb exception: '+name)
+ thumb = icon
+ shows[name] = {'show_url': url, 'thumb': thumb, 'description': desc}
+ cache.set("shows", repr(shows))
+ return True
+
+
+def get_shows(shows):
+ addDir(__language__(30000),'latest_episodes',4,icon)
+ addLink(__language__(30001),'twit_live','','',3,live_icon)
+ cache_shows = eval(cache.cacheFunction(shows_cache, shows))
+ if not cache_shows:
+ addon_log('shows_cache FAILED')
+ for i in shows.keys():
+ if i == 'Radio Leo': continue
+ addDir(i, shows[i]['show_url'], 1, shows[i]['thumb'],
shows[i]['description'])
+
+
+def index(url,iconimage):
+ soup = BeautifulSoup(make_request(url),
convertEntities=BeautifulSoup.HTML_ENTITIES)
+ items = soup.findAll('div', attrs={'id' : "primary"})[0]('div',
attrs={'class' : 'field-content'})
+ for i in items:
+ url = i.a['href']
+ if url.startswith('http://twit.tv/show/'):
+ name = i.a.string.encode('ascii', 'ignore')
+ try:
+ description = i.p.string
+ except:
+ description = ''
+ try:
+ date = i.findPrevious('span').string
+ except:
+ date = ''
+ addLink(name,url,description,date,2,iconimage)
+ try:
+ page = 'http://twit.tv'+soup('li', attrs={'class' :
"pager-next"})[0].a['href']
+ addDir('Next Page',page,1,iconimage)
+ except:
+ pass
+
+
+def cache_latest_episods():
+ shows = eval(cache.get('shows'))
+ url = 'http://twit.tv/'
+ soup = BeautifulSoup(make_request(url),
convertEntities=BeautifulSoup.HTML_ENTITIES)
+ h_tag = soup.find('h2', attrs={'class': 'block-title'}, text='Most
Recent Episodes')
+ items_string = str(h_tag.findNext('div', attrs={'class':
"view-content"})('div'))
+ items_string = items_string.replace('\n','').replace('>
<','><').replace('>, <','><')
+ pattern = (
+ '<span class="field-content">(.+?)</span></div><div
class=".+?"><span class=".+?">'
+ '<div class="coverart"><img src="(.+?)" alt="" title=""
width=".+?" height=".+?" class=".+?" />'
+ '</div><div class="show-info"><a href="(.+?)">(.+?)</a>(.+?)
</div></span></div><div class=".+?">'
+ '<div class="field-content"><p>(.+?)</p>'
+ )
+ items_list = re.findall(pattern, items_string)
+ episode_list = []
+ episodes = ''
+ for show, thumb, href, episode, date, desc in items_list:
+ if episode in episodes:
+ addon_log('episode already in list')
+ continue
+ name = '%s - %s' %(show, episode)
+ try:
+ thumbnail = shows[show]['thumb']
+ except:
+ addon_log('thumbnail exception: '+show)
+ thumbnail = thumb
+ episode_list.append((name,href,desc,date,thumbnail))
+ episodes += episode+', '
+ return episode_list
+
+
+def get_latest_episodes():
+ episodes = cache.cacheFunction(cache_latest_episods)
+ for i in episodes:
+ addLink(i[0], i[1], i[2], i[3], 2, i[4])
+
+
+def set_media_url(url):
+ playback_settings = {
+ '0': 'hd download',
+ '1': 'sd download',
+ '2': 'download',
+ '3': 'audio download'
+ }
+ soup = BeautifulSoup(make_request(url),
convertEntities=BeautifulSoup.HTML_ENTITIES)
+ media_urls = {}
+ for i in soup('span', attrs={'class' : "download"}):
+ media_urls[i.a['class']] = i.a['href']
+ if content_type == 'audio':
+ playback_setting = '3'
+ playback_type = 'audio download'
+ else:
+ playback_setting = addon.getSetting('playback')
+ playback_type = playback_settings[playback_setting]
+ playback_url = None
+ if media_urls.has_key(playback_type):
+ playback_url = media_urls[playback_type]
+ else:
+ p_set = int(playback_setting)
+ if (p_set + 1) <= 3:
+ for i in range(len(playback_settings)):
+ p_set += 1
+ if p_set < 3:
+ try:
+ playback_url =
media_urls[playback_settings[str(p_set)]]
+ break
+ except: continue
+ if not playback_url:
+ dialog = xbmcgui.Dialog()
+ ret = dialog.select(__language__(30002), media_urls.keys())
+ playback_url = media_urls.values()[ret]
+
+ if playback_url:
+ success = True
+ else:
+ success = False
+ playback_url = ''
+ item = xbmcgui.ListItem(path=playback_url)
+ xbmcplugin.setResolvedUrl(int(sys.argv[1]), success, item)
+
+
+def twit_live():
+ live_streams = [
+
'http://twit.live-s.cdn.bitgravity.com/cdn-live-s1/_definst_/twit/live/high/playlist.m3u8',
+
'http://twit.live-s.cdn.bitgravity.com/cdn-live-s1/_definst_/twit/live/low/playlist.m3u8',
+ 'http://bglive-a.bitgravity.com/twit/live/high?noprefix',
+ 'http://bglive-a.bitgravity.com/twit/live/low?noprefix',
+ 'ustream',
+ 'justintv',
+
'http://hls.twit.tv:1935/flosoft/_definst_/mp4:twitStreamHi_1628/playlist.m3u8',
+
'http://hls.twit.tv:1935/flosoft/_definst_/mp4:twitStream_1128/playlist.m3u8',
+
'http://hls.twit.tv:1935/flosoft/_definst_/mp4:twitStream_696/playlist.m3u8',
+
'http://hls.twit.tv:1935/flosoft/_definst_/mp4:twitStream_496/playlist.m3u8',
+ 'http://twit.am/listen'
+ ]
+ if content_type == 'audio':
+ link = 'http://twit.am/listen'
+ else:
+ link = live_streams[int(addon.getSetting('twit_live'))]
+ if link == 'justintv':
+ link = get_jtv()
+ elif link == 'ustream':
+ link = get_ustream()
+ success = False
+ if link:
+ success = True
+ else: link = ''
+ item = xbmcgui.ListItem(path=link)
+ xbmcplugin.setResolvedUrl(int(sys.argv[1]), success, item)
+
+
+def get_ustream():
+ def getSwf():
+ url = 'http://www.ustream.tv/flash/viewer.swf'
+ req = urllib2.Request(url)
+ response = urllib2.urlopen(req)
+ swfUrl = response.geturl()
+ return swfUrl
+ data =
make_request('http://cgw.ustream.tv/Viewer/getStream/1/1524.amf')
+ amf_data = remoting.decode(data).bodies[0][1].body
+ if amf_data['success']:
+ hls_url = None
+ if amf_data.has_key('liveHttpUrl'):
+ try: hls_url = amf_data['liveHttpUrl']
+ except: pass
+ if hls_url:
+ return hls_url
+ else:
+ streams = None
+ try:
+ streams =
amf_data['streamVersions']['streams/live_1']['streamVersionCdn']
+ except: pass
+ if streams:
+ for i in streams.keys():
+ rtmp = streams[i].values()[0]
+ path = streams[i].values()[1]
+ break
+ playpath = ' playpath='+path
+ swf = ' swfUrl='+getSwf()
+ pageUrl = ' pageUrl=http://live.twit.tv'
+ url = rtmp + playpath + swf + pageUrl + ' swfVfy=1
live=true'
+ return url
+ else:
+ return None
+
+
+def get_jtv():
+ try:
+ soup =
BeautifulSoup(make_request('http://usher.justin.tv/find/twit.xml?type=live'))
+ token = ' jtv='+soup.token.string.replace('\\','\\5c').replace('
','\\20').replace('"','\\22')
+ rtmp = soup.connect.string+'/'+soup.play.string
+ Pageurl = ' Pageurl=http://www.justin.tv/twit'
+ swf = '
swfUrl=http://www.justin.tv/widgets/live_embed_player.swf?channel=twit
live=true'
+ url = rtmp+token+swf+Pageurl
+ return url
+ except:
+ return None
+
+
+def get_params():
+ param=[]
+ paramstring=sys.argv[2]
+ if len(paramstring)>=2:
+ params=sys.argv[2]
+ cleanedparams=params.replace('?','')
+ if (params[len(params)-1]=='/'):
+ params=params[0:len(params)-2]
+ pairsofparams=cleanedparams.split('&')
+ param={}
+ for i in range(len(pairsofparams)):
+ splitparams={}
+ splitparams=pairsofparams[i].split('=')
+ if (len(splitparams))==2:
+ param[splitparams[0]]=splitparams[1]
+ return param
+
+
+def addLink(name,url,description,date,mode,iconimage):
+
u=(sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)+
+
"&iconimage="+urllib.quote_plus(iconimage)+"&content_type="+content_type)
+ ok=True
+ episode = None
+ try: episode = int(re.findall('#(.+?):', name)[0])
+ except:
+ try: episode = int(name.split(' ')[-1])
+ except: pass
+ liz=xbmcgui.ListItem(name, iconImage=iconimage,
thumbnailImage=iconimage)
+ liz.setInfo(type="Video", infoLabels={"Title": name,
"Plot":description, "Aired": date, "episode": episode})
+ liz.setProperty("Fanart_Image", fanart)
+ liz.setProperty('IsPlayable', 'true')
+
ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz)
+ return ok
+
+
+def addDir(name,url,mode,iconimage,description=None):
+
u=(sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)+
+
"&iconimage="+urllib.quote_plus(iconimage)+"&content_type="+content_type)
+ ok=True
+ liz=xbmcgui.ListItem(name, iconImage=iconimage,
thumbnailImage=iconimage)
+ liz.setInfo(type="Video", infoLabels={"Title": name,
"Plot":description})
+ liz.setProperty( "Fanart_Image", fanart )
+
ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=True)
+ return ok
+
+
+if debug == 'true':
+ cache.dbg = True
+
+if first_run == 'true':
+ cache_shows_file()
+ addon_log('first_run, caching shows file')
+ xbmc.sleep(1000)
+ addon.setSetting('first_run', 'false')
+
+params=get_params()
+url=None
+name=None
+mode=None
+content_type='video'
+
+try:
+ url=urllib.unquote_plus(params["url"])
+except:
+ pass
+try:
+ name=urllib.unquote_plus(params["name"])
+except:
+ pass
+try:
+ iconimage=urllib.unquote_plus(params["iconimage"])
+except:
+ pass
+try:
+ mode=int(params["mode"])
+except:
+ pass
+try:
+ content_type=str(params["content_type"])
+except:
+ pass
+
+addon_log("Mode: "+str(mode))
+addon_log("URL: "+str(url))
+addon_log("Name: "+str(name))
+
+if mode==None:
+ try:
+ shows = eval(cache.get('shows'))
+ if isinstance(shows, dict):
+ get_shows(shows)
+ else: raise
+ except:
+ addon_log('"shows" cache missing')
+ cache_shows_file()
+ addon_log('caching shows file, this should only happen if common cache
db is reset')
+ xbmc.sleep(1000)
+ shows = eval(cache.get('shows'))
+ if isinstance(shows, dict):
+ get_shows(shows)
+ else:
+ addon_log('"shows" cache ERROR')
+ xbmcplugin.setContent(int(sys.argv[1]), 'tvshows')
+ xbmcplugin.endOfDirectory(int(sys.argv[1]))
+
+elif mode==1:
+ index(url,iconimage)
+ xbmcplugin.setContent(int(sys.argv[1]), 'episodes')
+ xbmcplugin.endOfDirectory(int(sys.argv[1]))
+
+elif mode==2:
+ set_media_url(url)
+
+elif mode==3:
+ twit_live()
+
+elif mode==4:
+ get_latest_episodes()
+ xbmcplugin.setContent(int(sys.argv[1]), 'episodes')
+ xbmcplugin.endOfDirectory(int(sys.argv[1]))
diff --git a/plugin.video.twit/resources/language/English/strings.xml
b/plugin.video.twit/resources/language/English/strings.xml
index 0595507..02d195b 100644
--- a/plugin.video.twit/resources/language/English/strings.xml
+++ b/plugin.video.twit/resources/language/English/strings.xml
@@ -1,24 +1,24 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<strings>
- <string id='30000'>Latest Episodes</string>
- <string id="30001">TWiT Live</string>
- <string id="30002">Available Streams</string>
- <string id="30003">Bitgravity (hls 1 mbps)</string>
- <string id="30004">Bitgravity (hls 400 kbps)</string>
- <string id='30005'>Bitgravity (http 1 mbps)</string>
- <string id="30006">Bitgravity (http 400 kbps)</string>
- <string id="30007">Ustream (rtmp 1.5 mbps)</string>
- <string id="30008">JustinTV (rtmp 1 mbps)</string>
- <string id="30009">Flosoft.biz (hls 1.5 mbps)</string>
- <string id='30010'>Flosoft.biz (hls 1 mbps)</string>
- <string id='30011'>Flosoft.biz (hls 600 kbps)</string>
- <string id="30012">Flosoft.biz (hls 400 kbps)</string>
- <string id="30013">Audio TWiT.am/listen</string>
- <string id="30014">Playback Type</string>
- <string id="30015">Video (HD) 1280x720 Bitrate 2500</string>
- <string id="30016">Video (SD) 864x480 Bitrate 500</string>
- <string id="30017">Video (low/mobile) 640x368 Bitrate 256</string>
- <string id="30018">Audio</string>
- <string id="30019">Add-on Debugging</string>
- <string id="30020"></string>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<strings>
+ <string id='30000'>Latest Episodes</string>
+ <string id="30001">TWiT Live</string>
+ <string id="30002">Available Streams</string>
+ <string id="30003">Bitgravity (hls 1 mbps)</string>
+ <string id="30004">Bitgravity (hls 400 kbps)</string>
+ <string id='30005'>Bitgravity (http 1 mbps)</string>
+ <string id="30006">Bitgravity (http 400 kbps)</string>
+ <string id="30007">Ustream (rtmp 1.5 mbps)</string>
+ <string id="30008">JustinTV (rtmp 1 mbps)</string>
+ <string id="30009">Flosoft.biz (hls 1.5 mbps)</string>
+ <string id='30010'>Flosoft.biz (hls 1 mbps)</string>
+ <string id='30011'>Flosoft.biz (hls 600 kbps)</string>
+ <string id="30012">Flosoft.biz (hls 400 kbps)</string>
+ <string id="30013">Audio TWiT.am/listen</string>
+ <string id="30014">Playback Type</string>
+ <string id="30015">Video (HD) 1280x720 Bitrate 2500</string>
+ <string id="30016">Video (SD) 864x480 Bitrate 500</string>
+ <string id="30017">Video (low/mobile) 640x368 Bitrate 256</string>
+ <string id="30018">Audio</string>
+ <string id="30019">Add-on Debugging</string>
+ <string id="30020"></string>
</strings>
\ No newline at end of file
diff --git a/plugin.video.twit/resources/settings.xml
b/plugin.video.twit/resources/settings.xml
index d843226..fc94a39 100644
--- a/plugin.video.twit/resources/settings.xml
+++ b/plugin.video.twit/resources/settings.xml
@@ -1,6 +1,6 @@
-<settings>
- <setting id="playback" type="enum" lvalues="30015|30016|30017|30018"
label="30014" default="1" />
- <setting id="twit_live" label="30001" type="select"
lvalues="30003|30004|30005|30006|30007|30008|30009|30010|30011|30012|30013"
default="4" />
- <setting id="debug" type="bool" label="30019" default="false" />
- <setting id="first_run" type="bool" visible="false" default="true" />
+<settings>
+ <setting id="playback" type="enum" lvalues="30015|30016|30017|30018"
label="30014" default="1" />
+ <setting id="twit_live" label="30001" type="select"
lvalues="30003|30004|30005|30006|30007|30008|30009|30010|30011|30012|30013"
default="4" />
+ <setting id="debug" type="bool" label="30019" default="false" />
+ <setting id="first_run" type="bool" visible="false" default="true" />
</settings>
\ No newline at end of file
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=b3b7ef23f916b8d3f45eadce53a43c08ce6fa2d7
commit b3b7ef23f916b8d3f45eadce53a43c08ce6fa2d7
Author: beenje <bee...@xbmc.org>
Date: Sun Mar 17 22:09:14 2013 +0100
[plugin.audio.groove] updated to version 2.0.2
diff --git a/plugin.audio.groove/addon.xml b/plugin.audio.groove/addon.xml
index 8dffb03..811f4af 100644
--- a/plugin.audio.groove/addon.xml
+++ b/plugin.audio.groove/addon.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.audio.groove" name="Grooveshark XBMC"
- version="2.0.0" provider-name="Stephen Denham">
+ version="2.0.2" provider-name="Stephen Denham">
<requires>
<import addon="xbmc.python" version="2.1.0" />
<import addon="script.module.simplejson"/>
diff --git a/plugin.audio.groove/changelog.txt
b/plugin.audio.groove/changelog.txt
index df64849..bf1d2fe 100644
--- a/plugin.audio.groove/changelog.txt
+++ b/plugin.audio.groove/changelog.txt
@@ -1,3 +1,12 @@
+2.0.2
+
+Correct icon resolution.
+
+2.0.1
+
+Better resolution icon.
+Fix playlists with accented characters.
+
2.0.0
Frodo version.
diff --git a/plugin.audio.groove/icon.png b/plugin.audio.groove/icon.png
index 2d2ba74..38434b4 100644
Binary files a/plugin.audio.groove/icon.png and b/plugin.audio.groove/icon.png
differ
diff --git a/plugin.audio.groove/resources/lib/GroovesharkAPI.py
b/plugin.audio.groove/resources/lib/GroovesharkAPI.py
index 9956897..282c94f 100644
--- a/plugin.audio.groove/resources/lib/GroovesharkAPI.py
+++ b/plugin.audio.groove/resources/lib/GroovesharkAPI.py
@@ -556,6 +556,6 @@ class GrooveAPI:
while (i < len(playlists)):
s = playlists[i]
- list.append([str(s['PlaylistName']).encode('utf8',
'ignore'), s['PlaylistID']])
+ list.append([unicode(s['PlaylistName']).encode('utf8',
'ignore'), s['PlaylistID']])
i = i + 1
return list
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=a3b677436e56ddee88725dc43708c089dfa343c8
-----------------------------------------------------------------------
Summary of changes:
plugin.audio.groove/addon.xml | 2 +-
plugin.audio.groove/changelog.txt | 9 +
plugin.audio.groove/icon.png | Bin 262963 -> 67867 bytes
.../resources/lib/GroovesharkAPI.py | 2 +-
.../LICENSE.txt | 0
plugin.video.itbn_org/addon.xml | 21 +
plugin.video.itbn_org/changelog.txt | 10 +
plugin.video.itbn_org/default.py | 465 ++++++++++++
plugin.video.itbn_org/icon.png | Bin 0 -> 44134 bytes
.../resources/language/English/strings.xml | 0
.../resources/media}/live.png | Bin 17048 -> 17048 bytes
.../resources/media/main_menu.png | Bin 0 -> 28384 bytes
.../resources/media}/movies.png | Bin 51020 -> 51020 bytes
.../resources/media/nextpage.png | Bin 18680 -> 18680 bytes
.../resources/media/previouspage.png | Bin 0 -> 18839 bytes
.../resources/media}/search.png | Bin 34942 -> 34942 bytes
plugin.video.itbn_org/resources/settings.xml | 12 +
plugin.video.twit/addon.xml | 45 +-
plugin.video.twit/changelog.txt | 155 ++--
plugin.video.twit/default.py | 788 ++++++++++----------
.../resources/language/English/strings.xml | 46 +-
plugin.video.twit/resources/settings.xml | 10 +-
plugin.video.twit/resources/storageserverdummy.py | 30 -
23 files changed, 1057 insertions(+), 538 deletions(-)
copy {plugin.audio.dradio => plugin.video.itbn_org}/LICENSE.txt (100%)
create mode 100644 plugin.video.itbn_org/addon.xml
create mode 100644 plugin.video.itbn_org/changelog.txt
create mode 100644 plugin.video.itbn_org/default.py
create mode 100644 plugin.video.itbn_org/icon.png
copy {plugin.video.dtm_tv =>
plugin.video.itbn_org}/resources/language/English/strings.xml (100%)
copy {plugin.video.bliptv/thumbnails =>
plugin.video.itbn_org/resources/media}/live.png (100%)
create mode 100644 plugin.video.itbn_org/resources/media/main_menu.png
copy {plugin.video.bliptv/thumbnails =>
plugin.video.itbn_org/resources/media}/movies.png (100%)
copy plugin.video.bliptv/thumbnails/next.png =>
plugin.video.itbn_org/resources/media/nextpage.png (100%)
create mode 100644 plugin.video.itbn_org/resources/media/previouspage.png
copy {plugin.video.bliptv/thumbnails =>
plugin.video.itbn_org/resources/media}/search.png (100%)
create mode 100644 plugin.video.itbn_org/resources/settings.xml
delete mode 100644 plugin.video.twit/resources/storageserverdummy.py
hooks/post-receive
--
Plugins
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Xbmc-addons mailing list
Xbmc-addons@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/xbmc-addons