The branch, frodo has been updated
via 9ced68fe14f585da26ec056a8b16ca9674908585 (commit)
from cdc4700e89c003d8e70d4855d8ea0ce850a82ce4 (commit)
- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=9ced68fe14f585da26ec056a8b16ca9674908585
commit 9ced68fe14f585da26ec056a8b16ca9674908585
Author: sphere <[email protected]>
Date: Fri Mar 28 11:32:59 2014 +0100
[plugin.video.gfq] updated to version 2.0.0
diff --git a/plugin.video.gfq/addon.xml b/plugin.video.gfq/addon.xml
index c4c5e0a..f234ad9 100644
--- a/plugin.video.gfq/addon.xml
+++ b/plugin.video.gfq/addon.xml
@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.gfq"
name="GFQ"
- version="1.1.0"
- provider-name="Bawitdaba <[email protected]>">
+ version="2.0.0"
+ provider-name="Bawitdaba">
<requires>
<import addon="xbmc.python" version="2.1.0"/>
- <import addon="script.module.beautifulsoup" version="3.0.8"/>
+ <import addon="script.module.beautifulsoup4" version="4.3.1"/>
+ <import addon="script.common.plugin.cache" version="2.5.2"/>
</requires>
- <extension point="xbmc.python.pluginsource"
- library="default.py">
- <provides>video</provides>
+ <extension point="xbmc.python.pluginsource" library="default.py">
+ <provides>audio video</provides>
</extension>
<extension point="xbmc.addon.metadata">
- <summary lang="en">GFQ</summary>
- <description lang="en">[B]Guys From Queens[/B]
+ <summary lang="en">Guys From Queens Network</summary>
+ <description lang="en">Watch live shows and previously recorded podcasts
from the Guys From Queens (GFQ) Network
-Watch live shows and previously recorded podcasts from the Guys From Queens
(GFQ) Network
-
-http://www.guysfromqueens.com
-http://www.gfqlive.tv</description>
+http://www.gfqnetwork.com</description>
<platform>all</platform>
<language>en</language>
+ <license>GNU GENERAL PUBLIC LICENSE. Version 2, June 1991</license>
+ <source>https://code.google.com/p/gfq-xbmc/</source>
+ <forum></forum>
+ <website>http://www.gfqnetwork.com/</website>
</extension>
- <license>GNU GENERAL PUBLIC LICENSE. Version 2, June 1991</license>
</addon>
\ No newline at end of file
diff --git a/plugin.video.gfq/changelog.txt b/plugin.video.gfq/changelog.txt
index a87e6e8..bf99209 100644
--- a/plugin.video.gfq/changelog.txt
+++ b/plugin.video.gfq/changelog.txt
@@ -1,4 +1,16 @@
-[B]1.1.0[/B]
+2.0.0
+- Full Addon Rewrite, all functions re-written or re-derived from source
+- Changed fanart.jpg to match GFQ Website Redesign
+- Changed icon.png to match new GFQ Logo
+- Changed shows to be pulled from OPML XML file at
http://www.gfqnetwork.com/roku/config.opml instead of scraping website
+- Added Caching to Latest Episodes and GFQ Show Names
+- Added Podcast Stream Information for Episode Number, Aired Date, Runtime,
Video Resolution, Video Codec, Video Aspect Ratio, Audio Codec, and Audio
Channels
+- Added GFQ Live Stream Information for Video Resolution, Video Codec, Video
Aspect Ratio, Audio Codec, and Audio Channels
+- Removed GFQ Live - Vaughn link
+- Added GFQ Live - Dailymotion
+- Fixed GFQ Live - Justin.tv not working. Now using HLS iPad/Mobile links
+- Fixed GFQ Live - Ustream not working. Now using HLS iPad/Mobile links
+1.1.0
- Changed show series to be listed dynamically from
http://www.guysfromqueens.com/feeds/
- Added Latest Episodes for a recent listing of GFQ Network shows
- Fixed a bug where due to a feedburner formatting issue the RSS Video feeds
(Episodes) were not getting loaded properly
@@ -6,6 +18,5 @@
- Added Vaughn live streaming service to GFQ Live menu
- Added live streaming audio only to the GFQ Live menu
- Changed GFQ Live titles to match the correct bitrate of the streams
-
-[B]1.0.0[/B]
+1.0.0
- Initial release, derived from the TWiT addon made by divingmule and Adam B
\ No newline at end of file
diff --git a/plugin.video.gfq/default.py b/plugin.video.gfq/default.py
index 578762f..ba157a6 100644
--- a/plugin.video.gfq/default.py
+++ b/plugin.video.gfq/default.py
@@ -1,3 +1,5 @@
+# -*- coding: utf-8 -*-
+
#############################################################################################
#
# Name: plugin.video.gfq
@@ -8,311 +10,357 @@
#
#############################################################################################
-import urllib,urllib2,re,os
-import xbmcplugin,xbmcgui,xbmcaddon
-from BeautifulSoup import BeautifulSoup
-
-__settings__ = xbmcaddon.Addon(id='plugin.video.gfq')
-__language__ = __settings__.getLocalizedString
-home = __settings__.getAddonInfo('path')
-fanart = xbmc.translatePath( os.path.join( home, 'fanart.jpg' ) )
-
-
-def categories():
- addDir(__language__(30000),'addLiveLinks',3,xbmc.translatePath(
os.path.join( home, 'resources/live.png' ) ))
-
addDir(__language__(30100),'http://blip.tv/gfqnetwork/rss',1,xbmc.translatePath(
os.path.join( home, 'resources/live.png' ) ))
-
- headers = {'User-agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0)
Gecko/20100101 Firefox/6.0'}
- req =
urllib2.Request('http://www.guysfromqueens.com/feeds',None,headers)
- response = urllib2.urlopen(req)
- showHTML=response.read()
- response.close()
-
- showHTML=showHTML.replace('&','&')
- showHTML=showHTML.replace('"','"')
- showHTML=showHTML.replace(''',"'")
- showHTML=showHTML.replace(''',"'")
- showHTML=showHTML.replace('<','<')
- showHTML=showHTML.replace('>','>')
- showHTML=showHTML.replace(' ',' ')
- showHTML=showHTML.replace('­','-')
-
- # Cut HTML off before inactive shows are listed
- showHTML=showHTML.split('id="searchform"')[0]
-
- soup = BeautifulSoup(showHTML,
convertEntities=BeautifulSoup.HTML_ENTITIES)
-
- items_left = soup.findAll('div', attrs={'style' : "float: left; width:
300px; margin: 0 30px 20px 0;"})
- items_right = soup.findAll('div', attrs={'style' : "float: left;
width: 300px;"})
- items = items_left + items_right
- ShowTitles = []
- CoverLinks = []
- ShowLinks = []
-
- for index in range (len(items)):
- sub_items = BeautifulSoup(str(items[index]))
-
- title_items = sub_items.findAll('h2')
-
ShowTitles=ShowTitles+re.compile('<h2>(.*)</h2>').findall(str(title_items))
-
- cover_items = sub_items.findAll('img')
- CoverLinks=CoverLinks+re.compile('<img width="150" height="150"
.* src="(.*)" title=".*').findall(str(cover_items))
-
- link_items = sub_items.findAll('a')
- ShowLinks=ShowLinks+re.compile('.*<a href="(.*)"
target="_blank">RSS .*video.*</a>.*').findall(str(link_items))
-
- #print 'debug:::: ShowTitles: '+str(len(ShowTitles))
- #print 'debug:::: CoverLinks: '+str(len(CoverLinks))
- #print 'debug:::: ShowLinks: '+str(len(ShowLinks))
-
- Sorted_ShowTitles = sorted(ShowTitles)
-
- for sort_index in range (len(Sorted_ShowTitles)):
- for index in range (len(ShowTitles)):
- if Sorted_ShowTitles[sort_index] == ShowTitles[index]:
- CoverLink=str(CoverLinks[index])
- CoverLink=CoverLink.replace('-150x150','')
- print 'debug:::: CoverLink: '+str(CoverLink)
-
addDir(ShowTitles[index],ShowLinks[index],1,CoverLink)
-
-
-def addLiveLinks():
- addLink(__language__(30001)+' ','URL',__language__(30001)+'
','',7,xbmc.translatePath( os.path.join( home, 'resources/vaughn.png' ) ))
- addLink(__language__(30002)+'
','http://cgw.ustream.tv/Viewer/getStream/1/3068635.amf',__language__(30002)+'
','',5,xbmc.translatePath( os.path.join( home, 'resources/ustream.png' ) ))
- addLink(__language__(30003)+' ','URL',__language__(30003)+'
','',6,xbmc.translatePath( os.path.join( home, 'resources/justintv.png' ) ))
- addLink(__language__(30004)+'
','http://s25.streamerportal.com:8235/live',__language__(30004)+'
','',4,xbmc.translatePath( os.path.join( home, 'resources',
'resources/live.png' ) ))
-
-def index(url,iconimage):
- headers = {'User-agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0)
Gecko/20100101 Firefox/6.0'}
- req = urllib2.Request(url,None,headers)
+import urllib
+import urllib2
+import re
+import os
+import json
+import time
+from datetime import datetime
+from dateutil.parser import parse
+from traceback import format_exc
+from urlparse import urlparse, parse_qs
+from math import ceil
+
+import StorageServer
+from bs4 import BeautifulSoup
+
+import xbmcplugin
+import xbmcgui
+import xbmcaddon
+
+addon = xbmcaddon.Addon()
+addon_id = addon.getAddonInfo('id')
+addon_version = addon.getAddonInfo('version')
+addon_fanart = addon.getAddonInfo('fanart')
+addon_icon = addon.getAddonInfo('icon')
+addon_path = xbmc.translatePath(addon.getAddonInfo('path')).encode('utf-8')
+language = addon.getLocalizedString
+cache = StorageServer.StorageServer("gfq", 24)
+
+
+def addon_log(string):
+ try:
+ log_message = string.encode('utf-8', 'ignore')
+ except:
+ log_message = 'addonException: addon_log: %s' %format_exc()
+ xbmc.log("[%s-%s]: %s" %(addon_id, addon_version, log_message),
level=xbmc.LOGDEBUG)
+
+
+def cache_shows_file():
+ ''' creates an initial cache from the shows file '''
+ show_file = os.path.join(addon_path, 'resources', 'shows')
+ cache.set("shows", open(show_file, 'r').read())
+
+
+def make_request(url, locate=False):
+ try:
+ req = urllib2.Request(url)
response = urllib2.urlopen(req)
- link=response.read()
+ data = response.read()
response.close()
+ if locate:
+ return response.geturl()
+ 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: %s' %e.reason)
+ if hasattr(e, 'code'):
+ addon_log('We failed with error code - %s.' %e.code)
+
+
+def set_resolved_url(resolved_url):
+ success = False
+ if resolved_url:
+ success = True
+ else:
+ resolved_url = ''
+ item = xbmcgui.ListItem(path=resolved_url)
+ xbmcplugin.setResolvedUrl(int(sys.argv[1]), success, item)
+
+
+def get_justintv():
+ token_url =
'https://api.twitch.tv/api/channels/guysfromqueens/access_token?as3=t'
+ data = json.loads(make_request(token_url))
+ url_params = [
+ 'nauthsig=%s' %data['sig'],
+ 'player=jtvweb',
+ 'private_code=null',
+ 'type=any',
+ 'nauth=%s' %urllib2.quote(data['token']),
+ 'allow_source=true',
+ ]
+ resolved_url = 'http://usher.twitch.tv/select/guysfromqueens.json?' +
'&'.join(url_params)
+ set_resolved_url(resolved_url)
+
+
+def get_dailymotion():
+ # User ID = x14gtas
+ req = urllib2.Request("http://www.dailymotion.com/sequence/x14gtas")
+ response = urllib2.urlopen(req)
+ content = response.read()
+ response.close()
+
+ if content.find('"statusCode":410') > 0 or
content.find('"statusCode":403') > 0:
+ xbmc.executebuiltin('XBMC.Notification(Unable to find live stream.)')
+ else:
+ matchFullHD = re.compile('"hd1080URL":"(.+?)"',
re.DOTALL).findall(content)
+ matchHD = re.compile('"hd720URL":"(.+?)"', re.DOTALL).findall(content)
+ matchHQ = re.compile('"hqURL":"(.+?)"', re.DOTALL).findall(content)
+ matchSD = re.compile('"sdURL":"(.+?)"', re.DOTALL).findall(content)
+ matchLD = re.compile('"video_url":"(.+?)"', re.DOTALL).findall(content)
+ url = ""
+ if matchFullHD:
+ url = urllib.unquote_plus(matchFullHD[0]).replace("\\", "")
+ elif matchHD:
+ url = urllib.unquote_plus(matchHD[0]).replace("\\", "")
+ elif matchHQ:
+ url = urllib.unquote_plus(matchHQ[0]).replace("\\", "")
+ elif matchSD:
+ url = urllib.unquote_plus(matchSD[0]).replace("\\", "")
+ elif matchLD:
+ url = urllib.unquote_plus(matchSD2[0]).replace("\\", "")
+ if url:
+ req = urllib2.Request(url)
+ response = urllib2.urlopen(req)
+ url = response.read()
+ response.close()
+
+ set_resolved_url(url)
+
+
+def add_dir(name, url, iconimage, mode, info={}, VideoStreamInfo={},
AudioStreamInfo={}):
+ item_params = {'name': name, 'url': url, 'mode': mode,
+ 'iconimage': iconimage, 'content_type': content_type}
+ plugin_url = '%s?%s' %(sys.argv[0], urllib.urlencode(item_params))
+ listitem = xbmcgui.ListItem(name, iconImage=iconimage,
thumbnailImage=iconimage)
+ isfolder = True
+ if mode == 'resolve_url' or mode == 'justintv' or mode == 'dailymotion':
+ isfolder = False
+ listitem.setProperty('IsPlayable', 'true')
+ listitem.setProperty('Fanart_Image', addon_fanart)
+ info_type = 'video'
+ if content_type == 'audio':
+ info_type = 'music'
+ listitem.setInfo(type=info_type, infoLabels=info)
+ else:
+ listitem.setInfo(type=info_type, infoLabels=info)
+
+ if hasattr(listitem, 'addStreamInfo'):
+ listitem.addStreamInfo('audio', AudioStreamInfo)
+ listitem.addStreamInfo('video', VideoStreamInfo)
+
+ xbmcplugin.addDirectoryItem(int(sys.argv[1]), plugin_url, listitem,
isfolder)
+
+
+def shows_cache():
+ ''' this function checks for shows that haven't been cached '''
+ soup =
BeautifulSoup(make_request('http://www.gfqnetwork.com/roku/config.opml'),
'html.parser')
+ outlines = soup.findAll('outline')
+
+ show_titles = re.compile('title="(.+?)"').findall(str(outlines))
+ show_icons = re.compile('img="(.+?)"').findall(str(outlines))
+ show_urls = re.compile('url="(.+?)"').findall(str(outlines))
+
+ for index in range(len(show_titles)):
+ if not shows.has_key(show_titles[index]):
+ addon_log('Show not in cache: %s' %show_titles[index])
+ try:
+ shows[show_titles[index]] = {'show_icon': show_icons[index],
'show_url': show_urls[index], 'show_desc': ''}
+ cache.set('shows', repr(shows))
+ addon_log('Cached new show: %s' %show_titles[index])
+ except:
+ addon_log('addonException cache new show: %s' %format_exc)
+ return "True"
+
+
+def display_shows():
+ ''' display the main menu '''
+ # check for new shows at the set cacheFunction interval
+ cache_shows = eval(cache.cacheFunction(shows_cache))
+ add_dir(language(30000), 'gfq_live', addon_icon, 'gfq_live')
+ add_dir(language(30100), 'http://feeds.feedburner.com/GfqNetworkallVideo',
addon_icon, 'latest_episodes')
+ items = sorted(shows.keys(), key=str.lower)
+ for i in items:
+ show = shows[i]
+ add_dir(i, show['show_url'], show['show_icon'], 'episodes', {'plot':
show['show_desc']})
+
+
+def display_live():
+ UstreamVideoStreamInfo = {'codec': 'h264', 'aspect': 1.78, 'width': 426,
'height': 240} #UStream
+ VideoStreamInfo = {'codec': 'h264', 'aspect': 1.78, 'width': 1280,
'height': 720}
+ AudioStreamInfo = {'codec': 'aac', 'language': 'en', 'channels': 2}
+
+ # // Dailymotion
+ add_dir(language(30001), 'get_dailymotion', addon_icon, 'dailymotion',
[],VideoStreamInfo, AudioStreamInfo)
+ # // Ustream
+ add_dir(language(30002),
'http://iphone-streaming.ustream.tv/ustreamVideo/3068635/streams/live/playlist.m3u8',
addon_icon, 'resolve_url', [],UstreamVideoStreamInfo, AudioStreamInfo)
+ # // Justin.tv
+ add_dir(language(30003), 'get_justintv', addon_icon, 'justintv',
[],VideoStreamInfo, AudioStreamInfo)
+ # // Audio Only
+ add_dir(language(30004), 'http://s25.streamerportal.com:8235/live',
addon_icon, 'resolve_url', [],VideoStreamInfo, AudioStreamInfo)
+
+
+def display_episodes(url, iconimage):
+ episodes = get_episodes(url, iconimage)
+ for i in episodes:
+ add_dir(i['info']['Title'], i['url'], i['thumb'], 'resolve_url',
i['info'], i['VideoStreamInfo'], i['AudioStreamInfo'])
+
+
+def get_episodes(url, iconimage):
+ ''' return array of episodes of a specific show '''
+ soup = BeautifulSoup(make_request(url), 'html.parser')
+ soup = soup.prettify().encode('utf-8').strip()
+ soup = BeautifulSoup(soup, 'html.parser')
+
+ # ' // Find All <item> tags (1 Tag per Episode)
+ items = soup.find_all("item")
+
+ episodes = []
+
+ for item in items:
+ try:
+ show_title = str(item.find_next("title").get_text("",
strip=True).encode('utf-8'))
+ except:
+ show_title = ""
+ show_number = re.compile('.* Ep. (.+?) - .*').findall(show_title)
+ if len(show_number) != 1:
+ show_number = re.compile('.* Ep. (.+?) â .*').findall(show_title)
+ if len(show_number) == 1:
+ show_number = int(show_number[0])
+ else:
+ show_number = 0
+ try:
+ show_date = parse(str(item.find_next("pubdate").get_text("",
strip=True).encode('utf-8')), fuzzy=True)
+ except:
+ show_date = ""
+ show_icon = addon_icon
+ try:
+ show_duration = str(item.find_next("itunes:duration").get_text("",
strip=True).encode('utf-8'))
+ except:
+ show_duration = "0:0:0"
+ show_duration = sum(int(x) * 60 ** i for i,x in
enumerate(reversed(show_duration.split(":"))))
+
+ info = {}
+ # ' // Episode Title
+ info['Title'] = show_title
+ info['TVShowTitle'] = show_title
+ info['Genre'] = 'Podcast'
+ # ' // Episode Published Date
+ info['Date'] = show_date.strftime('%d-%m-%Y')
+ info['Premiered'] = show_date.strftime('%d-%m-%Y')
+ info['Aired'] = show_date.strftime('%d-%m-%Y')
+ info['Year'] = show_date.strftime('%Y')
+ # ' // Episode Number
+ info['Episode'] = show_number
+ # ' // Episode Duration
+ info['Duration'] = show_duration / 60
+ # ' // Episode Description
+ try:
+ info['Plot'] = str(item.find_next("itunes:summary").get_text("",
strip=True).encode('utf-8'))
+ except:
+ info['Plot'] = ""
+ try:
+ media_content = re.compile('<media:content filesize="(.+?)"
type="video/mp4"
url="(.+?)">').findall(str(item.find_next("media:content").encode('utf-8')))
+ except:
+ media_content = ""
+ if len(media_content) != 1:
+ try:
+ media_content = re.compile('<media:content blip:acodec="ffaac"
blip:role="Source" blip:vcodec="ffh264" expression="full" filesize="(.+?)"
height="720" isdefault="true" type="video/mp4" url="(.+?)"
width="1280">').findall(str(item.find_next("media:content", attrs={"blip:role":
"Source"}).encode('utf-8')))
+ except:
+ media_content = ""
+ if len(media_content) == 1:
+ media_content = media_content[0]
+ info['Size'] = int(media_content[0])
+ VideoStreamInfo = {'codec': 'h264', 'aspect': 1.78, 'width': 1280,
'height': 720, 'duration': show_duration}
+ AudioStreamInfo = {'codec': 'aac', 'language': 'en', 'channels': 2}
- link=link.replace('&','&')
- link=link.replace('"','"')
- link=link.replace(''',"'")
- link=link.replace('<','<')
- link=link.replace('>','>')
- link=link.replace(' ',' ')
- link=link.replace('­','-')
-
- soup = BeautifulSoup(link)
-
- info = soup.findAll('enclosure')
-
- title = soup.findAll('title')
- del title[0];del title[0]
- name=re.compile('<title>(.+?)</title>').findall(str(title))
-
- description=''
- desc = soup.findAll('itunes:subtitle')
- if len(desc) != 0:
- del desc[0]
-
description=re.compile('<itunes:subtitle>(.+?)</itunes:subtitle>').findall(str(desc))
-
- pubdate = soup.findAll('pubdate')
- del pubdate[0]
- date=re.compile('<pubdate>(.+?)</pubdate>').findall(str(pubdate))
-
- if len(name) != len(date):
- pubdate = soup.findAll('pubdate')
- date=re.compile('<pubdate>(.+?)</pubdate>').findall(str(pubdate))
-
- link = link.replace('>','>\r\n')
-
- soup = BeautifulSoup(link)
- info = soup.findAll('enclosure')
-
- vidurls=re.compile('.*<enclosure.*url="(.+?)".*').findall(str(info))
-
- #print 'debug:::: Name Length: '+str(len(name))
- #print 'debug:::: URL Length: '+str(len(vidurls))
- #print 'debug:::: URL test: '+str(vidurls[0])
- #print 'debug:::: Description Length: '+str(len(description))
- #print 'debug:::: Date Length: '+str(len(date))
-
- for index in range (len(name)):
- if len(name)==len(description):
-
addLink(name[index],vidurls[index],description[index],date[index],4,iconimage)
- else:
- addLink(name[index],vidurls[index],'',date[index],4,iconimage)
-
-
-def getSwf(inURL):
- req = urllib2.Request(inURL)
- response = urllib2.urlopen(req)
- swfUrl = response.geturl()
- return swfUrl
-
-def getUstream(url):
- def getSwf():
- url = 'http://www.ustream.tv/flash/viewer.swf'
- req = urllib2.Request(url)
- response = urllib2.urlopen(req)
- swfUrl = response.geturl()
- return swfUrl
-
+ episodes.append({'url': media_content[1], 'thumb': iconimage,
'info': info, 'VideoStreamInfo': VideoStreamInfo, 'AudioStreamInfo':
AudioStreamInfo})
+ return episodes
- headers = {'User-agent' : 'Mozilla/5.0 (Windows; U; Windows NT 5.1;
en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13'}
- data = None
- req = urllib2.Request(url,data,headers)
- response = urllib2.urlopen(req)
- link=response.read()
- response.close()
- match = re.compile('.*(rtmp://.+?)\x00.*').findall(link)
- rtmp = match[0]
- sName = re.compile('.*streamName\W\W\W(.+?)[/]*\x00.*').findall(link)
- playpath = ' playpath='+sName[0]
- swf = ' swfUrl='+getSwf()
- pageUrl = ' pageUrl=http://www.ustream.tv/gfqlive'
- url = rtmp + playpath + swf + pageUrl + ' swfVfy=1 live=true'
- playLive(url)
-
-def getVaughn():
- rtmpIP = 'live.vaughnlive.tv:443/live'
- #rtmpIP = 'video-viewing-slc-02.vaughnsoft.com:443/live'
- app = 'app=live'
- swfUrl =
'swfUrl=http://vaughnlive.tv/swf/live_vaughnlive_player_v3.swf?channel=gfqnetwork'
- tcUrl = 'rtmp://' + rtmpIP
- pageUrl = 'pageUrl=http://vaughnlive.tv/gfqnetwork'
- Playpath = 'Playpath=live_gfqnetwork'
- live = 'live=true'
-
- url = tcUrl + ' ' + swfUrl + ' ' + app + ' ' + Playpath + ' ' +
pageUrl + ' ' + live
-
- item = xbmcgui.ListItem(path=url)
- xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, item)
-
-def getJtv():
- headers = {'User-agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0)
Gecko/20100101 Firefox/6.0',
- 'Referer' : 'http://www.justin.tv/guysfromqueens'}
- req =
urllib2.Request('http://usher.justin.tv/find/guysfromqueens.xml?type=live',None,headers)
- response = urllib2.urlopen(req)
- link=response.read()
- response.close()
- soup = BeautifulSoup(link)
- token = ' jtv='+soup.token.string.replace('\\','\\5c').replace('
','\\20').replace('"','\\22')
- rtmp = soup.connect.string+'/'+soup.play.string
- Pageurl = ' Pageurl=http://www.justin.tv/guysfromqueens'
- swf = '
swfUrl=http://www.justin.tv/widgets/live_embed_player.swf?channel=guysfromqueens'
- url = rtmp+token+swf+Pageurl
- item = xbmcgui.ListItem(path=url)
- xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, item)
+def cache_latest_episods(url, iconimage):
+ episodes = get_episodes(url, iconimage)
+ return episodes
-def playLive(url):
- item = xbmcgui.ListItem(path=url)
- xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, item)
+def get_latest_episodes(url, iconimage):
+ episodes = cache.cacheFunction(cache_latest_episods, url, iconimage)
+ for i in episodes:
+ add_dir(i['info']['Title'], i['url'], i['thumb'], 'resolve_url',
i['info'], i['VideoStreamInfo'], i['AudioStreamInfo'])
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):
- ok=True
-
- try:
- if date != '':
- description = description + "\n \n Published: " + date
- except:
- if date != '':
- description = "Published: " + date
+ p = parse_qs(sys.argv[2][1:])
+ for i in p.keys():
+ p[i] = p[i][0]
+ return p
-
u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&iconimage="+urllib.quote_plus(iconimage)
- liz=xbmcgui.ListItem(name, iconImage="DefaultVideo.png",
thumbnailImage=iconimage)
- liz.setInfo(type="Video",
infoLabels={"Title":name,"Plot":description,"Date": date})
- liz.setProperty( "Fanart_Image", fanart )
- liz.setProperty('IsPlayable', 'true')
-
ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz)
+first_run = addon.getSetting('first_run')
+if first_run != addon_version:
+ cache_shows_file()
+ addon_log('first_run, caching shows file')
+ xbmc.sleep(1000)
+ addon.setSetting('first_run', addon_version)
- return ok
+params = get_params()
+if params.has_key('content_type') and params['content_type'] == 'audio':
+ content_type = 'audio'
+else:
+ content_type = 'video'
-def addDir(name,url,mode,iconimage):
- ok=True
-
u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&iconimage="+urllib.quote_plus(iconimage)
- liz=xbmcgui.ListItem(name, iconImage="DefaultFolder.png",
thumbnailImage=iconimage)
- liz.setInfo( type="Video", infoLabels={ "Title": name } )
- liz.setProperty( "Fanart_Image", fanart )
-
ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=True)
-
- return ok
-
-
-params=get_params()
-url=None
-name=None
-mode=None
-
+mode = None
try:
- url=urllib.unquote_plus(params["url"])
+ mode = params['mode']
+ addon_log('Mode: %s, Name: %s, URL: %s'
+ %(params['mode'], params['name'], 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
-
-#print "Mode: "+str(mode)
-#print "URL: "+str(url)
-#print "Name: "+str(name)
-
-if mode==None or url==None or len(url)<1:
- print ""
- categories()
-
-elif mode==1:
- print ""
- index(url,iconimage)
-
-elif mode==2:
- print ""
- getVideo(url)
-
-elif mode==3:
- print ""
- addLiveLinks()
-
-elif mode==4:
- print ""
- playLive(url)
-
-elif mode==5:
- print ""
- getUstream(url)
-
-elif mode==6:
- print ""
- getJtv()
-
-elif mode==7:
- print ""
- getVaughn()
-
-xbmcplugin.endOfDirectory(int(sys.argv[1]))
\ No newline at end of file
+ addon_log('Get root directory')
+
+if mode is None:
+ try:
+ shows = eval(cache.get('shows'))
+ if isinstance(shows, dict):
+ display_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):
+ display_shows()
+ else:
+ addon_log('"shows" cache ERROR')
+ xbmcplugin.setContent(int(sys.argv[1]), 'tvshows')
+ xbmcplugin.endOfDirectory(int(sys.argv[1]))
+elif mode == 'episodes':
+ display_episodes(params['url'], params['iconimage'])
+ xbmcplugin.setContent(int(sys.argv[1]), 'episodes')
+ xbmcplugin.endOfDirectory(int(sys.argv[1]))
+
+elif mode == 'latest_episodes':
+ get_latest_episodes(params['url'], addon_icon)
+ xbmcplugin.setContent(int(sys.argv[1]), 'episodes')
+ xbmcplugin.endOfDirectory(int(sys.argv[1]))
+
+elif mode == 'resolve_url':
+ set_resolved_url(params['url'])
+
+elif mode == 'gfq_live':
+ display_live()
+ xbmcplugin.setContent(int(sys.argv[1]), 'episodes')
+ xbmcplugin.endOfDirectory(int(sys.argv[1]))
+
+elif mode == 'dailymotion':
+ get_dailymotion()
+
+elif mode == 'justintv':
+ get_justintv()
\ No newline at end of file
diff --git a/plugin.video.gfq/fanart.jpg b/plugin.video.gfq/fanart.jpg
index 0eb35d4..0991344 100644
Binary files a/plugin.video.gfq/fanart.jpg and b/plugin.video.gfq/fanart.jpg
differ
diff --git a/plugin.video.gfq/icon.png b/plugin.video.gfq/icon.png
index c19d4e2..1a92b0a 100644
Binary files a/plugin.video.gfq/icon.png and b/plugin.video.gfq/icon.png differ
diff --git a/plugin.video.gfq/resources/language/English/strings.xml
b/plugin.video.gfq/resources/language/English/strings.xml
index b593675..a5cd538 100644
--- a/plugin.video.gfq/resources/language/English/strings.xml
+++ b/plugin.video.gfq/resources/language/English/strings.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<strings>
<string id='30000'>GFQ Live Streams</string>
- <string id='30001'>GFQ Live - Vaughn (1.2 MB/s)</string>
- <string id='30002'>GFQ Live - UStream (980 KB/s)</string>
- <string id='30003'>GFQ Live - Justin.TV (1.2 MB/s)</string>
- <string id='30004'>GFQ Live - Audio Only (64 KB/s)</string>
+ <string id='30001'>GFQ Live - Dailymotion</string>
+ <string id='30002'>GFQ Live - Ustream</string>
+ <string id='30003'>GFQ Live - Justin.tv</string>
+ <string id='30004'>GFQ Live - Audio Only</string>
<string id='30100'>Latest Episodes</string>
</strings>
\ No newline at end of file
-----------------------------------------------------------------------
Summary of changes:
plugin.video.gfq/addon.xml | 26 +-
plugin.video.gfq/changelog.txt | 17 +-
plugin.video.gfq/dateutil/__init__.py | 9 +
plugin.video.gfq/dateutil/easter.py | 92 ++
plugin.video.gfq/dateutil/parser.py | 886 ++++++++++++++++
plugin.video.gfq/dateutil/relativedelta.py | 432 ++++++++
plugin.video.gfq/dateutil/rrule.py | 1097 ++++++++++++++++++++
plugin.video.gfq/dateutil/tz.py | 951 +++++++++++++++++
plugin.video.gfq/dateutil/tzwin.py | 180 ++++
plugin.video.gfq/dateutil/zoneinfo/__init__.py | 87 ++
plugin.video.gfq/default.py | 630 ++++++------
plugin.video.gfq/fanart.jpg | Bin 758935 -> 328616
bytes
plugin.video.gfq/icon.png | Bin 51198 -> 19818 bytes
plugin.video.gfq/resources/justintv.png | Bin 8145 -> 0 bytes
.../resources/language/English/strings.xml | 8 +-
plugin.video.gfq/resources/live.png | Bin 17905 -> 0 bytes
plugin.video.gfq/resources/settings.xml | 6 +
plugin.video.gfq/resources/shows | 1 +
plugin.video.gfq/resources/ustream.png | Bin 7844 -> 0 bytes
plugin.video.gfq/resources/vaughn.png | Bin 15381 -> 0 bytes
20 files changed, 4111 insertions(+), 311 deletions(-)
create mode 100644 plugin.video.gfq/dateutil/__init__.py
create mode 100644 plugin.video.gfq/dateutil/easter.py
create mode 100644 plugin.video.gfq/dateutil/parser.py
create mode 100644 plugin.video.gfq/dateutil/relativedelta.py
create mode 100644 plugin.video.gfq/dateutil/rrule.py
create mode 100644 plugin.video.gfq/dateutil/tz.py
create mode 100644 plugin.video.gfq/dateutil/tzwin.py
create mode 100644 plugin.video.gfq/dateutil/zoneinfo/__init__.py
delete mode 100644 plugin.video.gfq/resources/justintv.png
delete mode 100644 plugin.video.gfq/resources/live.png
create mode 100644 plugin.video.gfq/resources/settings.xml
create mode 100644 plugin.video.gfq/resources/shows
delete mode 100644 plugin.video.gfq/resources/ustream.png
delete mode 100644 plugin.video.gfq/resources/vaughn.png
hooks/post-receive
--
Plugins
------------------------------------------------------------------------------
_______________________________________________
Xbmc-addons mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xbmc-addons