The branch, frodo has been updated
       via  0859b6c751a634f06524114b21eae9c9ec7f6a15 (commit)
       via  923ff507934be2129acce2eca9947e63046cb235 (commit)
      from  c24502345a96fe14c0df04bc7bc69501bf3fe32e (commit)

- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=0859b6c751a634f06524114b21eae9c9ec7f6a15

commit 0859b6c751a634f06524114b21eae9c9ec7f6a15
Author: beenje <[email protected]>
Date:   Wed Apr 3 22:02:04 2013 +0200

    [plugin.video.twitch] updated to version 0.2.6

diff --git a/plugin.video.twitch/addon.xml b/plugin.video.twitch/addon.xml
index 17f304a..cf018bb 100644
--- a/plugin.video.twitch/addon.xml
+++ b/plugin.video.twitch/addon.xml
@@ -1,8 +1,9 @@
 <?xml version='1.0' encoding='UTF-8' standalone='yes'?>
-<addon id='plugin.video.twitch' version='0.2.2' name='TwitchTV' 
provider-name='StateOfTheArt'>
+<addon id='plugin.video.twitch' version='0.2.6' name='TwitchTV' 
provider-name='StateOfTheArt'>
   <requires>
-    <import addon='xbmc.python' version='2.0'/>
+    <import addon='xbmc.python' version='2.1.0'/>
     <import addon='script.module.simplejson' version='2.0.10'/>
+    <import addon="script.module.xbmcswift2" version="1.2.0"/>
   </requires>
   <extension point='xbmc.python.pluginsource' library='default.py'>
         <provides>video</provides>
@@ -10,9 +11,13 @@
   <extension point='xbmc.addon.metadata'>
     <platform>all</platform>
     <language>en</language>
+    <source>https://github.com/StateOfTheArt89/Twitch.tv-on-XBMC</source>
+    <license>GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007</license>
     <summary lang='de'>TwitchTV video plugin</summary>
     <description lang='de'>Schaue die besten Gaming-Streams auf 
XBMC!</description>
     <summary lang='en'>TwitchTV video plugin</summary>
     <description lang='en'>Watch your favorite gaming streams on 
XBMC!</description>
+    <summary lang='pl'>TwitchTV video plugin</summary>
+    <description lang='pl'>Oglądaj ulubione programy TwitchTV na 
XBMC!</description>
   </extension>
 </addon>
diff --git a/plugin.video.twitch/changelog.txt 
b/plugin.video.twitch/changelog.txt
index e383461..315b815 100644
--- a/plugin.video.twitch/changelog.txt
+++ b/plugin.video.twitch/changelog.txt
@@ -23,4 +23,18 @@
 0.2.1
 - added featured streams section
 0.2.2
-- added teams section - thx to kokarn
\ No newline at end of file
+- added teams section - thx to kokarn
+0.2.3
+- code refactor
+- integration of xbmcswift2
+0.2.4
+- fixed bug in following section
+- fixed bug in function getBestJtvTokenPossible
+0.2.5
+- serveral fixes and new features thx to grocal
+- fixed 'status' in favorite json data might be null
+- new translation: Polish
+- changed getting live favorite channels from on single .json query 
(user/favorite with live=true variable set)
+- channel listing in format "[channel_name] channel_status_text"
+0.2.6
+- bug fix: crashes or wrong error messages, when opening streams
\ No newline at end of file
diff --git a/plugin.video.twitch/default.py b/plugin.video.twitch/default.py
index d726d05..506021f 100644
--- a/plugin.video.twitch/default.py
+++ b/plugin.video.twitch/default.py
@@ -1,355 +1,324 @@
-import xbmcplugin

-import xbmcgui

-import sys

-import urllib2,urllib,re

-import xbmcaddon

-import os

-import xbmcvfs

-import socket

-try:

-    import json

-except:

-    import simplejson as json

-

-thisPlugin = int(sys.argv[1])

-settings = xbmcaddon.Addon(id='plugin.video.twitch')

-httpHeaderUserAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) 
Gecko/20100101 Firefox/6.0'

-translation = settings.getLocalizedString

-ITEMS_PER_SITE=20

-

-def downloadWebData(url):

-    try:

-        req = urllib2.Request(url)

-        req.add_header('User-Agent', httpHeaderUserAgent)

-        response = urllib2.urlopen(req)

-        data=response.read()

-        response.close()

-        return data

-    except urllib2.HTTPError, e:

-        # HTTP errors usualy contain error information in JSON Format

-        return e.fp.read()

-    except urllib2.URLError, e:

-        xbmc.executebuiltin("XBMC.Notification("+translation(32001)+"," + 
translation(32010) +")")

-

-def getJsonFromTwitchApi(url):

-    jsonString=downloadWebData(url)

-    if jsonString is None:

-        return None

-    try:

-        jsonData=json.loads(jsonString)

-    except:

-        
xbmc.executebuiltin('XBMC.Notification("'+translation(32008)+'","'+translation(32008)+'")')

-        return None

-    if type(jsonData) is dict and 'error' in jsonData.keys():

-        
xbmc.executebuiltin('XBMC.Notification("'+translation(32007)+'","'+jsonData['error']+'")')

-        return None

-    return jsonData

-       

-def createMainListing():

-    addDir(translation(30005),'','featured','')

-    addDir(translation(30001),'','games','')

-    addDir(translation(30002),'','following','')

-    addDir(translation(30006),'','teams','')

-    addDir(translation(30003),'','search','')

-    addDir(translation(30004),'','settings','')

-    xbmcplugin.endOfDirectory(thisPlugin)

-

-def createFollowingList():

-    username = settings.getSetting('username').lower()

-    if not username:

-        settings.openSettings()

-        username = settings.getSetting('username').lower()

-    #Using xml in this case, because it's alot faster than parsing throw the 
big json result

-    xmlDataOnlineStreams = 
downloadWebData(url='http://api.justin.tv/api/stream/list.xml')

-    jsonData = 
getJsonFromTwitchApi(url='http://api.justin.tv/api/user/favorites/'+username+'.json')

-    if jsonData is None:

-        return

-    for x in jsonData:

-        name = x['status']

-        image = x['image_url_huge']

-        loginname = x['login']

-        if len(name) <= 0:

-            name = loginname

-        if xmlDataOnlineStreams.count('<login>'+loginname+'</login>') > 0:

-            addLink(name,loginname,'play',image,loginname)

-    xbmcplugin.endOfDirectory(thisPlugin)

-       

-def createListOfFeaturedStreams():

-    jsonData = 
getJsonFromTwitchApi(url='https://api.twitch.tv/kraken/streams/featured')

-    if jsonData is None:

-        return

-    for x in jsonData['featured']:

-        try:

-            image = x['stream']['channel']['logo']

-            image = image.replace("http://","",1)

-            image = urllib.quote(image)

-            image = 'http://' + image

-        except:

-            image = ""

-        name = x['stream']['channel']['status']

-        if name == '':

-            name = x['stream']['channel']['display_name']

-        channelname = x['stream']['channel']['name']

-        addLink(name,'...','play',image,channelname)

-    xbmcplugin.endOfDirectory(thisPlugin)

-

-def createListOfTeams():

-    #Temporary solution until twitch api method is available

-    
jsonString=downloadWebData(url='https://spreadsheets.google.com/feeds/list/0ArmMFLQnLIp8dFJ5bW9aOW03VHY5aUhsUFNXSUl1SXc/od6/public/basic?alt=json')

-    if jsonString is None:

-        return

-    try:

-        jsonData=json.loads(jsonString)

-    except:

-        
xbmc.executebuiltin('XBMC.Notification("'+translation(32008)+'","'+translation(32008)+'")')

-        return

-    for x in jsonData['feed']['entry']:

-        teamData = x['content']['$t'].split(',')

-        try:

-            image = teamData[1][7:]

-            image = image.replace("http://","",1)

-            image = urllib.quote(image)

-            image = 'http://' + image

-        except:

-            image = ""

-        name = x['title']['$t']

-        channelname = teamData[0][7:]

-        addDir(name,channelname,'team',image,)

-    xbmcplugin.endOfDirectory(thisPlugin)

-

-def createListOfTeamStreams(team=''):

-    jsonData = 
getJsonFromTwitchApi(url='http://api.twitch.tv/api/team/'+team+'/live_channels.json')

-    if jsonData is None:

-        return

-    for x in jsonData['channels']:

-        try:

-            image = x['channel']['image']['size600']

-            image = image.replace("http://","",1)

-            image = urllib.quote(image)

-            image = 'http://' + image

-        except:

-            image = ""

-        if x['channel']['title'] is None:

-            name = x['channel']['display_name']

-        else:

-            name = x['channel']['display_name']+' - '+x['channel']['title']

-        channelname = x['channel']['name']

-        addLink(name,'...','play',image,channelname)

-    xbmcplugin.endOfDirectory(thisPlugin)

- 

-def createListOfGames(index=0):

-    jsonData = 
getJsonFromTwitchApi(url='https://api.twitch.tv/kraken/games/top?limit='+str(ITEMS_PER_SITE)+'&offset='+str(index*ITEMS_PER_SITE))

-    if jsonData is None:

-        return

-    for x in jsonData['top']:

-        try:

-            name = str(x['game']['name'])

-            game = urllib.quote(name)

-            image = ''

-        except:

-            continue

-        try:

-            image = x['game']['images']['super']

-            image = image.replace("http://","",1)

-            image = urllib.quote(image)

-            image = 'http://' + image

-        except:

-            image = ''

-        addDir(name,game,'channel',image)

-    if len(jsonData['top']) >= ITEMS_PER_SITE:

-        addDir(translation(31001),'','games','',index+1)

-    xbmcplugin.endOfDirectory(thisPlugin)

-

-def search():

-    keyboard = xbmc.Keyboard('', translation(30101))

-    keyboard.doModal()

-    if keyboard.isConfirmed() and keyboard.getText():

-        search_string = urllib.quote_plus(keyboard.getText())

-        sdata = 
downloadWebData('http://api.swiftype.com/api/v1/public/engines/search.json?callback=jQuery1337&q='+search_string+'&engine_key=9NXQEpmQPwBEz43TM592&page=1&per_page='+str(ITEMS_PER_SITE))

-        sdata = sdata.replace('jQuery1337','');

-        sdata = sdata[1:len(sdata)-1]

-        jdata = json.loads(sdata)

-        records = jdata['records']['broadcasts']

-        for x in records:

-            addLink(x['title'],x['user'],'play',x['thumbnail'],x['user'])

-        xbmcplugin.endOfDirectory(thisPlugin)

-

-       

-def createListForGame(gameName, index=0):

-    
jsonString=downloadWebData(url='https://api.twitch.tv/kraken/streams?game='+gameName+'&limit='+str(ITEMS_PER_SITE)+'&offset='+str(index*ITEMS_PER_SITE))

-    if jsonString is None:

-        return

-    jsonData=json.loads(jsonString)

-    try:

-        jsonData=json.loads(jsonString)

-    except:

-        
xbmc.executebuiltin('XBMC.Notification("'+translation(32008)+'","'+translation(32008)+'")')

-        return

-    for x in jsonData['streams']:

-        try:

-            image = x['channel']['logo']

-            image = image.replace("http://","",1)

-            image = urllib.quote(image)

-            image = 'http://' + image

-        except:

-            image = ""

-        name = x['channel']['status']

-        if name == '':

-            name = x['channel']['display_name']

-        channelname = x['channel']['name']

-        addLink(name,'...','play',image,channelname)

-    if len(jsonData['streams']) >= ITEMS_PER_SITE:

-        addDir(translation(31001),url,'channel','',index+1)

-    xbmcplugin.endOfDirectory(thisPlugin)

-       

-def addLink(name,url,mode,iconimage,channelname):

-        
u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&channelname="+channelname

-        ok=True

-        liz=xbmcgui.ListItem(name, iconImage="DefaultVideo.png", 
thumbnailImage=iconimage)

-        liz.setInfo( type="Video", infoLabels={ "Title": name } )

-        liz.setProperty('IsPlayable', 'true')

-        
ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz)

-        return ok

-               

-def addDir(name,url,mode,iconimage,index=0):

-        
u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&siteIndex="+str(index)

-        ok=True

-        liz=xbmcgui.ListItem(name, iconImage="DefaultFolder.png", 
thumbnailImage=iconimage)

-        liz.setInfo( type="Video", infoLabels={ "Title": name } )

-        
ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=True)

-        return ok

-               

-def get_request(url, headers=None):

-        try:

-            if headers is None:

-                headers = {'User-agent' : httpHeaderUserAgent,

-                           'Referer' : 'http://www.twitch.tv/'}

-            req = urllib2.Request(url,None,headers)

-            response = urllib2.urlopen(req)

-            link=response.read()

-            response.close()

-            return link

-        except urllib2.URLError, e:

-            errorStr = str(e.read())

-            if hasattr(e, 'code'):

-                if str(e.code) == '403':

-                    if 'archive' in url:

-                        
xbmc.executebuiltin("XBMC.Notification("+translation(31000)+"," 
+translation(32003)+ " " +name+")")

-                
xbmc.executebuiltin("XBMC.Notification("+translation(31000)+"," + 
translation(32001) +")")

-

-       

-def parameters_string_to_dict(parameters):

-        # Convert parameters encoded in a URL to a dict.

-        paramDict = {}

-        if parameters:

-            paramPairs = parameters[1:].split("&")

-            for paramsPair in paramPairs:

-                paramSplits = paramsPair.split('=')

-                if (len(paramSplits)) == 2:

-                    paramDict[paramSplits[0]] = paramSplits[1]

-        return paramDict

-               

-def getSwfUrl(channel_name):

-        # Helper method to grab the swf url, resolving HTTP 301/302 along the 
way

-        base_url = 
'http://www.justin.tv/widgets/live_embed_player.swf?channel=%s' % channel_name

-        headers = {'User-agent' : httpHeaderUserAgent,

-                   'Referer' : 'http://www.justin.tv/'+channel_name}

-        req = urllib2.Request(base_url, None, headers)

-        response = urllib2.urlopen(req)

-        return response.geturl()

-               

-def getBestJtvTokenPossible(name):

-        # Helper method to find another jtv token

-        swf_url = getSwfUrl(name)

-        headers = {'User-agent' : httpHeaderUserAgent,

-                   'Referer' : swf_url}

-        url = 'http://usher.justin.tv/find/'+name+'.json?type=any&group='

-        data = json.loads(get_request(url,headers))

-        bestVideoHeight = -1

-        bestIndex = 0

-        index = 0

-        for x in data:

-            value = x.get('token', '')

-            videoHeight = int(x['video_height'])

-            if (value != '') and (videoHeight > bestVideoHeight):

-                bestVideoHeight = x['video_height']

-                bestIndex = index  

-            index = index + 1

-        return data[bestIndex]

-

-def playLive(name, play=False, password=None):

-        swf_url = getSwfUrl(name)

-        headers = {'User-agent' : httpHeaderUserAgent,

-                   'Referer' : swf_url}

-        chosenQuality = settings.getSetting('video')

-        videoTypeName = 'any'

-        if chosenQuality == '0':

-            videoTypeName = 'any'

-        elif chosenQuality == '1':

-            videoTypeName = '720p'

-        elif chosenQuality == '2':

-            videoTypeName = '480p'

-        elif chosenQuality == '3':

-            videoTypeName = '360p'

-        url = 
'http://usher.justin.tv/find/'+name+'.json?type='+videoTypeName+'&private_code=null&group='

-        data = json.loads(get_request(url,headers))

-        tokenIndex = 0

-

-        try:

-            # trying to get a token in desired quality

-            token = ' 
jtv='+data[tokenIndex]['token'].replace('\\','\\5c').replace(' 
','\\20').replace('"','\\22')

-            rtmp = data[tokenIndex]['connect']+'/'+data[tokenIndex]['play']

-        except:

-            
xbmc.executebuiltin("XBMC.Notification("+translation(32005)+","+translation(32006)+")")

-            jtvtoken = getBestJtvTokenPossible(name)

-            if jtvtoken == '':

-                
xbmc.executebuiltin("XBMC.Notification("+translation(31000)+","+translation(32004)+")")

-                return

-            token = ' jtv='+jtvtoken['token'].replace('\\','\\5c').replace(' 
','\\20').replace('"','\\22')

-            rtmp = jtvtoken['connect']+'/'+jtvtoken['play']

-        

-        swf = ' swfUrl=%s swfVfy=1 live=1' % swf_url

-        Pageurl = ' Pageurl=http://www.justin.tv/'+name

-        url = rtmp+token+swf+Pageurl

-        if play == True:

-            info = xbmcgui.ListItem(name)

-            playlist = xbmc.PlayList(1)

-            playlist.clear()

-            playlist.add(url, info)

-            xbmc.executebuiltin('playlist.playoffset(video,0)')

-        else:

-            item = xbmcgui.ListItem(path=url)

-            xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, item)

-

-params=parameters_string_to_dict(sys.argv[2])

-mode=params.get('mode')

-url=params.get('url')

-sIndex=params.get('siteIndex')

-try:

-    index = int(sIndex)

-except:

-    index = 0

-channelname=params.get('channelname')

-if type(url)==type(str()):

-       url=urllib.unquote_plus(url)

-if mode == 'games':

-       createListOfGames(index)  

-elif mode == 'featured':

-       createListOfFeaturedStreams()

-elif mode == 'channel':

-       createListForGame(url, index)

-elif mode == 'play':

-       playLive(channelname)

-elif mode == 'following':

-       createFollowingList()

-elif mode == 'teams':

-        createListOfTeams()

-elif mode == 'team':

-        createListOfTeamStreams(url)

-elif mode == 'settings':

-       settings.openSettings()

-elif mode == 'search':

-       search()

-else:

-       createMainListing()

-

+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+import xbmcplugin
+import xbmcgui
+import sys
+import urllib2
+import urllib
+import re
+import xbmcaddon
+import os
+import socket
+try:
+    import json
+except:
+    import simplejson as json
+from xbmcswift2 import Plugin
+
+settings = xbmcaddon.Addon(id='plugin.video.twitch')
+httpHeaderUserAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) 
Gecko/20100101 Firefox/6.0'
+translation = settings.getLocalizedString
+ITEMS_PER_SITE = 20
+plugin = Plugin()
+
+
+def downloadWebData(url):
+    try:
+        req = urllib2.Request(url)
+        req.add_header('User-Agent', httpHeaderUserAgent)
+        response = urllib2.urlopen(req)
+        data = response.read()
+        response.close()
+        return data
+    except urllib2.HTTPError, e:
+        # HTTP errors usualy contain error information in JSON Format
+        return e.fp.read()
+    except urllib2.URLError, e:
+        showNotification(translation(32001), translation(32010))
+
+def showNotification(caption, text):
+     xbmc.executebuiltin("XBMC.Notification(" + caption + "," + text + ")")
+
+
+def getJsonFromTwitchApi(url):
+    jsonString = downloadWebData(url)
+    if jsonString is None:
+        return None
+    try:
+        jsonData = json.loads(jsonString)
+    except:
+        showNotification(translation(32008), translation(32008))
+        return None
+    if type(jsonData) is dict and 'error' in jsonData.keys():
+        showNotification(translation(32007),jsonData['error'])
+        return None
+    return jsonData
+
+def getTitle(streamer, title, viewers):
+        titleDisplay = settings.getSetting('titledisplay')
+        if streamer is None:
+            streamer = '-'
+        if title is None:
+            title = 'no title'
+        if viewers is None:
+            viewers = '0'    
+
+        streamTitle = streamer + ' - ' + title
+        if titleDisplay == '0':
+            #Streamer - Stream Title
+            streamTitle = streamer + ' - ' + title
+        elif titleDisplay == '1':
+            #Viewers - Streamer - Stream Title
+            streamTitle = str(viewers) + ' - ' + streamer + ' - ' + title
+        elif titleDisplay == '2':
+            #Stream Title
+            streamTitle = title
+        elif titleDisplay == '3':
+            #Streamer
+            streamTitle = streamer
+        return streamTitle
+
+
[email protected]('/')
+def createMainListing():
+    items = [
+        {'label': translation(30005), 'path': plugin.url_for(
+            endpoint='createListOfFeaturedStreams'
+        )},
+        {'label': translation(30001), 'path': plugin.url_for(
+            endpoint='createListOfGames', sindex='0'
+        )},
+        {'label': translation(30002), 'path': plugin.url_for(
+            endpoint='createFollowingList'
+        )},
+        {'label': translation(30006), 'path': plugin.url_for(
+            endpoint='createListOfTeams', sindex='0'
+        )},
+        {'label': translation(30003), 'path': plugin.url_for(
+            endpoint='search'
+        )},
+        {'label': translation(30004), 'path': plugin.url_for(
+            endpoint='showSettings'
+        )}
+    ]
+    return items
+
[email protected]('/createListOfFeaturedStreams/')
+def createListOfFeaturedStreams():
+    items = []
+    jsonData = getJsonFromTwitchApi(
+        url='https://api.twitch.tv/kraken/streams/featured')
+    if jsonData is None:
+        return
+    for x in jsonData['featured']:
+        try:
+            streamData = x['stream']
+            channelData = x['stream']['channel']
+            loginname = channelData['name']
+            title = getTitle(streamer=channelData.get('name'), 
title=channelData.get('status'), viewers=streamData.get('viewers'))
+            items.append({'label': title, 'path': 
plugin.url_for(endpoint='playLive', name=loginname),
+             'is_playable': True, 'icon' : channelData['logo']})
+        except:
+            pass
+    return items
+
+
[email protected]('/createListOfGames/<sindex>/')
+def createListOfGames(sindex):
+    index = int(sindex)
+    items = []
+    jsonData = 
getJsonFromTwitchApi(url='https://api.twitch.tv/kraken/games/top?limit=' + 
str(ITEMS_PER_SITE) + '&offset=' + str(index * ITEMS_PER_SITE))
+    if jsonData is None:
+        return
+    for x in jsonData['top']:
+        try:
+            name = str(x['game']['name'])
+        except:
+            continue
+        try:
+            image = x['game']['images']['super']
+        except:
+            image = ''
+        items.append({'label': name, 'path': plugin.url_for(
+            'createListForGame', gameName=name, sindex='0'), 'icon' : image})
+    if len(jsonData['top']) >= ITEMS_PER_SITE:
+        items.append({'label': translation(31001), 'path': 
plugin.url_for('createListOfGames', sindex=str(index + 1))})
+    return items
+
+
[email protected]('/createListForGame/<gameName>/<sindex>/')
+def createListForGame(gameName, sindex):
+    index = int(sindex)
+    items = []
+    jsonData = 
getJsonFromTwitchApi(url='https://api.twitch.tv/kraken/streams?game=' + 
urllib.quote_plus(gameName) + '&limit=' + str(ITEMS_PER_SITE) + '&offset=' + 
str(index * ITEMS_PER_SITE))
+    if jsonData is None:
+        return
+    for x in jsonData['streams']:
+        channelData = x['channel']
+        try:
+            image = channelData['logo']
+        except:
+            image = ""
+        title = getTitle(streamer=channelData.get('name'), 
title=channelData.get('status'), viewers=x.get('viewers'))
+        items.append({'label': title, 'path': 
plugin.url_for(endpoint='playLive', name=channelData['name']),
+                    'is_playable' : True, 'icon' : image})
+    if len(jsonData['streams']) >= ITEMS_PER_SITE:
+        items.append({'label': translation(31001), 'path': plugin.url_for(
+            'createListForGame', gameName=gameName, sindex=str(index + 1))})
+    return items
+
+
[email protected]('/createFollowingList/')
+def createFollowingList():
+    items = []
+    username = settings.getSetting('username').lower()
+    if not username:
+        settings.openSettings()
+        username = settings.getSetting('username').lower()
+    jsonData = getJsonFromTwitchApi('http://api.justin.tv/api/user/favorites/' 
+ username + '.json?limit=100&offset=0&live=true')
+    if jsonData is None:
+        return
+    for x in jsonData:
+        loginname = x['login']
+        image = x['image_url_huge']
+        title = getTitle(streamer=x.get('login'), title=x.get('status'), 
viewers=x.get('views_count'))
+        items.append({'label': title , 'path': 
plugin.url_for(endpoint='playLive', name=loginname), 'icon' : image, 
'is_playable' : True})
+    return items    
+
[email protected]('/createListOfTeams/')
+def createListOfTeams():
+    items = []
+    jsonData = getJsonFromTwitchApi('https://api.twitch.tv/kraken/teams/')
+    if jsonData is None:
+        return
+    for x in jsonData['teams']:
+        try:
+            image = x['logo']
+        except:
+            image = ""
+        name = x['name']
+        items.append({'label': name, 'path': 
plugin.url_for(endpoint='createListOfTeamStreams', team=name), 'icon' : image})
+    return items
+
+
[email protected]('/createListOfTeamStreams/<team>/')
+def createListOfTeamStreams(team):
+    items = []      
+    jsonData = getJsonFromTwitchApi(url='http://api.twitch.tv/api/team/' + 
urllib.quote_plus(team) + '/live_channels.json')
+    if jsonData is None:
+        return
+    for x in jsonData['channels']:
+        try:
+            image = x['channel']['image']['size600']
+        except:
+            image = ""
+        try:
+            channelData = x['channel']
+            title = getTitle(streamer=channelData.get('display_name'), 
title=channelData.get('title'), viewers=channelData.get('current_viewers'))
+            channelname = x['channel']['name']
+            items.append({'label': title, 'path': 
plugin.url_for(endpoint='playLive', name=channelname), 'is_playable' : True, 
'icon' : image})
+        except:
+            # malformed data element
+            pass
+    return items
+
+
[email protected]('/search/')
+def search():
+    items = []
+    keyboard = xbmc.Keyboard('', translation(30101))
+    keyboard.doModal()
+    if keyboard.isConfirmed() and keyboard.getText():
+        search_string = urllib.quote_plus(keyboard.getText())
+        sdata = 
downloadWebData('http://api.swiftype.com/api/v1/public/engines/search.json?callback=jQuery1337&q='
 + search_string + '&engine_key=9NXQEpmQPwBEz43TM592&page=1&per_page=' + 
str(ITEMS_PER_SITE))
+        sdata = sdata.replace('jQuery1337', '')
+        sdata = sdata[1:len(sdata) - 1]
+        jdata = json.loads(sdata)
+        records = jdata['records']['broadcasts']
+        for x in records:
+            items.append({'label': x['title'], 'path': plugin.url_for(
+                endpoint='playLive', name=x['user']
+            ), 'is_playable' : True})
+        return items
+
[email protected]('/showSettings/')
+def showSettings():
+    #there is probably a better way to do this
+    settings.openSettings()
+
+
+def getSwfUrl(channel_name):
+    # Helper method to grab the swf url
+    base_url = 'http://www.justin.tv/widgets/live_embed_player.swf?channel=%s' 
% channel_name
+    headers = {'User-agent': httpHeaderUserAgent,
+               'Referer': 'http://www.justin.tv/' + channel_name}
+    req = urllib2.Request(base_url, None, headers)
+    response = urllib2.urlopen(req)
+    return response.geturl()
+
+
+def getBestJtvTokenPossible(name):
+    # Helper method to find another jtv token
+    swf_url = getSwfUrl(name)
+    headers = {'User-agent': httpHeaderUserAgent,
+               'Referer': swf_url}
+    url = 'http://usher.justin.tv/find/' + name + '.json?type=any&group='
+    data = json.loads(downloadWebData(url))
+    bestVideoHeight = -1
+    bestIndex = -1
+    index = 0
+    for x in data:
+        value = x.get('token', '')
+        videoHeight = int(x['video_height'])
+        if (value != '') and (videoHeight > bestVideoHeight):
+            bestVideoHeight = x['video_height']
+            bestIndex = index
+        index = index + 1
+    if bestIndex == -1:
+        return None
+    return data[bestIndex]
+
+
[email protected]('/playLive/<name>/')
+def playLive(name):
+    swf_url = getSwfUrl(name)
+    headers = {'User-agent': httpHeaderUserAgent,
+               'Referer': swf_url}
+    chosenQuality = settings.getSetting('video')
+    videoTypeName = 'any'
+    if chosenQuality == '0':
+        videoTypeName = 'any'
+    elif chosenQuality == '1':
+        videoTypeName = '720p'
+    elif chosenQuality == '2':
+        videoTypeName = '480p'
+    elif chosenQuality == '3':
+        videoTypeName = '360p'
+    url = 'http://usher.justin.tv/find/' + name + '.json?type=' + \
+        videoTypeName + '&private_code=null&group='
+    data = json.loads(downloadWebData(url))
+    tokenIndex = 0
+
+    try:
+        # trying to get a token in desired quality
+        token = ' jtv=' + data[tokenIndex]['token'].replace(
+            '\\', '\\5c').replace(' ', '\\20').replace('"', '\\22')
+        rtmp = data[tokenIndex]['connect'] + '/' + data[tokenIndex]['play']
+    except:
+        showNotification(translation(32005),translation(32006))
+        jtvtoken = getBestJtvTokenPossible(name)
+        if jtvtoken is None:
+            showNotification(translation(31000),translation(32004))
+            return
+        token = ' jtv=' + jtvtoken['token'].replace('\\', '\\5c').replace(' ', 
'\\20').replace('"', '\\22')
+        rtmp = jtvtoken['connect'] + '/' + jtvtoken['play']
+
+    swf = ' swfUrl=%s swfVfy=1 live=true' % swf_url
+    Pageurl = ' Pageurl=http://www.justin.tv/' + name
+    url = rtmp+token+swf+Pageurl
+    item = xbmcgui.ListItem(path=url)
+    xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, item)
+
+
+if __name__ == '__main__':
+    plugin.run()
diff --git a/plugin.video.twitch/resources/language/English/strings.xml 
b/plugin.video.twitch/resources/language/English/strings.xml
index 67751ba..52dca61 100644
--- a/plugin.video.twitch/resources/language/English/strings.xml
+++ b/plugin.video.twitch/resources/language/English/strings.xml
@@ -1,37 +1,43 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>

-<strings>

-  <!-- main menu -->

-  <string id="30001">Games</string>

-  <string id="30002">Following</string>

-  <string id="30003">Search</string>

-  <string id="30004">Settings</string>

-  <string id="30005">Featured Streams</string>

-  <string id="30006">Teams</string>

-  

-  <!--search -->

-  <string id="30101">Search for channels</string>

-  

-  <!--general --> 

-  <string id="31000">TwitchTV</string>

-  <string id="31001">next page...</string>

-

-   <!--notifications --> 

-  <string id="32001">Http error</string>

-  <string id="32002">No Live Data Found</string>

-  <string id="32003">No archives found for</string>

-  <string id="32004">User Token Error</string>

-  <string id="32005">Changed video settings</string>

-  <string id="32006">Selected video settings are not available</string>

-  <string id="32007">TwitchApi error</string>

-  <string id="32008">JSON error</string>

-  <string id="32009">Failed to parse the result set</string>

-  <string id="32010">Please check your internet connection</string>

-  

-  <!--settings -->

-  <string id="33000">Video Quality</string>

-  <string id="33001">Best possible</string>

-  <string id="33002">720p</string>

-  <string id="33003">480p</string>

-  <string id="33004">360p</string>

-  

-</strings>

+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<strings>
+  <!-- main menu -->
+  <string id="30001">Games</string>
+  <string id="30002">Following</string>
+  <string id="30003">Search</string>
+  <string id="30004">Settings</string>
+  <string id="30005">Featured Streams</string>
+  <string id="30006">Teams</string>
+  
+  <!--search -->
+  <string id="30101">Search for channels</string>
+  
+  <!--general --> 
+  <string id="31000">TwitchTV</string>
+  <string id="31001">next page...</string>
+
+   <!--notifications --> 
+  <string id="32001">Http error</string>
+  <string id="32002">No Live Data Found</string>
+  <string id="32003">No archives found for</string>
+  <string id="32004">User Token Error</string>
+  <string id="32005">Changed video settings</string>
+  <string id="32006">Selected video settings are not available</string>
+  <string id="32007">TwitchApi error</string>
+  <string id="32008">JSON error</string>
+  <string id="32009">Failed to parse the result set</string>
+  <string id="32010">Please check your internet connection</string>
+  
+  <!--settings -->
+  <string id="33000">Video Quality</string>
+  <string id="33001">Best possible</string>
+  <string id="33002">720p</string>
+  <string id="33003">480p</string>
+  <string id="33004">360p</string>
+  <string id="33010">Display titles</string>
+  <string id="33011">Streamer - Stream Title</string>
+  <string id="33012">Viewers - Streamer - Stream Title</string>
+  <string id="33013">Stream Title</string>
+  <string id="33014">Streamer</string>
+
+  <string id="33100">Username</string>
+</strings>
diff --git a/plugin.video.twitch/resources/language/German/strings.xml 
b/plugin.video.twitch/resources/language/German/strings.xml
index d3e8315..efc1f79 100644
--- a/plugin.video.twitch/resources/language/German/strings.xml
+++ b/plugin.video.twitch/resources/language/German/strings.xml
@@ -1,36 +1,43 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>

-<strings>

-  <!-- main menu -->

-  <string id="30001">Games</string>

-  <string id="30002">Folgend</string>

-  <string id="30003">Suche</string>

-  <string id="30004">Einstellungen</string>

-  <string id="30005">Featured Streams</string>

-  <string id="30006">Teams</string>

-  

-  <!-- search -->

-  <string id="30101">Suche nach Kanälen</string>

-  

-   <!--general --> 

-  <string id="31000">TwitchTV</string>

-  <string id="31001">nächste Seite...</string>

-

-   <!--notifications --> 

-  <string id="32001">Http Fehler</string>

-  <string id="32002">Keine Live-Daten gefunden</string>

-  <string id="32003">Keine Archive gefunden für</string>

-  <string id="32004">User Token Fehler</string>

-  <string id="32005">Geaenderte Video Einstellung</string>

-  <string id="32006">Gewaehlte Qualitaet nicht verfuegbar...Eventuell Premium 
Content?</string>

-  <string id="32007">TwitchApi Fehler</string>

-  <string id="32008">JSON Fehler</string>

-  <string id="32009">Fehlerhaftes Datenformat</string>

-  <string id="32010">Bitte Internet-Verbindung pruefen</string>

-  

-    <!--settings -->

-  <string id="33000">Video Qualität</string>

-  <string id="33001">Beste</string>

-  <string id="33002">720p</string>

-  <string id="33003">480p</string>

-  <string id="33004">360p</string>

-</strings>

+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<strings>
+  <!-- main menu -->
+  <string id="30001">Games</string>
+  <string id="30002">Folgend</string>
+  <string id="30003">Suche</string>
+  <string id="30004">Einstellungen</string>
+  <string id="30005">Featured Streams</string>
+  <string id="30006">Teams</string>
+  
+  <!-- search -->
+  <string id="30101">Suche nach Kanälen</string>
+  
+   <!--general --> 
+  <string id="31000">TwitchTV</string>
+  <string id="31001">nächste Seite...</string>
+
+   <!--notifications --> 
+  <string id="32001">Http Fehler</string>
+  <string id="32002">Keine Live-Daten gefunden</string>
+  <string id="32003">Keine Archive gefunden für</string>
+  <string id="32004">User Token Fehler</string>
+  <string id="32005">Geaenderte Video Einstellung</string>
+  <string id="32006">Gewaehlte Qualitaet nicht verfuegbar...Eventuell Premium 
Content?</string>
+  <string id="32007">TwitchApi Fehler</string>
+  <string id="32008">JSON Fehler</string>
+  <string id="32009">Fehlerhaftes Datenformat</string>
+  <string id="32010">Bitte Internet-Verbindung pruefen</string>
+  
+    <!--settings -->
+  <string id="33000">Video Qualität</string>
+  <string id="33001">Beste</string>
+  <string id="33002">720p</string>
+  <string id="33003">480p</string>
+  <string id="33004">360p</string>
+  <string id="33010">Stream-Bezeichnung</string>
+  <string id="33011">Streamer - Status</string>
+  <string id="33012">Zuschauerzahl - Streamer - Status</string>
+  <string id="33013">Status</string>
+  <string id="33014">Streamer</string>
+
+  <string id="33100">Benutzername</string>
+</strings>
diff --git a/plugin.video.twitch/resources/settings.xml 
b/plugin.video.twitch/resources/settings.xml
index c6e5de9..8056a0e 100644
--- a/plugin.video.twitch/resources/settings.xml
+++ b/plugin.video.twitch/resources/settings.xml
@@ -2,9 +2,11 @@
 <settings>
   <!-- General -->
   <category label="General">
-    <setting id="username" type="text" label="Username" default="" />
+    <setting id="username" type="text" label="33100" default="" />
        <!-- Video Quality -->
     <setting id="video" type="enum" label="33000" 
lvalues="33001|33002|33003|33004" default="0" />
+       <!-- Title Display -->
+       <setting id="titledisplay" type="enum" label="33010" 
lvalues="33011|33012|33013|33014" default="0" />
   </category>
   
 

http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=923ff507934be2129acce2eca9947e63046cb235


-----------------------------------------------------------------------

Summary of changes:
 .../LICENSE.txt                                    |    0
 plugin.program.rpcalendar/Mayan-calendar.jpg       |  Bin 0 -> 125954 bytes
 plugin.program.rpcalendar/addon.py                 |  136 ++++
 plugin.program.rpcalendar/addon.xml                |   19 +
 plugin.program.rpcalendar/changelog.txt            |    2 +
 plugin.program.rpcalendar/fanart.jpg               |  Bin 0 -> 203563 bytes
 plugin.program.rpcalendar/icon.png                 |  Bin 0 -> 98216 bytes
 .../resources/__init__.py                          |    0
 .../resources/language/English/strings.xml         |   16 +
 .../resources/media/background.jpg                 |  Bin 0 -> 681682 bytes
 plugin.video.twitch/README.md                      |   27 +
 plugin.video.twitch/addon.xml                      |    9 +-
 plugin.video.twitch/changelog.txt                  |   16 +-
 plugin.video.twitch/default.py                     |  679 ++++++++++----------
 .../resources/language/English/strings.xml         |   80 ++--
 .../resources/language/German/strings.xml          |   79 ++-
 .../resources/language/Polish/strings.xml          |   43 ++
 plugin.video.twitch/resources/settings.xml         |    4 +-
 18 files changed, 678 insertions(+), 432 deletions(-)
 copy {plugin.audio.booksshouldbefree_com => 
plugin.program.rpcalendar}/LICENSE.txt (100%)
 create mode 100644 plugin.program.rpcalendar/Mayan-calendar.jpg
 create mode 100644 plugin.program.rpcalendar/addon.py
 create mode 100644 plugin.program.rpcalendar/addon.xml
 create mode 100644 plugin.program.rpcalendar/changelog.txt
 create mode 100644 plugin.program.rpcalendar/fanart.jpg
 create mode 100644 plugin.program.rpcalendar/icon.png
 copy {plugin.image.iphoto => plugin.program.rpcalendar}/resources/__init__.py 
(100%)
 create mode 100644 
plugin.program.rpcalendar/resources/language/English/strings.xml
 create mode 100644 plugin.program.rpcalendar/resources/media/background.jpg
 create mode 100644 plugin.video.twitch/README.md
 create mode 100644 plugin.video.twitch/resources/language/Polish/strings.xml


hooks/post-receive
-- 
Plugins

------------------------------------------------------------------------------
Minimize network downtime and maximize team effectiveness.
Reduce network management and security costs.Learn how to hire 
the most talented Cisco Certified professionals. Visit the 
Employer Resources Portal
http://www.cisco.com/web/learning/employer_resources/index.html
_______________________________________________
Xbmc-addons mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xbmc-addons

Reply via email to