The branch, dharma has been updated
       via  ed23a9aa65f7ca309912b55b728badacbbe4a835 (commit)
      from  6e9b46b146f155e78f401b4b101f7251daa7e303 (commit)

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

commit ed23a9aa65f7ca309912b55b728badacbbe4a835
Author: spiff <[email protected]>
Date:   Mon Feb 28 11:47:20 2011 +0100

    [plugin.video.arretsurimages] updated to version 1.1.0

diff --git a/plugin.video.arretsurimages/addon.xml 
b/plugin.video.arretsurimages/addon.xml
index 068c0e5..567f8c2 100644
--- a/plugin.video.arretsurimages/addon.xml
+++ b/plugin.video.arretsurimages/addon.xml
@@ -1,11 +1,12 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="plugin.video.arretsurimages"
        name="Arrêt Sur Images"
-       version="1.0.3"
-       provider-name="Beenje">
+       version="1.1.0"
+       provider-name="beenje">
   <requires>
     <import addon="xbmc.python" version="1.0"/>
     <import addon="script.module.beautifulsoup" version="3.0.8"/>
+    <import addon="script.module.simplejson" version="2.0.10"/>
   </requires>
   <extension point="xbmc.python.pluginsource"
              library="default.py">
diff --git a/plugin.video.arretsurimages/changelog.txt 
b/plugin.video.arretsurimages/changelog.txt
index 0d0382b..b0b5f6f 100644
--- a/plugin.video.arretsurimages/changelog.txt
+++ b/plugin.video.arretsurimages/changelog.txt
@@ -1,3 +1,9 @@
+[B]Version 1.1.0[/B]
+
+- Retrieve HTML5 video instead of iPhone links: full length video now available
+- Add video quality setting
+- Add setting to hide the different parts and directly play the main video
+
 [B]Version 1.0.3[/B]
 
 - Fix crash on atv2 due to cookie handling
diff --git a/plugin.video.arretsurimages/resources/language/English/strings.xml 
b/plugin.video.arretsurimages/resources/language/English/strings.xml
index a61b6c8..98be904 100644
--- a/plugin.video.arretsurimages/resources/language/English/strings.xml
+++ b/plugin.video.arretsurimages/resources/language/English/strings.xml
@@ -32,9 +32,14 @@
     <string id="30090">Downloading</string>
     <string id="30091">Always Ask for Download Location</string>
     <string id="30092">Download Folder</string>
+    <string id="30100">Video</string>
+    <string id="30101">Quality</string>
+    <string id="30102">high</string>
+    <string id="30103">normal</string>
+    <string id="30105">Display all parts</string>
 
     <!--Context Menu-->
-    <string id="30100">Download Video</string>
+    <string id="30180">Download Video</string>
 
     <!--Download Menu-->
     <string id="30200">Download in progress</string>
diff --git a/plugin.video.arretsurimages/resources/language/French/strings.xml 
b/plugin.video.arretsurimages/resources/language/French/strings.xml
index 8295086..0656ee6 100644
--- a/plugin.video.arretsurimages/resources/language/French/strings.xml
+++ b/plugin.video.arretsurimages/resources/language/French/strings.xml
@@ -32,9 +32,14 @@
     <string id="30090">Téléchargement</string>
     <string id="30091">Toujours demander le dossier de 
téléchargement</string>
     <string id="30092">Dossier de téléchargement</string>
+    <string id="30100">Vidéo</string>
+    <string id="30101">Qualité</string>
+    <string id="30102">haute</string>
+    <string id="30103">normale</string>
+    <string id="30105">Afficher les actes</string>
 
     <!--Context Menu-->
-    <string id="30100">Télécharger la vidéo</string>
+    <string id="30180">Télécharger la vidéo</string>
 
     <!--Download Menu-->
     <string id="30200">Téléchargement en cours</string>
diff --git a/plugin.video.arretsurimages/resources/lib/asi.py 
b/plugin.video.arretsurimages/resources/lib/asi.py
index 401f899..7c7b9f8 100644
--- a/plugin.video.arretsurimages/resources/lib/asi.py
+++ b/plugin.video.arretsurimages/resources/lib/asi.py
@@ -12,6 +12,7 @@ from videoDownloader import Download
 URLEMISSION = 'http://www.arretsurimages.net/toutes-les-emissions.php'
 URLALLEMISSION = 'http://www.arretsurimages.net/emissions.php'
 SORTMETHOD = ['date_publication', 'nb_vues', 'nb_comments']
+QUALITY = ['stream_h264_hq_url', 'stream_h264_url']
 
 ASI = asi_scraper.ArretSurImages()
 
@@ -65,11 +66,18 @@ class UI:
             # Let xbmc know this can be played
             isFolder = False
             li.setProperty("IsPlayable", "true")
+        elif itemType == 'mainProgram':
+            # 'mainProgram' is the main video file that can be played directly
+            # Program can be downloaded -> add option to contextmenu
+            isFolder = False
+            li.setProperty("IsPlayable", "true")
+            contextmenu = [(getLS(30180), 'XBMC.RunPlugin(%s?download=%s)' % 
(sys.argv[0], urllib.quote_plus(info['url'])))]
+            li.addContextMenuItems(contextmenu, replaceItems=True)
         elif itemType == 'program':
-            # 'program' is a folder including video files
+            # 'program' is a folder including video files (main + parts)
             # Program can be downloaded -> add option to contextmenu
             isFolder = True
-            contextmenu = [(getLS(30100), 'XBMC.RunPlugin(%s?download=%s)' % 
(sys.argv[0], urllib.quote_plus(info['url'])))]
+            contextmenu = [(getLS(30180), 'XBMC.RunPlugin(%s?download=%s)' % 
(sys.argv[0], urllib.quote_plus(info['url'])))]
             li.addContextMenuItems(contextmenu, replaceItems=True)
         else:
             # itemType == 'folder'
@@ -77,9 +85,9 @@ class UI:
         # Add item to list
         ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=u, 
listitem=li, isFolder=isFolder)
 
-    def playVideo(self):
+    def playVideo(self, quality):
         """Play the video"""
-        video = ASI.getVideoDetails(self.main.args.url)
+        video = ASI.getVideoDetails(self.main.args.url, quality)
         li=xbmcgui.ListItem(video['Title'],
                             iconImage = self.main.args.icon,
                             thumbnailImage = self.main.args.icon,
@@ -87,6 +95,17 @@ class UI:
         li.setInfo(type='Video', infoLabels=video)
         xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, li)
 
+    def playMainVideo(self, quality):
+        """Directly play the main video (don't display all the available 
parts)"""
+        mainProgram = ASI.getProgramParts(self.main.args.url, 
self.main.args.name, self.main.args.icon)[0]
+        video = ASI.getVideoDetails(mainProgram['url'], quality)
+        li=xbmcgui.ListItem(video['Title'],
+                            iconImage = mainProgram['Thumb'],
+                            thumbnailImage = mainProgram['Thumb'],
+                            path = video['url'])
+        li.setInfo(type='Video', infoLabels=video)
+        xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, li)
+
     def navItems(self, navItems, mode):
         """Display navigation items"""
         if navItems['next']:
@@ -102,19 +121,25 @@ class UI:
         self.addItem({'Title':'D@ns le texte', 'mode':'dansLeTexte', 
'Plot':getLS(30033)})
         self.endofdirectory()
 
-    def programs(self, defaultUrl=None):
+    def programs(self, defaultUrl=None, displayParts=True):
         """Display all programs from self.main.args.url or defaultUrl"""
         newMode = 'parts'
         if self.main.args.url:
+            # url retrieved when navigating between pages (next/previous)
             programs = ASI.Programs(self.main.args.url)
         else:
+            # defaultUrl is passed to display the first page
             programs = ASI.Programs(defaultUrl)
+        if displayParts:
+            itemType = 'program'
+        else:
+            itemType = 'mainProgram'
         # Add nav items to the list
         self.navItems(programs.navItems, self.main.args.mode)
         # Add programs to the list
         for program in programs.getPrograms():
             program['mode'] = newMode
-            self.addItem(program, 'program')
+            self.addItem(program, itemType)
         # End the list
         self.endofdirectory()
 
@@ -122,7 +147,7 @@ class UI:
         """Display all parts of the selected program"""
         newMode = 'playVideo'
         # Add program parts to the list
-        for part in ASI.getProgramParts(self.main.args.url, 
self.main.args.name):
+        for part in ASI.getProgramParts(self.main.args.url, 
self.main.args.name, self.main.args.icon):
             part['mode'] = newMode
             self.addItem(part, 'video')
         # End the list
@@ -136,7 +161,7 @@ class Main:
         self.parseArgs()
         self.getSettings()
         # Check username and password have been set
-        if self.settings['username'] and self.settings['password']:
+        if self.username and self.password:
             if checkMode:
                 self.checkMode()
         else:
@@ -152,18 +177,19 @@ class Main:
             self.args = updateArgs(mode = 'None', url = 'None', name = 'None')
 
     def getSettings(self):
-        self.settings = dict()
-        self.settings['username'] = __addon__.getSetting('username')
-        self.settings['password'] = __addon__.getSetting('password')
-        self.settings['sortMethod'] = int(__addon__.getSetting('sortMethod'))
-        self.settings['downloadMode'] = __addon__.getSetting('downloadMode')
-        self.settings['downloadPath'] = __addon__.getSetting('downloadPath')
+        self.username = __addon__.getSetting('username')
+        self.password = __addon__.getSetting('password')
+        self.sortMethod = SORTMETHOD[int(__addon__.getSetting('sortMethod'))]
+        self.downloadMode = __addon__.getSetting('downloadMode')
+        self.downloadPath = __addon__.getSetting('downloadPath')
+        self.quality = QUALITY[int(__addon__.getSetting('quality'))]
+        self.displayParts = (__addon__.getSetting('displayParts') == 'true')
 
     def downloadVideo(self, url):
-        if self.settings['downloadMode'] == 'true':
+        if self.downloadMode == 'true':
             downloadPath = xbmcgui.Dialog().browse(3, getLS(30090), 'video')
         else:
-            downloadPath = self.settings['downloadPath']
+            downloadPath = self.downloadPath
         if downloadPath:
             video = ASI.getVideoDownloadLink(url)
             Download(video['Title'], video['url'], downloadPath)
@@ -174,24 +200,27 @@ class Main:
             # Try to login only if username isn't already logged in
             # (we don't have to login everytime as we use a cookie)
             # We only need to check that when starting the plugin
-            if ASI.isLoggedIn(self.settings['username']) or 
ASI.login(self.settings['username'], self.settings['password']):
+            if ASI.isLoggedIn(self.username) or ASI.login(self.username, 
self.password):
                 UI().showCategories()
             else:
                 xbmcgui.Dialog().ok(getLS(30050), getLS(30053))
         elif mode == 'toutesLesEmissions':
-            url = URLALLEMISSION + '?orderby=' + 
SORTMETHOD[self.settings['sortMethod']]  
-            UI().programs(url)
+            url = URLALLEMISSION + '?orderby=' + self.sortMethod
+            UI().programs(url, self.displayParts)
         elif mode == 'arretSurImages':
-            url = URLEMISSION + '?id=1' + '&orderby=' + 
SORTMETHOD[self.settings['sortMethod']]  
-            UI().programs(url)
+            url = URLEMISSION + '?id=1' + '&orderby=' + self.sortMethod
+            UI().programs(url, self.displayParts)
         elif mode == 'ligneJaune':
-            url = URLEMISSION + '?id=2' + '&orderby=' + 
SORTMETHOD[self.settings['sortMethod']]
-            UI().programs(url)
+            url = URLEMISSION + '?id=2' + '&orderby=' + self.sortMethod
+            UI().programs(url, self.displayParts)
         elif mode == 'dansLeTexte':
-            url = URLEMISSION + '?id=3' + '&orderby=' + 
SORTMETHOD[self.settings['sortMethod']]
-            UI().programs(url)
+            url = URLEMISSION + '?id=3' + '&orderby=' + self.sortMethod
+            UI().programs(url, self.displayParts)
         elif mode == 'parts':
-            UI().programParts()
+            if self.displayParts:
+                UI().programParts()
+            else:
+                UI().playMainVideo(self.quality)
         elif mode == 'playVideo':
-            UI().playVideo()
+            UI().playVideo(self.quality)
 
diff --git a/plugin.video.arretsurimages/resources/lib/asi_scraper.py 
b/plugin.video.arretsurimages/resources/lib/asi_scraper.py
index 71a9274..267a50e 100644
--- a/plugin.video.arretsurimages/resources/lib/asi_scraper.py
+++ b/plugin.video.arretsurimages/resources/lib/asi_scraper.py
@@ -1,6 +1,7 @@
 # -*- coding: utf-8 -*-
 import re
 import sys
+import simplejson
 from ClientForm import ParseResponse
 from util import getHTML, getUrllib2ResponseObject, cleanHTML
 from BeautifulSoup import SoupStrainer, MinimalSoup as BeautifulSoup
@@ -10,6 +11,7 @@ URLASI = 'http://www.arretsurimages.net'
 URLLOGIN = 'http://www.arretsurimages.net/forum/login.php'
 URLMONCOMPTE = 'http://www.arretsurimages.net/forum/control.php?panel=summary'
 IPHONEVIDEO = 'http://iphone.dailymotion.com/video/'
+JSONREQUEST = 
'http://www.dailymotion.com/json/video/%s?fields=title,thumbnail_url,stream_h264_hq_url,stream_h264_url'
 
 
 pluginName = sys.modules['__main__'].__plugin__
@@ -58,7 +60,7 @@ class ArretSurImages:
             print "bouton-telecharger.png not found"
         return {'Title':title, 'url':link}
 
-    def getVideoDetails(self, url):
+    def getIphoneVideoDetails(self, url):
         """Return the video title and link"""
         html = getHTML(url)
         soup = BeautifulSoup(html)
@@ -75,7 +77,7 @@ class ArretSurImages:
             link = 'None'
         return {'Title':title, 'url':link}
 
-    def getProgramParts(self, url, name):
+    def getIphoneProgramParts(self, url, name):
         """Return all parts of a program"""
         html = getHTML(url)
         soup = BeautifulSoup(html)
@@ -97,6 +99,58 @@ class ArretSurImages:
             parts.pop()
         return parts
 
+    def getVideoDetails(self, url, quality):
+        """Return the video title and real link"""
+        # Follow the swf link and get the video id from the answer
+        # (this works due to the iPad user-agent)
+        html = getHTML(url)
+        match = re.search("DM_Widget_Video_PlayerV4Html5\('(\w*)',", html)
+        if match:
+            videoId = match.group(1)
+            # Run the json request with the video id
+            request = getHTML(JSONREQUEST % videoId)
+            result = simplejson.loads(request)
+            link = result[quality]
+            title = result["title"]
+        else:
+            print "No video id found parsing swf link answer"
+            link = 'None'
+            title = 'None'
+        return {'Title':title, 'url':link}
+
+    def getProgramParts(self, url, name, icon):
+        """Return all parts of a program (swf links)
+
+        swf links allow to get HTML5 links with iPad user-agent"""
+        html = getHTML(url)
+        # Filter to avoid wrap-porte (La chronique porte) defined at the 
beginning
+        # of the html page
+        blocContainers = SoupStrainer(attrs = {'class':'contenu-html 
bg-page-contenu'})
+        soup = BeautifulSoup(html, parseOnlyThese = blocContainers)
+        parts = []
+        part = 0
+        # Get all movie links
+        for param in soup.findAll('param', attrs = {'name':'movie'}):
+            link = param["value"]
+            if part == 0:
+                # First link is the full video, just use the icon from 
previous page
+                title = name
+                thumb = icon
+            else:
+                title = name + ' - Acte %d' % part
+                # Try to get the icon linked to the iPhone video on that page
+                # That's much faster than getting it from the json request 
(see getVideoDetails),
+                # which would require 2 extra HTML requests for each part
+                try:
+                    media = param.parent.parent.find(text=re.compile(u'img 
src='))
+                    match = re.search(u'img src="(.*?)"', media)
+                    thumb = URLASI + match.group(1)
+                except (TypeError, AttributeError):
+                    thumb = icon
+            parts.append({'url':link, 'Title':title, 'Thumb':thumb})
+            part += 1
+        return parts
+
     def isLoggedIn(self, username):
         """Return True if @username is already logged in,
         False otherwise"""
diff --git a/plugin.video.arretsurimages/resources/lib/util.py 
b/plugin.video.arretsurimages/resources/lib/util.py
index c5f601f..e26a19b 100644
--- a/plugin.video.arretsurimages/resources/lib/util.py
+++ b/plugin.video.arretsurimages/resources/lib/util.py
@@ -8,7 +8,7 @@ import xbmc
 pluginName = sys.modules['__main__'].__plugin__
 
 
-def getHTML(url, cookiefile = 
xbmc.translatePath('special://temp/asi-cookies.lwp'), headers = [('User-Agent', 
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; fr-fr) AppleWebKit/531.22.7 
(KHTML, like Gecko) Version/4.0.5 Safari/531.22.7')]):
+def getHTML(url, cookiefile = 
xbmc.translatePath('special://temp/asi-cookies.lwp'), headers = [('User-Agent', 
'Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 
(KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10')]):
     """Return HTML from a given URL"""
     try:
         print '[%s] %s attempting to open %s with data' % (pluginName, 
__name__, url.get_full_url())
diff --git a/plugin.video.arretsurimages/resources/settings.xml 
b/plugin.video.arretsurimages/resources/settings.xml
index d1010f9..a13c7b0 100644
--- a/plugin.video.arretsurimages/resources/settings.xml
+++ b/plugin.video.arretsurimages/resources/settings.xml
@@ -14,4 +14,9 @@
         <setting id="downloadMode" type="bool" default="true" label="30091" />
         <setting id="downloadPath" type="folder" source="auto" default="" 
enable="eq(-1,false)" option="writeable" label="30092" />
     </category>
+    <!--Video-->
+    <category label="30100">
+        <setting id="quality" type="enum" label="30101" default="0" 
lvalues="30102|30103" />
+        <setting id="displayParts" type="bool" default="true" label="30105" />
+    </category>
 </settings>

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

Summary of changes:
 plugin.video.arretsurimages/addon.xml              |    5 +-
 plugin.video.arretsurimages/changelog.txt          |    6 ++
 .../resources/language/English/strings.xml         |    7 ++-
 .../resources/language/French/strings.xml          |    7 ++-
 plugin.video.arretsurimages/resources/lib/asi.py   |   83 +++++++++++++-------
 .../resources/lib/asi_scraper.py                   |   58 +++++++++++++-
 plugin.video.arretsurimages/resources/lib/util.py  |    2 +-
 plugin.video.arretsurimages/resources/settings.xml |    5 +
 8 files changed, 139 insertions(+), 34 deletions(-)


hooks/post-receive
-- 
Plugins

------------------------------------------------------------------------------
Free Software Download: Index, Search & Analyze Logs and other IT data in 
Real-Time with Splunk. Collect, index and harness all the fast moving IT data 
generated by your applications, servers and devices whether physical, virtual
or in the cloud. Deliver compliance at lower cost and gain new business 
insights. http://p.sf.net/sfu/splunk-dev2dev 
_______________________________________________
Xbmc-addons mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xbmc-addons

Reply via email to