The branch, dharma has been updated
       via  4eb7d99a37e97cd8af1c3be4eb872f6bbb203f95 (commit)
      from  6a4741b07c332ba564bcb6b407ec836fab7c93c9 (commit)

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

commit 4eb7d99a37e97cd8af1c3be4eb872f6bbb203f95
Author: spiff <[email protected]>
Date:   Fri Feb 24 14:30:58 2012 +0100

    [plugin.video.ted.talks] updated to version 2.3.1

diff --git a/plugin.video.ted.talks/addon.xml b/plugin.video.ted.talks/addon.xml
index acda7f1..bf33f86 100644
--- a/plugin.video.ted.talks/addon.xml
+++ b/plugin.video.ted.talks/addon.xml
@@ -1,12 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="plugin.video.ted.talks"
        name="TED Talks"
-       version="2.2.6"
-       provider-name="rwparris2">
+       version="2.3.1"
+       provider-name="rwparris2, moreginger">
   <requires>
     <import addon="xbmc.python" version="1.0"/>
     <import addon="script.module.simplejson" version="2.0.10"/>
     <import addon="script.module.beautifulsoup" version="3.0.8"/>
+    <import addon="script.module.elementtree" version="1.2.7"/>
   </requires>
   <extension point="xbmc.python.pluginsource"
             library="default.py">
diff --git a/plugin.video.ted.talks/changelog.txt 
b/plugin.video.ted.talks/changelog.txt
index 0f7105f..e0295f0 100644
--- a/plugin.video.ted.talks/changelog.txt
+++ b/plugin.video.ted.talks/changelog.txt
@@ -1,3 +1,17 @@
+[B]Version 2.3.1[/B]
+Works on Dharma again
+Newest Talks now work on Eden+Win32
+Remove duplicates of some themes
+
+[B]Version 2.3.0[/B]
+Get new talks from RSS feeds
+Update themes scraper to cope with website changes
+Icons for themes
+Log correct version number for plugin on startup
+
+[B]Version 2.2.6[/B]
+Fix for problem introduced in 2.2.5 where certain talks could not be played.
+
 [B]Version 2.2.5[/B]
 Fixed playback of certain videos would fail (thanks to moreginger)
 
diff --git a/plugin.video.ted.talks/default.py 
b/plugin.video.ted.talks/default.py
index ef7443d..87e21f7 100644
--- a/plugin.video.ted.talks/default.py
+++ b/plugin.video.ted.talks/default.py
@@ -3,27 +3,15 @@
     rwparris2
 """
 import sys
+import resources.lib.plugin as plugin
+import resources.lib.model.arguments as arguments
 
-#plugin constants
-__plugin__ = "TED Talks"
-__author__ = "rwparris2"
-__url__ = "http://code.google.com/p/xbmc-addons/";
-__svn_url__ = 
"http://xbmc-addons.googlecode.com/svn/trunk/plugins/video/TED%20Talks";
-__version__ = "2.2.2"
-
-print "[PLUGIN] '%s: version %s' initialized!" % (__plugin__, __version__)
 
 if __name__ == "__main__":
+    plugin.init()
     import resources.lib.ted_talks as ted_talks
-    if not sys.argv[2]:
-        ted_talks.Main()
-    elif sys.argv[2].startswith('?addToFavorites'):
-        
ted_talks.Main(checkMode=False).addToFavorites(sys.argv[2].split('=')[-1])
-    elif sys.argv[2].startswith('?removeFromFavorites'):
-        
ted_talks.Main(checkMode=False).removeFromFavorites(sys.argv[2].split('=')[-1])
-    elif sys.argv[2].startswith('?downloadVideo'):
-        ted_talks.Main(checkMode=False).downloadVid(sys.argv[2].split('=')[-1])
-    else:
-        ted_talks.Main()
+
+    args_map = arguments.parse_arguments(sys.argv[2])
+    ted_talks.Main(logger = plugin.log, args_map = args_map).run()
 
 sys.modules.clear()
diff --git a/plugin.video.ted.talks/resources/language/English/strings.xml 
b/plugin.video.ted.talks/resources/language/English/strings.xml
index 05fbbf8..436a0b9 100644
--- a/plugin.video.ted.talks/resources/language/English/strings.xml
+++ b/plugin.video.ted.talks/resources/language/English/strings.xml
@@ -38,12 +38,12 @@
     <string id="30074">Always Ask for Download Location</string>
     
     <!--Context Menu-->
-    <!--<string id="13347">Queue item</string>from system-->
     <string id="30090">Add to TED.com favorites</string>
     <string id="30091">Add to favorites successful</string>
     <string id="30092">Add to favorites failed</string>
     <string id="30093">Remove from TED.com favorites</string>
     <string id="30094">Remove from favorites successful</string>
     <string id="30095">Remove from favorites failed</string>
-    <string id="30096">Download Video</string>
+    <string id="30096">Download video</string>
+    <string id="30097">Queue</string><!-- Was 13347 from system, but no longer 
available. -->
 </strings>
\ No newline at end of file
diff --git a/plugin.video.ted.talks/resources/lib/talkDownloader.py 
b/plugin.video.ted.talks/resources/lib/talkDownloader.py
index c3e766d..8f829c6 100644
--- a/plugin.video.ted.talks/resources/lib/talkDownloader.py
+++ b/plugin.video.ted.talks/resources/lib/talkDownloader.py
@@ -1,15 +1,14 @@
 import urllib
 import os.path
-import sys
 import xbmc
 import xbmcgui
 
 #enable localization
 import xbmcaddon
+import plugin
 
 __settings__ = xbmcaddon.Addon(id='plugin.video.ted.talks')
 getLS = __settings__.getLocalizedString
-pluginName = sys.modules['__main__'].__plugin__
 
 
 class Download:
@@ -24,12 +23,12 @@ class Download:
         #unicode causes problems here, convert to standard str
         self.filename = self.getLegalFilename(self.title.title().replace(' ', 
'') + '.mp4')
         self.fullDownloadPath = os.path.join(downloadPath, self.filename)
-        print '[%s] %s : Attempting to download\n%s --> %s' % (pluginName, 
__name__, self.url, self.fullDownloadPath)
+        print '[%s] %s : Attempting to download\n%s --> %s' % 
(plugin.__plugin__, __name__, self.url, self.fullDownloadPath)
 
         if self.checkPath(downloadPath, self.filename):
             try:
                 re = urllib.urlretrieve(self.url, self.fullDownloadPath, 
reporthook = self.showdlProgress)
-                print '[%s] Download Success!' % (pluginName)
+                print '[%s] Download Success!' % (plugin.__plugin__)
             except IOError, e:
                 print e
                 self.pDialog.close()
diff --git a/plugin.video.ted.talks/resources/lib/ted_talks.py 
b/plugin.video.ted.talks/resources/lib/ted_talks.py
index 85d9e88..7e5d0b5 100644
--- a/plugin.video.ted.talks/resources/lib/ted_talks.py
+++ b/plugin.video.ted.talks/resources/lib/ted_talks.py
@@ -1,34 +1,37 @@
 import sys
 import urllib
 import ted_talks_scraper
+from talkDownloader import Download
+from model.fetcher import Fetcher
+from model.user import User
+from model.rss_scraper import NewTalksRss
+from model.favorites_scraper import Favorites
+import menu_util
 import xbmc
 import xbmcplugin
 import xbmcgui
-from talkDownloader import Download
 import xbmcaddon
 
 __settings__ = xbmcaddon.Addon(id='plugin.video.ted.talks')
 getLS = __settings__.getLocalizedString
 
-#getLS = xbmc.getLocalizedString
-TedTalks = ted_talks_scraper.TedTalks()
-
 
-class updateArgs:
-
-    def __init__(self, *args, **kwargs):
-        for key, value in kwargs.iteritems():
-            if value == 'None':
-                kwargs[key] = None
-            else:
-                kwargs[key] = urllib.unquote_plus(kwargs[key])
-        self.__dict__.update(kwargs)
+def login(user_scraper, username, password):
+    user_details = user_scraper.login(username, password)
+    if not user_scraper:
+        xbmcgui.Dialog().ok(getLS(30050), getLS(30051))
+    return user_details
 
 
 class UI:
 
-    def __init__(self):
-        self.main = Main(checkMode = False)
+    def __init__(self, logger, get_HTML, ted_talks, user, settings, args):
+        self.logger = logger
+        self.get_HTML = get_HTML
+        self.ted_talks = ted_talks
+        self.user = user
+        self.settings = settings
+        self.args = args
         xbmcplugin.setContent(int(sys.argv[1]), 'movies')
 
     def endofdirectory(self, sortMethod = 'title'):
@@ -39,57 +42,48 @@ class UI:
             sortMethod = xbmcplugin.SORT_METHOD_DATE
         #Sort methods are required in library mode.
         xbmcplugin.addSortMethod(int(sys.argv[1]), sortMethod)
-        #If name is next or previous, then the script arrived here from a 
navItem, and won't to add to the heirarchy
-        if self.main.args.name in [getLS(30020), getLS(30021)]:
-            dontAddToHierarchy = True
-        else:
-            dontAddToHierarchy = False
         #let xbmc know the script is done adding items to the list.
-        xbmcplugin.endOfDirectory(handle = int(sys.argv[1]), updateListing = 
dontAddToHierarchy)
+        xbmcplugin.endOfDirectory(handle = int(sys.argv[1]), updateListing = 
False)
 
-    def addItem(self, info, isFolder=True):
+    def addItem(self, info, isFolder = True):
         #Defaults in dict. Use 'None' instead of None so it is compatible for 
quote_plus in parseArgs
+        #create params for xbmcplugin module
+        args = {}
+        for key1, key2 in {'url': 'url', 'mode': 'mode', 'Title': 'name', 
'Thumb': 'icon'}.iteritems():
+            if key1 in info:
+                if info[key1] is None:
+                    self.logger("'None' in item dict: " + info)
+                else:
+                    args[key2] = urllib.quote_plus(info[key1].encode('ascii', 
'ignore'))
+        
+        u = sys.argv[0] + '?' + "&".join(key + '=' + value for key, value in 
args.iteritems())
+                        
         info.setdefault('url', 'None')
         info.setdefault('Thumb', 'None')
         info.setdefault('Icon', info['Thumb'])
-        #create params for xbmcplugin module
-        u = sys.argv[0]+\
-            '?url='+urllib.quote_plus(info['url'])+\
-            '&mode='+urllib.quote_plus(info['mode'])+\
-            
'&name='+urllib.quote_plus(info['Title'].encode('ascii','ignore'))+\
-            '&icon='+urllib.quote_plus(info['Thumb'])            
         #create list item
         if info['Title'].startswith(" "):
-          title = info['Title'][1:]
+            title = info['Title'][1:]
         else:
-          title = info['Title']  
-        li=xbmcgui.ListItem(label = title, iconImage = info['Icon'], 
thumbnailImage = info['Thumb'])
-        li.setInfo(type='Video', infoLabels=info)
+            title = info['Title']  
+        li = xbmcgui.ListItem(label = title, iconImage = info['Icon'], 
thumbnailImage = info['Thumb'])
+        li.setInfo(type='Video', infoLabels = info)
         #for videos, replace context menu with queue and add to favorites
         if not isFolder:
             li.setProperty("IsPlayable", "true")#let xbmc know this can be 
played, unlike a folder.
-            #add context menu items to non-folder items.
-            contextmenu = [(getLS(13347), 'Action(Queue)')]
-            contextmenu += [(getLS(30096), 'RunPlugin(%s?downloadVideo=%s)' % 
(sys.argv[0], info['url']))]
-            #only add add to favorites context menu if the user has a username 
& isn't already looking at favorites.
-            if self.main.settings['username']:
-                if self.main.args.mode == 'favorites':
-                    contextmenu += [(getLS(30093), 
'RunPlugin(%s?removeFromFavorites=%s)' % (sys.argv[0], info['url']))]
-                else:
-                    contextmenu += [(getLS(30090), 
'RunPlugin(%s?addToFavorites=%s)' % (sys.argv[0], info['url']))]
-            #replaceItems=True replaces the useless one with the two defined 
above.
-            li.addContextMenuItems(contextmenu, replaceItems=True)
-        #for folders, completely remove contextmenu, as it is totally useless.
+            context_menu = menu_util.create_context_menu(getLS = getLS)
+            li.addContextMenuItems(context_menu, replaceItems = True)
         else:
-            li.addContextMenuItems([], replaceItems=True)
+            #for folders, completely remove contextmenu, as it is totally 
useless.
+            li.addContextMenuItems([], replaceItems = True)
         #add item to list
-        ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=u, 
listitem=li, isFolder=isFolder)
+        xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=u, 
listitem=li, isFolder=isFolder)
 
     def playVideo(self):
-        video = TedTalks.getVideoDetails(self.main.args.url)
+        video = self.ted_talks.getVideoDetails(self.args['url'])
         li=xbmcgui.ListItem(video['Title'],
-                            iconImage = self.main.args.icon,
-                            thumbnailImage = self.main.args.icon,
+                            iconImage = self.args['icon'],
+                            thumbnailImage = self.args['icon'],
                             path = video['url'])
         li.setInfo(type='Video', infoLabels=video)
         xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, li)
@@ -101,41 +95,43 @@ class UI:
             self.addItem({'Title': getLS(30021), 'url':navItems['previous'], 
'mode':mode})
 
     def showCategories(self):
-        self.addItem({'Title':getLS(30001), 'mode':'newTalks', 
'Plot':getLS(30031)})#new
+        self.addItem({'Title':getLS(30001), 'mode':'newTalksRss', 
'Plot':getLS(30031)})#new RSS
         self.addItem({'Title':getLS(30002), 'mode':'speakers', 
'Plot':getLS(30032)})#speakers
         self.addItem({'Title':getLS(30003), 'mode':'themes', 
'Plot':getLS(30033)})#themes
         #self.addItem({'Title':getLS(30004), 'mode':'search', 
'Plot':getLS(30034)})#search
-        if self.main.settings['username']:
+        if self.settings['username']:
             self.addItem({'Title':getLS(30005), 'mode':'favorites', 
'Plot':getLS(30035)})#favorites
         self.endofdirectory()
-
-    def newTalks(self):
-        newMode = 'playVideo'
-        newTalks = TedTalks.NewTalks(self.main.args.url)
-        #add talks to the list
-        for talk in newTalks.getNewTalks():
-            talk['mode'] = newMode
-            self.addItem(talk, isFolder = False)
-        #add nav items to the list
-        self.navItems(newTalks.navItems, self.main.args.mode)
-        #end the list
+        
+    def newTalksRss(self):
+        newTalks = NewTalksRss(self.logger)
+        for talk in newTalks.get_new_talks():
+            li = xbmcgui.ListItem(label = talk['title'], iconImage = 
talk['thumb'], thumbnailImage = talk['thumb'])
+            li.setProperty("IsPlayable", "true")
+            li.setInfo('video', {'date':talk['date'], 
'duration':talk['duration'], 'plot':talk['plot']})
+            favorites_action = None
+            if self.settings['username'] != None:
+                favorites_action = "add"
+            context_menu = menu_util.create_context_menu(getLS = getLS, url = 
talk['link'], favorites_action = favorites_action, talkID = talk['id'])
+            li.addContextMenuItems(context_menu, replaceItems = True)
+            xbmcplugin.addDirectoryItem(handle = int(sys.argv[1]), url = 
talk['link'], listitem = li)
         self.endofdirectory(sortMethod = 'date')
 
     def speakers(self):
         newMode = 'speakerVids'
-        speakers = TedTalks.Speakers(self.main.args.url)
+        speakers = self.ted_talks.Speakers(self.get_HTML, self.args.get('url'))
         #add speakers to the list
         for speaker in speakers.getAllSpeakers():
             speaker['mode'] = newMode
             self.addItem(speaker, isFolder = True)
         #add nav items to the list
-        self.navItems(speakers.navItems, self.main.args.mode)
+        self.navItems(speakers.navItems, self.args['mode'])
         #end the list
         self.endofdirectory()
 
     def speakerVids(self):
         newMode = 'playVideo'
-        speakers = TedTalks.Speakers(self.main.args.url)
+        speakers = self.ted_talks.Speakers(self.get_HTML, self.args.get('url'))
         for talk in speakers.getTalks():
             talk['mode'] = newMode
             self.addItem(talk, isFolder = False)
@@ -144,7 +140,7 @@ class UI:
 
     def themes(self):
         newMode = 'themeVids'
-        themes = TedTalks.Themes(self.main.args.url)
+        themes = self.ted_talks.Themes(self.get_HTML, self.args.get('url'))
         #add themes to the list
         for theme in themes.getThemes():
             theme['mode'] = newMode
@@ -154,7 +150,7 @@ class UI:
 
     def themeVids(self):
         newMode = 'playVideo'
-        themes = TedTalks.Themes(self.main.args.url)
+        themes = self.ted_talks.Themes(self.get_HTML, self.args.get('url'))
         for talk in themes.getTalks():
             talk['mode'] = newMode
             self.addItem(talk, isFolder = False)
@@ -163,9 +159,9 @@ class UI:
     def favorites(self):
         newMode = 'playVideo'
         #attempt to login
-        if self.main.isValidUser():
-            favorites = TedTalks.Favorites()
-            for talk in favorites.getFavoriteTalks(self.main.user):
+        userID, realname = login(self.user, self.settings['username'], 
self.settings['password'])
+        if userID:
+            for talk in Favorites(self.logger, 
self.get_HTML).getFavoriteTalks(userID):
                 talk['mode'] = newMode
                 self.addItem(talk, isFolder = False)
             self.endofdirectory()
@@ -173,22 +169,13 @@ class UI:
 
 class Main:
 
-    def __init__(self, checkMode = True):
-        self.user = None
-        self.parseArgs()
+    def __init__(self, logger, args_map):
+        self.logger = logger
+        self.args_map = args_map
         self.getSettings()
-        if checkMode:
-            self.checkMode()
-
-    def parseArgs(self):
-        # call updateArgs() with our formatted argv to create the self.args 
object
-        if (sys.argv[2]):
-            exec "self.args = updateArgs(%s')" % (sys.argv[2][1:].replace('&', 
"',").replace('=', "='"))
-        else:
-            # updateArgs will turn the 'None' into None.
-            # Don't simply define it as None because unquote_plus in 
updateArgs will throw an exception.
-            # This is a pretty ugly solution, but fuck it :(
-            self.args = updateArgs(mode = 'None', url = 'None', name = 'None')
+        self.get_HTML = Fetcher(logger, xbmc.translatePath).getHTML
+        self.user = User(self.get_HTML)
+        self.ted_talks = ted_talks_scraper.TedTalks(self.get_HTML)
 
     def getSettings(self):
         self.settings = dict()
@@ -197,32 +184,23 @@ class Main:
         self.settings['downloadMode'] = __settings__.getSetting('downloadMode')
         self.settings['downloadPath'] = __settings__.getSetting('downloadPath')
 
-    def isValidUser(self):
-        self.user = TedTalks.User(self.settings['username'], 
self.settings['password'])
-        if self.user:
-            return True
-        else:
-            xbmcgui.Dialog().ok(getLS(30050), getLS(30051))
-            return False
-
-    def addToFavorites(self, url):
-        if self.isValidUser():
-            successful = TedTalks.Favorites().addToFavorites(self.user, url)
-            if successful:
-                xbmc.executebuiltin('Notification(%s,%s,)' % (getLS(30000), 
getLS(30091)))
+    def set_favorite(self, talkID, is_favorite):
+        """
+        talkID ID for the talk.
+        is_favorite True to set as a favorite, False to unset.
+        """
+        if login(self.user, self.settings['username'], 
self.settings['password']):
+            favorites = Favorites(self.logger, self.fetcher.getHTML)
+            if is_favorite:
+                successful = favorites.addToFavorites(talkID)
             else:
-                xbmc.executebuiltin('Notification(%s,%s,)' % (getLS(30000), 
getLS(30092)))
-
-    def removeFromFavorites(self, url):
-        if self.isValidUser():
-            successful = TedTalks.Favorites().removeFromFavorites(self.user, 
url)
-            if successful:
-                xbmc.executebuiltin('Notification(%s,%s,)' % (getLS(30000), 
getLS(30094)))
-            else:
-                xbmc.executebuiltin('Notification(%s,%s,)' % (getLS(30000), 
getLS(30095)))
+                successful = favorites.removeFromFavorites(talkID)
+            notification_messages = {(True, True): 30091, (True, False): 
30092, (False, True): 30094, (False, False): 30095}
+            notification_message = notification_messages[(is_favorite, 
successful)]
+            xbmc.executebuiltin('Notification(%s,%s,)' % (getLS(30000), 
getLS(notification_message)))
 
     def downloadVid(self, url):
-        video = TedTalks.getVideoDetails(url)
+        video = self.ted_talks.getVideoDetails(url)
         if self.settings['downloadMode'] == 'true':
             downloadPath = xbmcgui.Dialog().browse(3, getLS(30096), 'files')
         else:
@@ -230,21 +208,31 @@ class Main:
         if downloadPath:
             Download(video['Title'], video['url'], downloadPath)
 
-    def checkMode(self):
-        mode = self.args.mode
-        if mode is None:
-            UI().showCategories()
-        elif mode == 'playVideo':
-            UI().playVideo()
-        elif mode == 'newTalks':
-            UI().newTalks()
-        elif mode == 'speakers':
-            UI().speakers()
-        elif mode == 'speakerVids':
-            UI().speakerVids()
-        elif mode == 'themes':
-            UI().themes()
-        elif mode == 'themeVids':
-            UI().themeVids()
-        elif mode == 'favorites':
-            UI().favorites()
+    def run(self):
+        # TODO Make these all modes for consistency
+        if 'addToFavorites' in self.args_map:
+            self.set_favorite(self.args_map['addToFavorites'], True)
+        if 'removeFromFavorites' in self.args_map:
+            self.set_favorite(self.args_map['removeFromFavorites'], False)
+        if 'downloadVideo' in self.args_map:
+            self.downloadVid(self.args_map('downloadVideo'))
+        
+        ui = UI(self.logger, self.get_HTML, self.ted_talks, self.user, 
self.settings, self.args_map)
+        if 'mode' not in self.args_map:
+            ui.showCategories()
+        else:
+            mode = self.args_map['mode']
+            if mode == 'playVideo':
+                ui.playVideo()
+            elif mode == 'newTalksRss':
+                ui.newTalksRss()
+            elif mode == 'speakers':
+                ui.speakers()
+            elif mode == 'speakerVids':
+                ui.speakerVids()
+            elif mode == 'themes':
+                ui.themes()
+            elif mode == 'themeVids':
+                ui.themeVids()
+            elif mode == 'favorites':
+                ui.favorites()
diff --git a/plugin.video.ted.talks/resources/lib/ted_talks_scraper.py 
b/plugin.video.ted.talks/resources/lib/ted_talks_scraper.py
index 3cc31da..cc04336 100644
--- a/plugin.video.ted.talks/resources/lib/ted_talks_scraper.py
+++ b/plugin.video.ted.talks/resources/lib/ted_talks_scraper.py
@@ -1,46 +1,73 @@
 import re
-import sys
-from ClientForm import ParseResponse
-from util import getHTML, getUrllib2ResponseObject, cleanHTML, resizeImage
+from model.util import cleanHTML, resizeImage
 from BeautifulSoup import SoupStrainer, MinimalSoup as BeautifulSoup
+from model.url_constants import URLTED
 
 #MAIN URLS
-URLTED = 'http://www.ted.com'
 URLTHEMES = 'http://www.ted.com/themes/atoz/page/'
 URLSPEAKERS = 'http://www.ted.com/speakers/atoz/page/'
-URLNEW = 'http://www.ted.com/talks/list/page/'
 URLSEARCH = 'http://www.ted.com/search?q=%s/page/'
-URLLOGIN = 'http://www.ted.com/users/signin/'
-URLPROFILE = 'http://www.ted.com/profiles/'
-URLFAVORITES = 'http://www.ted.com/profiles/favorites/id/'
-URLADDFAV ='http://www.ted.com/profiles/addfavorites?id=%s&modulename=talks'
-URLREMFAV ='http://www.ted.com/profiles/removefavorites?id=%s&modulename=talks'
 
-pluginName = sys.modules['__main__'].__plugin__
+def getNavItems(html):
+    """self.navItems={'next':url, 'previous':url, 
'selected':pagenumberasaninteger}"""
+    navItems = {'next':None, 'previous':None, 'selected':1}
+    paginationContainer = SoupStrainer(attrs = 
{'class':re.compile('pagination')})
+    for liTag in BeautifulSoup(html, parseOnlyThese = 
paginationContainer).findAll('li'):
+        if liTag.has_key('class'):
+            if liTag['class'] == 'next':
+                navItems['next'] = URLTED+liTag.a['href']
+            elif liTag['class'] == 'prev':
+                navItems['previous'] = URLTED+liTag.a['href']
+            elif liTag['class'] == 'selected':
+                navItems['selected'] = int(liTag.a.string)
+    return navItems
+
+
+class NewTalks:
+    """
+    Fetches new talks!
+    """
+    
+    def __init__(self, getHTML, getLS):
+        """
+        getHTML method to getHTML from a URL
+        getLS method to get localized string from an integer code
+        """
+        self.getHTML = getHTML
+        self.getLS = getLS
+ 
+    def getNewTalks(self, url = None):
+        """
+        Returns 2-tuples, first value is whether this is a folder, second is 
attributes dict
+        """
+        if url == None:
+            url = 'http://www.ted.com/talks/list/page/'
+        html = self.getHTML(url)
+
+        # Forward/backwards        
+        navItems = getNavItems(html)
+        if navItems['next']:
+            yield True, {'mode':'newTalks', 'Title': self.getLS(30020), 
'url':navItems['next']}
+        if navItems['previous']:
+            yield True, {'mode':'newTalks', 'Title': self.getLS(30021), 
'url':navItems['previous']}
+        
+        talkContainers = SoupStrainer(attrs = 
{'class':re.compile('talkMedallion')})
+        for talk in BeautifulSoup(html, parseOnlyThese = talkContainers):
+            link = URLTED+talk.dt.a['href']
+            title = cleanHTML(talk.dt.a['title'])
+            pic = resizeImage(talk.find('img', attrs = 
{'src':re.compile('.+?\.jpg')})['src'])
+            yield False, {'mode':'playVideo', 'url':link, 'Title':title, 
'Thumb':pic}
 
 
 class TedTalks:
 
-    def getNavItems(self, html):
-        """self.navItems={'next':url, 'previous':url, 
'selected':pagenumberasaninteger}"""
-        navItems = {'next':None, 'previous':None, 'selected':1}
-        paginationContainer = SoupStrainer(attrs = 
{'class':re.compile('pagination')})
-        for liTag in BeautifulSoup(html, parseOnlyThese = 
paginationContainer).findAll('li'):
-            if liTag.has_key('class'):
-                if liTag['class'] == 'next':
-                    navItems['next'] = URLTED+liTag.a['href']
-                elif liTag['class'] == 'prev':
-                    navItems['previous'] = URLTED+liTag.a['href']
-                elif liTag['class'] == 'selected':
-                    navItems['selected'] = int(liTag.a.string)
-            else: #no class attrib found.
-                print '[%s] %s no pagination found.' % (pluginName, __name__)
-        return navItems
+    def __init__(self, getHTML):
+        self.getHTML = getHTML
 
     def getVideoDetails(self, url):
         """self.videoDetails={Title, Director, Genre, Plot, id, url}"""
         #TODO: get 'related tags' and list them under genre
-        html = getHTML(url)
+        html = self.getHTML(url)
         url = ""
         soup = BeautifulSoup(html)
         #get title
@@ -63,77 +90,26 @@ class TedTalks:
                     break
 
         if url == "":
-          # look for utub link
-          utublinks = 
re.compile('http://(?:www.)?youtube.com/v/([^\&]*)\&').findall(html)
-          for link in utublinks:
-            url = 
'plugin://plugin.video.youtube/?action=play_video&videoid=%s' %(link)
+            # look for utub link
+            utublinks = 
re.compile('http://(?:www.)?youtube.com/v/([^\&]*)\&').findall(html)
+            for link in utublinks:
+                url = 
'plugin://plugin.video.youtube/?action=play_video&videoid=%s' %(link)
         #get id from url
         id = url.split('/')[-1]
         return {'Title':title, 'Director':speaker, 'Genre':'TED', 'Plot':plot, 
'PlotOutline':plot, 'id':id, 'url':url}
 
-    class User:
-        """makes a user object"""
-
-        def __init__(self, username = None, password = None):
-            self.username = username
-            self.password = password
-            if username and password:
-                self.id, self.realName = self.getUserDetails()
-            else:
-                self.id = self.realName = None
-
-        def getUserDetails(self):
-            html = self.getLoginResponse()
-            userContainer = SoupStrainer(attrs = 
{'class':re.compile('notices')})
-            for aTag in BeautifulSoup(html, parseOnlyThese = 
userContainer).findAll('a'):
-                if aTag['href'].startswith(URLPROFILE):
-                    id = aTag['href'].split('/')[-1]
-                    realName = aTag.string.strip()
-                    break
-                else:
-                    id = realName = None
-            return id, realName
-
-        def getLoginResponse(self, url = URLLOGIN):
-            #clientform doesn't like HTML, and I don't want to monkey patch 
it, so getUrllib2ResponseObject was born.
-            response = getUrllib2ResponseObject(url)
-            forms = ParseResponse(response, backwards_compat=False)
-            response.close()
-            #set username & password in the signin form
-            form = forms[1]
-            form["users[username]"] = self.username
-            form["users[password]"] = self.password
-            form["users[rememberme]"] = ["on"]
-            #click submit
-            return getHTML(form.click())
-
-    class NewTalks:
-        """self.videos=[{'link':link,'Title':title,'pic':pic},...]"""
-
-        def __init__(self, url=None):
-            if url is None:
-                url = URLNEW
-            self.html = getHTML(url)
-            self.navItems = TedTalks().getNavItems(self.html)
-
-        def getNewTalks(self):
-            talkContainers = SoupStrainer(attrs = 
{'class':re.compile('talkMedallion')})
-            for talk in BeautifulSoup(self.html, parseOnlyThese = 
talkContainers):
-                link = URLTED+talk.dt.a['href']
-                title = cleanHTML(talk.dt.a['title'])
-                pic = resizeImage(talk.find('img', attrs = 
{'src':re.compile('.+?\.jpg')})['src'])
-                yield {'url':link, 'Title':title, 'Thumb':pic}
 
     class Speakers:
 
-        def __init__(self, url=None):
+        def __init__(self, get_HTML, url):
             # adding 9999 to the url takes the script to the very last page of 
the list, providing the total # of pages.
-            if url == None:
-                url = URLSPEAKERS+'9999'
-            self.html = getHTML(url)
+            if url is None:
+                url = URLSPEAKERS + '9999'
+            self.get_HTML = get_HTML
+            self.html = self.get_HTML(url)
             # only bother with navItems where they have a chance to appear.
             if URLSPEAKERS in url:
-                self.navItems = TedTalks().getNavItems(self.html)
+                self.navItems = getNavItems(self.html)
 
         def getSpeakers(self):
             # use getAllSpeakers instead... just leaving this function here 
for educational purposes.
@@ -148,7 +124,7 @@ class TedTalks:
             for i in range(self.navItems['selected']):
                 # don't parse the last page twice.
                 if i is not 8:
-                    html = getHTML(URLSPEAKERS+str(i+1))
+                    html = self.get_HTML(URLSPEAKERS+str(i+1))
                 else:
                     html = self.html
                 for speaker in BeautifulSoup(html, parseOnlyThese = 
speakerContainers):
@@ -166,20 +142,25 @@ class TedTalks:
 
     class Themes:
 
-        def __init__(self, url=None):
+        def __init__(self, get_HTML, url=None):
             if url == None:
                 url = URLTHEMES
-            self.html = getHTML(url)
+            self.get_HTML = get_HTML
+            self.html = self.get_HTML(url)
             # a-z themes don't yet have navItems, so the check can be skipped 
for now.
             # self.navItems = TedTalks().getNavItems(html)
 
         def getThemes(self):
-            themes = list()
-            themeContainers = SoupStrainer(attrs = 
{'href':re.compile('/themes/\S.+?.html')})
+            themeContainers = SoupStrainer(name = 'a', attrs = 
{'href':re.compile('/themes/\S.+?.html')})
+            seen_titles = set()
             for theme in BeautifulSoup(self.html, parseOnlyThese = 
themeContainers):
-                title = theme.string
-                link = URLTED+theme['href']
-                yield {'url':link, 'Title':title}
+                if theme.img:
+                    title = theme['title']
+                    if title not in seen_titles:
+                        seen_titles.add(title)
+                        link = URLTED + theme['href']
+                        thumb = theme.img['src']
+                        yield {'url':link, 'Title':title, 'Thumb':thumb}
 
         def getTalks(self):
             # themes loaded with a json call. Why are they not more consistant?
@@ -187,7 +168,7 @@ class TedTalks:
             # search HTML for the link to tedtalk's "api".  It is easier to 
use regex here than BS.
             jsonUrl = URLTED+re.findall('DataSource\("(.+?)"', self.html)[0]
             # make a dict from the json formatted string from above url
-            talksMarkup = loads(getHTML(jsonUrl))
+            talksMarkup = loads(self.get_HTML(jsonUrl))
             # parse through said dict for all the metadata
             for markup in talksMarkup['resultSet']['result']:
                 talk = BeautifulSoup(markup['markup'])
@@ -196,44 +177,6 @@ class TedTalks:
                 pic = resizeImage(talk.find('img', attrs = 
{'src':re.compile('.+?\.jpg')})['src'])
                 yield {'url':link, 'Title':title, 'Thumb':pic}
 
-    class Favorites:
-
-        def getFavoriteTalks(self, user, url = URLFAVORITES):
-            """user must be TedTalks().User object with .id attribute"""
-            if user.id is not None:
-                html = getHTML(url+user.id)
-                talkContainer = SoupStrainer(attrs = {'class':re.compile('box 
clearfix')})
-                for talk in BeautifulSoup(html, parseOnlyThese = 
talkContainer):
-                    title = talk.ul.a.string
-                    link = URLTED+talk.dt.a['href']
-                    pic = resizeImage(talk.find('img', attrs = 
{'src':re.compile('.+?\.jpg')})['src'])
-                    yield {'url':link, 'Title':title, 'Thumb':pic}
-            else:
-                print '[%s] %s invalid user object' % (pluginName, __name__)
-
-        def addToFavorites(self, user, url):
-            """user must be TedTalks().User object with .id attribute"""
-            if user.id is not None:
-                id = TedTalks().getVideoDetails(url)['id']
-                print id
-                response = getHTML(URLADDFAV % (id))
-                if response:
-                    print '[%s] %s addToFavorites success' % (pluginName, 
__name__)
-                    return True
-            else:
-                print '[%s] %s invalid user object' % (pluginName, __name__)
-
-        def removeFromFavorites(self, user, url):
-            """user must be TedTalks().User object with .id attribute"""
-            if user.id is not None:
-                id = TedTalks().getVideoDetails(url)['id']
-                print id
-                response = getHTML(URLREMFAV % (id))
-                if response:
-                    print '[%s] %s removeFromFavorites success' % (pluginName, 
__name__)
-                    return True
-            else:
-                print '[%s] %s invalid user object' % (pluginName, __name__)
 
     class Search:
         pass

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

Summary of changes:
 plugin.video.ted.talks/.gitignore                  |    3 +
 plugin.video.ted.talks/addon.xml                   |    5 +-
 plugin.video.ted.talks/changelog.txt               |   14 ++
 plugin.video.ted.talks/default.py                  |   24 +--
 .../resources/language/English/strings.xml         |    4 +-
 plugin.video.ted.talks/resources/lib/menu_util.py  |   12 +
 .../resources/lib/menu_util_test.py                |   29 +++
 .../resources/lib/model}/ClientForm.py             |    0
 .../resources/lib/model}/__init__.py               |    0
 .../resources/lib/model/arguments.py               |   11 +
 .../resources/lib/model/arguments_test.py          |    9 +
 .../resources/lib/model/favorites_scraper.py       |   34 +++
 .../resources/lib/model/fetcher.py                 |   44 ++++
 .../resources/lib/model/rss_scraper.py             |  106 +++++++++
 .../resources/lib/model/rss_scraper_test.py        |   63 +++++
 .../resources/lib/model/url_constants.py           |    5 +
 plugin.video.ted.talks/resources/lib/model/user.py |   52 +++++
 .../resources/lib/model/user_test.py               |   46 ++++
 plugin.video.ted.talks/resources/lib/model/util.py |   32 +++
 plugin.video.ted.talks/resources/lib/plugin.py     |   19 ++
 .../resources/lib/talkDownloader.py                |    7 +-
 plugin.video.ted.talks/resources/lib/ted_talks.py  |  240 +++++++++----------
 .../resources/lib/ted_talks_scraper.py             |  213 +++++++-----------
 .../resources/lib/ted_talks_scraper_test.py        |   53 +++++
 24 files changed, 738 insertions(+), 287 deletions(-)
 create mode 100644 plugin.video.ted.talks/.gitignore
 create mode 100644 plugin.video.ted.talks/resources/lib/menu_util.py
 create mode 100644 plugin.video.ted.talks/resources/lib/menu_util_test.py
 copy {plugin.video.arretsurimages/resources/lib => 
plugin.video.ted.talks/resources/lib/model}/ClientForm.py (100%)
 copy {plugin.program.executor/resources => 
plugin.video.ted.talks/resources/lib/model}/__init__.py (100%)
 create mode 100644 plugin.video.ted.talks/resources/lib/model/arguments.py
 create mode 100644 plugin.video.ted.talks/resources/lib/model/arguments_test.py
 create mode 100644 
plugin.video.ted.talks/resources/lib/model/favorites_scraper.py
 create mode 100644 plugin.video.ted.talks/resources/lib/model/fetcher.py
 create mode 100644 plugin.video.ted.talks/resources/lib/model/rss_scraper.py
 create mode 100644 
plugin.video.ted.talks/resources/lib/model/rss_scraper_test.py
 create mode 100644 plugin.video.ted.talks/resources/lib/model/url_constants.py
 create mode 100644 plugin.video.ted.talks/resources/lib/model/user.py
 create mode 100644 plugin.video.ted.talks/resources/lib/model/user_test.py
 create mode 100644 plugin.video.ted.talks/resources/lib/model/util.py
 create mode 100644 plugin.video.ted.talks/resources/lib/plugin.py
 create mode 100644 
plugin.video.ted.talks/resources/lib/ted_talks_scraper_test.py


hooks/post-receive
-- 
Plugins

------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
Xbmc-addons mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xbmc-addons

Reply via email to