The branch, eden has been updated
       via  d511fe322af6a6f4f2aed7b6586f5e396fc7f19d (commit)
       via  9bca0fee4a445c5619f53b3380b941fa5c5afbe6 (commit)
      from  3c1ffdd006e1c10e50757bd7e1959cbd8f123a0b (commit)

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

commit d511fe322af6a6f4f2aed7b6586f5e396fc7f19d
Author: amet <[email protected]>
Date:   Thu Apr 12 22:41:24 2012 +0400

    [script.tvguide] -v 1.3.4
    
    [B]Version 1.3.4 - 2012-04-11[/B]
    - Minor fixed from buggalo error reports
    
    [B]Version 1.3.3 - 2012-04-09[/B]
    - Fixed minor problems in Rapier skin
    - Improved handling of configuration errors (fx if XMLTV source file was 
removed)
    - Improved handling of invalid XMLTV source data
    
    [B]Version 1.3.2 - 2012-04-08[/B]
    - Accidentally released instead of 1.3.1 below.
    - Added initial version of Rapier skin support (thanks Lunatixz)

diff --git a/script.tvguide/addon.xml b/script.tvguide/addon.xml
index 100e59f..d9471bb 100644
--- a/script.tvguide/addon.xml
+++ b/script.tvguide/addon.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<addon id="script.tvguide" name="TV Guide" version="1.3.2" 
provider-name="twinther [[email protected]]">
+<addon id="script.tvguide" name="TV Guide" version="1.3.4" 
provider-name="twinther [[email protected]]">
     <requires>
         <import addon="xbmc.python" version="2.0"/>
         <import addon="script.module.simplejson" version="2.0.10"/>
diff --git a/script.tvguide/changelog.txt b/script.tvguide/changelog.txt
index b36cc36..e5990ec 100644
--- a/script.tvguide/changelog.txt
+++ b/script.tvguide/changelog.txt
@@ -1,5 +1,14 @@
-[B]Version 1.3.2 - 2012-xx-xx[/B]
-- Added initial version of rapier skin support (thanks Lunatixz)
+[B]Version 1.3.4 - 2012-04-11[/B]
+- Minor fixed from buggalo error reports
+
+[B]Version 1.3.3 - 2012-04-09[/B]
+- Fixed minor problems in Rapier skin
+- Improved handling of configuration errors (fx if XMLTV source file was 
removed)
+- Improved handling of invalid XMLTV source data
+
+[B]Version 1.3.2 - 2012-04-08[/B]
+- Accidentally released instead of 1.3.1 below.
+- Added initial version of Rapier skin support (thanks Lunatixz)
 
 [B]Version 1.3.1 - 2012-04-05[/B]
 - Fixed [I]foreign key constraint failed[/I] with certain XMLTV files
diff --git a/script.tvguide/gui.py b/script.tvguide/gui.py
index ebacc52..ab5f86b 100644
--- a/script.tvguide/gui.py
+++ b/script.tvguide/gui.py
@@ -77,6 +77,9 @@ class SourceInitializer(threading.Thread):
                 xbmc.log("[script.tvguide] Using source: %s" % 
str(type(source)), xbmc.LOGDEBUG)
                 self.sourceInitializedHandler.onSourceInitialized(source)
                 break
+            except src.SourceNotConfiguredException:
+                self.sourceInitializedHandler.onSourceNotConfigured()
+                break
             except src.SourceUpdateInProgressException, ex:
                 xbmc.log('[script.tvguide] database update in progress...: %s' 
% str(ex), xbmc.LOGDEBUG)
                 xbmc.sleep(1000)
@@ -438,7 +441,10 @@ class TVGuide(xbmcgui.WindowXML):
 
         self.getControl(self.C_MAIN_TITLE).setLabel('[B]%s[/B]' % 
program.title)
         self.getControl(self.C_MAIN_TIME).setLabel('[B]%s - %s[/B]' % 
(program.startDate.strftime(xbmc.getRegion('time')), 
program.endDate.strftime(xbmc.getRegion('time'))))
-        self.getControl(self.C_MAIN_DESCRIPTION).setText(program.description)
+        if program.description:
+            
self.getControl(self.C_MAIN_DESCRIPTION).setText(program.description)
+        else:
+            
self.getControl(self.C_MAIN_DESCRIPTION).setText(strings(NO_DESCRIPTION))
 
         if program.channel.logo is not None:
             self.getControl(self.C_MAIN_LOGO).setImage(program.channel.logo)
@@ -594,12 +600,7 @@ class TVGuide(xbmcgui.WindowXML):
             startTime += HALF_HOUR
 
         # channels
-        try:
-            channels = self.source.getChannelList()
-        except src.SourceException:
-            self.onEPGLoadError()
-            return
-
+        channels = self.source.getChannelList()
         if channelStart < 0:
             channelStart = len(channels) - 1
         elif channelStart > len(channels) - 1:
@@ -608,19 +609,14 @@ class TVGuide(xbmcgui.WindowXML):
         channelEnd = channelStart + CHANNELS_PER_PAGE
         self.channelIdx = channelStart
 
-        viewChannels = channels[channelStart : channelEnd]
-        try:
-            programs = self.source.getProgramList(viewChannels, 
self.viewStartDate)
-        except src.SourceException:
-            self.onEPGLoadError()
-            return
+        channelsToShow = channels[channelStart : channelEnd]
+        programs = self.source.getProgramList(channelsToShow, 
self.viewStartDate)
 
         if programs is None:
             self.onEPGLoadError()
             return
 
         # set channel logo or text
-        channelsToShow = channels[channelStart : channelEnd]
         for idx in range(0, CHANNELS_PER_PAGE):
             if idx >= len(channelsToShow):
                 self.getControl(4110 + idx).setImage('')
@@ -634,7 +630,7 @@ class TVGuide(xbmcgui.WindowXML):
                     self.getControl(4110 + idx).setImage('')
 
         for program in programs:
-            idx = viewChannels.index(program.channel)
+            idx = channelsToShow.index(program.channel)
 
             startDelta = program.startDate - self.viewStartDate
             stopDelta = program.endDate - self.viewStartDate
@@ -721,6 +717,12 @@ class TVGuide(xbmcgui.WindowXML):
         xbmcgui.Dialog().ok(strings(LOAD_ERROR_TITLE), 
strings(LOAD_ERROR_LINE1), strings(LOAD_ERROR_LINE2))
         self.close()
 
+    def onSourceNotConfigured(self):
+        self.redrawingEPG = False
+        self._hideControl(self.C_MAIN_LOADING)
+        xbmcgui.Dialog().ok(strings(LOAD_ERROR_TITLE), 
strings(LOAD_ERROR_LINE1), strings(CONFIGURATION_ERROR_LINE2))
+        self.close()
+
     def onSourceInitialized(self, source):
         self.source = source
         self.notification = Notification(self.source, 
ADDON.getAddonInfo('path'))
diff --git a/script.tvguide/resources/language/Danish/strings.xml 
b/script.tvguide/resources/language/Danish/strings.xml
index 072d240..bb6e6c2 100644
--- a/script.tvguide/resources/language/Danish/strings.xml
+++ b/script.tvguide/resources/language/Danish/strings.xml
@@ -31,7 +31,8 @@
 
     <string id="30150">Ups, det er pinligt!</string>
     <string id="30151">Det var ikke muligt at indlæse program data,</string>
-    <string id="30152">prøv igen senere...</string>
+    <string id="30152">kontroller indstillingerne eller prøv igen 
senere...</string>
+    <string id="30153">fordi indstillingerne er ugyldige!</string>
 
     <string id="30200">på [B]%s[/B] om 5 minutter...</string>
     <string id="30201">på [B]%s[/B] starter nu...</string>
diff --git a/script.tvguide/resources/language/English/strings.xml 
b/script.tvguide/resources/language/English/strings.xml
index 00f28af..a661bed 100644
--- a/script.tvguide/resources/language/English/strings.xml
+++ b/script.tvguide/resources/language/English/strings.xml
@@ -31,7 +31,8 @@
 
     <string id="30150">Oops, sorry about that!</string>
     <string id="30151">It was not possible to load program data,</string>
-    <string id="30152">please try again later...</string>
+    <string id="30152">check settings or try again later...</string>
+    <string id="30153">because the settings are invalid!</string>
 
     <string id="30200">on [B]%s[/B] in 5 minutes...</string>
     <string id="30201">on [B]%s[/B] is starting now...</string>
diff --git 
a/script.tvguide/resources/skins/Default/720p/script-tvguide-main.xml 
b/script.tvguide/resources/skins/Default/720p/script-tvguide-main.xml
index c129b1b..7bab9d2 100644
--- a/script.tvguide/resources/skins/Default/720p/script-tvguide-main.xml
+++ b/script.tvguide/resources/skins/Default/720p/script-tvguide-main.xml
@@ -68,7 +68,6 @@
                     <font>font13</font>
                     <align>center</align>
                     <aligny>center</aligny>
-                    <include>Red_Textcolor</include>
                 </control>
                 <control type="label" id="4001">
                     <description>1st half hour column</description>
@@ -329,7 +328,7 @@
                 <description>Program time</description>
                 <posx>900</posx>
                 <posy>510</posy>
-                <width>240</width>
+                <width>340</width>
                 <height>50</height>
                 <textcolor>ffffffff</textcolor>
                 <font>font13</font>
diff --git 
a/script.tvguide/resources/skins/skin.rapier/720p/script-tvguide-main.xml 
b/script.tvguide/resources/skins/skin.rapier/720p/script-tvguide-main.xml
index e368465..41bf58a 100644
--- a/script.tvguide/resources/skins/skin.rapier/720p/script-tvguide-main.xml
+++ b/script.tvguide/resources/skins/skin.rapier/720p/script-tvguide-main.xml
@@ -8,18 +8,6 @@
        </coordinates>
        <controls>
                <!-- Background -->
-               <control type="group" id="4600">
-                       <posx>0</posx>
-                       <posy>0</posy>
-                       <width>1280</width>
-                       <height>720</height>
-                       <include>BackgroundDefault</include>
-                       <include>BackgroundOpenCloseAnim</include>              
        
-            <fadetime>500</fadetime>
-            <animation type="Conditional" condition="!Control.IsVisible(5000)">
-                <effect type="fade" start="100" end="0" time="500" />
-            </animation>
-               </control>
                <control type="image">
             <posx>0</posx>
             <posy>0</posy>
@@ -31,6 +19,30 @@
             </animation>
         </control>
 
+        <control type="image" id="4600">
+            <description>Holds the program specific background 
image</description>
+            <posx>0</posx>
+            <posy>0</posy>
+            <width>1280</width>
+            <height>720</height>
+            <include>BackgroundDefault</include>
+            <include>BackgroundOpenCloseAnim</include>
+            <fadetime>500</fadetime>
+            <animation type="Conditional" condition="Control.IsVisible(5000)">
+                <effect type="fade" start="100" end="0" time="500" />
+            </animation>
+        </control>
+        <control type="image">
+            <posx>0</posx>
+            <posy>570</posy>
+            <width>1280</width>
+            <height>150</height>
+            <texture>tvguide-glasspane.png</texture>
+            <animation type="Conditional" 
condition="StringCompare(Control.GetLabel(4600),)">
+                <effect type="fade" start="100" end="0" time="500" />
+            </animation>
+        </control>
+
         <control type="label" id="5000">
             <description>visibility marker for TV Guide group</description>
         </control>
@@ -475,8 +487,8 @@
                                <description>Program description</description> 
                                <posx>185</posx>
                                <posy>635</posy>
-                               <width>960</width>
-                               <height>80</height>
+                               <width>880</width>
+                               <height>75</height>
                                <aspectratio aligny="top">keep</aspectratio>
                                <fadetime>500</fadetime> 
                                <scrollspeed>50</scrollspeed>
@@ -723,7 +735,7 @@
             <width>1280</width>
             <height>720</height>
             <animation type="Conditional" condition="!Control.IsVisible(5000)">
-                <effect type="zoom" end="25" center="1250,690" time="500" />
+                <effect type="zoom" end="13" center="1240,660" time="500" />
             </animation>
         </control>
 
diff --git a/script.tvguide/source.py b/script.tvguide/source.py
index c11841a..deac05a 100644
--- a/script.tvguide/source.py
+++ b/script.tvguide/source.py
@@ -94,6 +94,9 @@ class SourceUpdateInProgressException(SourceException):
 class SourceUpdateCanceledException(SourceException):
     pass
 
+class SourceNotConfiguredException(SourceException):
+    pass
+
 class Source(object):
     KEY = "undefined"
     STREAMS = {}
@@ -130,6 +133,8 @@ class Source(object):
 
     def close(self):
         #self.conn.rollback() # rollback any non-commit'ed changes to avoid 
database lock
+        if self.player.isPlaying():
+            self.player.stop()
         self.conn.close()
 
     def wasSettingsChanged(self, addon):
@@ -151,9 +156,10 @@ class Source(object):
 
         if settingsChanged or noRows:
             for key in SETTINGS_TO_CHECK:
-                c.execute('INSERT OR IGNORE INTO settings(key, value) VALUES 
(?, ?)', [key, addon.getSetting(key)])
+                value = addon.getSetting(key).decode('utf-8', 'ignore')
+                c.execute('INSERT OR IGNORE INTO settings(key, value) VALUES 
(?, ?)', [key, value])
                 if not c.rowcount:
-                    c.execute('UPDATE settings SET value=? WHERE key=?', 
[addon.getSetting(key), key])
+                    c.execute('UPDATE settings SET value=? WHERE key=?', 
[value, key])
             self.conn.commit()
 
         c.close()
@@ -198,7 +204,7 @@ class Source(object):
             c.execute("INSERT INTO updates(source, date, programs_updated) 
VALUES(?, ?, ?)", [self.KEY, dateStr, datetime.datetime.now()])
             updatesId = c.lastrowid
 
-            imported = 0
+            imported = imported_channels = imported_programs = 0
             for item in self.getDataFromExternal(date, progress_callback):
                 imported += 1
 
@@ -206,6 +212,7 @@ class Source(object):
                     self.conn.commit()
 
                 if isinstance(item, Channel):
+                    imported_channels += 1
                     channel = item
                     if not channel.streamUrl and 
self.playbackUsingDanishLiveTV and self.STREAMS.has_key(channel.id):
                         channel.streamUrl = self.STREAMS[channel.id]
@@ -214,6 +221,7 @@ class Source(object):
                         c.execute('UPDATE channels SET title=?, logo=?, 
stream_url=?, visible=?, weight=(CASE ? WHEN -1 THEN weight ELSE ? END) WHERE 
id=? AND source=?', [channel.title, channel.logo, channel.streamUrl, 
channel.visible, channel.weight, channel.weight, channel.id, self.KEY])
 
                 elif isinstance(item, Program):
+                    imported_programs += 1
                     program = item
                     if isinstance(program.channel, Channel):
                         channel = program.channel.id
@@ -227,6 +235,9 @@ class Source(object):
             c.execute("UPDATE sources SET channels_updated=? WHERE id=?", 
[datetime.datetime.now(),self.KEY])
             self.conn.commit()
 
+            if imported_channels == 0 or imported_programs == 0:
+                raise SourceException('No channels or programs imported')
+
         except SourceUpdateCanceledException:
             # force source update on next load
             c.execute('UPDATE sources SET channels_updated=? WHERE id=?', 
[datetime.datetime.fromtimestamp(0), self.KEY])
@@ -234,16 +245,22 @@ class Source(object):
             self.conn.commit()
 
         except Exception, ex:
-            self.conn.rollback()
-
             import traceback as tb
             import sys
             (type, value, traceback) = sys.exc_info()
             tb.print_exception(type, value, traceback)
 
-            # invalidate cached data
-            c.execute('UPDATE sources SET channels_updated=? WHERE id=?', 
[datetime.datetime.fromtimestamp(0), self.KEY])
-            self.conn.commit()
+            try:
+                self.conn.rollback()
+            except sqlite3.OperationalError:
+                pass # no transaction is active
+
+            try:
+                # invalidate cached data
+                c.execute('UPDATE sources SET channels_updated=? WHERE id=?', 
[datetime.datetime.fromtimestamp(0), self.KEY])
+                self.conn.commit()
+            except sqlite3.OperationalError:
+                pass # database is locked
 
             raise SourceException(ex)
         finally:
@@ -309,7 +326,10 @@ class Source(object):
     def _isChannelListCacheExpired(self):
         c = self.conn.cursor()
         c.execute('SELECT channels_updated FROM sources WHERE id=?', 
[self.KEY])
-        lastUpdated = c.fetchone()['channels_updated']
+        row = c.fetchone()
+        if not row:
+            return True
+        lastUpdated = row['channels_updated']
         c.close()
 
         today = datetime.datetime.now()
@@ -322,11 +342,13 @@ class Source(object):
         @type channel: source.Channel
         @return:
         """
+        program = None
         now = datetime.datetime.now()
         c = self.conn.cursor()
         c.execute('SELECT * FROM programs WHERE channel=? AND source=? AND 
start_date <= ? AND end_date >= ?', [channel.id, self.KEY, now, now])
         row = c.fetchone()
-        program = Program(channel, row['title'], row['start_date'], 
row['end_date'], row['description'], row['image_large'], row['image_small'])
+        if row:
+            program = Program(channel, row['title'], row['start_date'], 
row['end_date'], row['description'], row['image_large'], row['image_small'])
         c.close()
 
         return program
@@ -667,60 +689,26 @@ class XMLTVSource(Source):
         self.logoFolder = addon.getSetting('xmltv.logo.folder')
         self.xmlTvFileLastChecked = datetime.datetime.fromtimestamp(0)
 
+        if not addon.getSetting('xmltv.file') or not 
xbmcvfs.exists(addon.getSetting('xmltv.file')):
+            raise SourceNotConfiguredException()
+
         self.xmlTvFile = os.path.join(self.cachePath, '%s.xmltv' % self.KEY)
         tempFile = os.path.join(self.cachePath, '%s.xmltv.tmp' % self.KEY)
-        if xbmcvfs.exists(addon.getSetting('xmltv.file')):
-            xbmc.log('[script.tvguide] Caching XMLTV file...')
-            xbmcvfs.copy(addon.getSetting('xmltv.file'), tempFile)
+        xbmc.log('[script.tvguide] Caching XMLTV file...')
+        xbmcvfs.copy(addon.getSetting('xmltv.file'), tempFile)
 
-            # if xmlTvFile doesn't exists or the file size is different from 
tempFile
-            # we copy the tempFile to xmlTvFile which in turn triggers a 
reload in self._isChannelListCacheExpired(..)
-            if not os.path.exists(self.xmlTvFile) or 
os.path.getsize(self.xmlTvFile) != os.path.getsize(tempFile):
-                if os.path.exists(self.xmlTvFile):
-                    os.unlink(self.xmlTvFile)
-                os.rename(tempFile, self.xmlTvFile)
+        # if xmlTvFile doesn't exists or the file size is different from 
tempFile
+        # we copy the tempFile to xmlTvFile which in turn triggers a reload in 
self._isChannelListCacheExpired(..)
+        if not os.path.exists(self.xmlTvFile) or 
os.path.getsize(self.xmlTvFile) != os.path.getsize(tempFile):
+            if os.path.exists(self.xmlTvFile):
+                os.unlink(self.xmlTvFile)
+            os.rename(tempFile, self.xmlTvFile)
 
     def getDataFromExternal(self, date, progress_callback = None):
-        context, f, size = self._loadXml()
-        event, root = context.next()
-        elements_parsed = 0
-
-        for event, elem in context:
-            if event == "end":
-                result = None
-                if elem.tag == "programme":
-                    channel = elem.get("channel")
-                    description = elem.findtext("desc")
-                    iconElement = elem.find("icon")
-                    icon = None
-                    if iconElement is not None:
-                        icon = iconElement.get("src")
-                    if not description:
-                        description = strings(NO_DESCRIPTION)
-                    result = Program(channel, elem.findtext('title'), 
self._parseDate(elem.get('start')), self._parseDate(elem.get('stop')), 
description, imageSmall=icon)
-
-                elif elem.tag == "channel":
-                    id = elem.get("id")
-                    title = elem.findtext("display-name")
-                    logo = None
-                    if self.logoFolder:
-                        logoFile = os.path.join(self.logoFolder, title + 
'.png')
-                        if xbmcvfs.exists(logoFile):
-                            logo = logoFile
-                    if not logo:
-                        iconElement = elem.find("icon")
-                        if iconElement is not None:
-                            logo = iconElement.get("src")
-                    result = Channel(id, title, logo)
-
-                if result:
-                    elements_parsed += 1
-                    if progress_callback and elements_parsed % 500 == 0:
-                        if not progress_callback(100.0 / size * f.tell()):
-                            raise SourceUpdateCanceledException()
-                    yield result
-
-            root.clear()
+        size = os.path.getsize(self.xmlTvFile)
+        f = open(self.xmlTvFile, "rb")
+        context = ElementTree.iterparse(f, events=("start", "end"))
+        return parseXMLTV(context, f, size, self.logoFolder, progress_callback)
 
     def _isChannelListCacheExpired(self):
         """
@@ -733,43 +721,80 @@ class XMLTVSource(Source):
 
         c = self.conn.cursor()
         c.execute('SELECT channels_updated FROM sources WHERE id=?', 
[self.KEY])
-        lastUpdated = c.fetchone()['channels_updated']
+        row = c.fetchone()
+        if not row:
+            return True
+        lastUpdated = row['channels_updated']
         c.close()
 
         fileModified = 
datetime.datetime.fromtimestamp(os.path.getmtime(self.xmlTvFile))
         return fileModified > lastUpdated
 
-
     def _isProgramListCacheExpired(self, startTime):
         return self._isChannelListCacheExpired()
 
-    def _loadXml(self):
-        size = os.path.getsize(self.xmlTvFile)
-        f = open(self.xmlTvFile, "rb")
-        context = ElementTree.iterparse(f, events=("start", "end"))
-        return context, f, size
-
-    def _parseDate(self, dateString):
-        dateStringWithoutTimeZone = dateString[:-6]
-        t = time.strptime(dateStringWithoutTimeZone, '%Y%m%d%H%M%S')
-        return datetime.datetime(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, 
t.tm_min, t.tm_sec)
-
-
-class ONTVSource(XMLTVSource):
+class ONTVSource(Source):
     KEY = 'ontv'
 
     def __init__(self, addon, cachePath):
         super(ONTVSource, self).__init__(addon, cachePath)
         self.ontvUrl = addon.getSetting('ontv.url')
 
-    def _isChannelListCacheExpired(self):
-        return Source._isChannelListCacheExpired(self)
-
-    def _loadXml(self):
+    def getDataFromExternal(self, date, progress_callback = None):
         xml = self._downloadUrl(self.ontvUrl)
         io = StringIO.StringIO(xml)
         context = ElementTree.iterparse(io)
-        return context, io, len(xml)
+        return parseXMLTV(context, io, len(xml), None, progress_callback)
+
+    def _isProgramListCacheExpired(self, startTime):
+        return self._isChannelListCacheExpired()
+
+
+def parseXMLTVDate(dateString):
+    dateStringWithoutTimeZone = dateString[:-6]
+    t = time.strptime(dateStringWithoutTimeZone, '%Y%m%d%H%M%S')
+    return datetime.datetime(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, 
t.tm_min, t.tm_sec)
+
+def parseXMLTV(context, f, size, logoFolder, progress_callback):
+    event, root = context.next()
+    elements_parsed = 0
+
+    for event, elem in context:
+        if event == "end":
+            result = None
+            if elem.tag == "programme":
+                channel = elem.get("channel")
+                description = elem.findtext("desc")
+                iconElement = elem.find("icon")
+                icon = None
+                if iconElement is not None:
+                    icon = iconElement.get("src")
+                if not description:
+                    description = strings(NO_DESCRIPTION)
+                result = Program(channel, elem.findtext('title'), 
parseXMLTVDate(elem.get('start')), parseXMLTVDate(elem.get('stop')), 
description, imageSmall=icon)
+
+            elif elem.tag == "channel":
+                id = elem.get("id")
+                title = elem.findtext("display-name")
+                logo = None
+                if logoFolder:
+                    logoFile = os.path.join(logoFolder, title + '.png')
+                    if xbmcvfs.exists(logoFile):
+                        logo = logoFile
+                if not logo:
+                    iconElement = elem.find("icon")
+                    if iconElement is not None:
+                        logo = iconElement.get("src")
+                result = Channel(id, title, logo)
+
+            if result:
+                elements_parsed += 1
+                if progress_callback and elements_parsed % 500 == 0:
+                    if not progress_callback(100.0 / size * f.tell()):
+                        raise SourceUpdateCanceledException()
+                yield result
+
+        root.clear()
 
 
 def instantiateSource(addon):
diff --git a/script.tvguide/strings.py b/script.tvguide/strings.py
index 9e02b1c..ae05b16 100644
--- a/script.tvguide/strings.py
+++ b/script.tvguide/strings.py
@@ -37,6 +37,7 @@ DONE = 30105
 LOAD_ERROR_TITLE = 30150
 LOAD_ERROR_LINE1 = 30151
 LOAD_ERROR_LINE2 = 30152
+CONFIGURATION_ERROR_LINE2 = 30153
 
 NOTIFICATION_5_MINS = 30200
 NOTIFICATION_NOW = 30201

http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/scripts;a=commit;h=9bca0fee4a445c5619f53b3380b941fa5c5afbe6

commit 9bca0fee4a445c5619f53b3380b941fa5c5afbe6
Author: amet <[email protected]>
Date:   Thu Apr 12 22:38:57 2012 +0400

    [script.web.viewer] -0.8.6
    
    *** 0.8.6 ***
    
    Remove autoforms logging that could print passwords to the log in plain text
    Added logging of version and python version
    
    *** 0.8.5 ***
    
    Fixed a bug causing downloads to fail
    
    *** 0.8.4 ***
    
    Handle more complex <br /> tags
    Added Read View to sub-options menu (For viewing pages without selectable 
elements or with widely spaced selectable elements.
    Parse file:// out of links so they display properly in local links
    Fix for pages without elements
    
    *** 0.8.3 ***
    
    Fixed an autoforms bug which caused infinite loops when form failed and 
then redirected back to the same form.

diff --git a/script.web.viewer/addon.xml b/script.web.viewer/addon.xml
index d1aaab3..68f092f 100644
--- a/script.web.viewer/addon.xml
+++ b/script.web.viewer/addon.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="script.web.viewer"
        name="Web Viewer"
-       version="0.8.2"
+       version="0.8.6"
        provider-name="Rick Phillips (ruuk)">
   <requires>
     <import addon="xbmc.python" version="2.0"/>
diff --git a/script.web.viewer/changelog.txt b/script.web.viewer/changelog.txt
index fa2f946..f909eac 100644
--- a/script.web.viewer/changelog.txt
+++ b/script.web.viewer/changelog.txt
@@ -1,6 +1,26 @@
 Web Viewer Changelog
 
-Current Version : 0.8.2
+Current Version : 0.8.6
+
+*** 0.8.6 ***
+
+Remove autoforms logging that could print passwords to the log in plain text
+Added logging of version and python version
+
+*** 0.8.5 ***
+
+Fixed a bug causing downloads to fail
+
+*** 0.8.4 ***
+
+Handle more complex <br /> tags
+Added Read View to sub-options menu (For viewing pages without selectable 
elements or with widely spaced selectable elements.
+Parse file:// out of links so they display properly in local links
+Fix for pages without elements
+
+*** 0.8.3 ***
+
+Fixed an autoforms bug which caused infinite loops when form failed and then 
redirected back to the same form.
 
 *** 0.8.2 ***
 
diff --git a/script.web.viewer/lib/webviewer/htmltoxbmc.py 
b/script.web.viewer/lib/webviewer/htmltoxbmc.py
index c8bc1ca..e44706d 100644
--- a/script.web.viewer/lib/webviewer/htmltoxbmc.py
+++ b/script.web.viewer/lib/webviewer/htmltoxbmc.py
@@ -40,7 +40,7 @@ class HTMLConverter:
                self.lineItemFilter = 
re.compile('<(li|/li|ul|ol|/ul|/ol)[^>]*?>',re.I)
                self.ulFilter = re.compile('<ul[^>]*?>(.+?)</ul>',re.I)
                self.olFilter = re.compile('<ol[^>]*?>(.+?)</ol>',re.I)
-               self.brFilter = re.compile('<br[ /]{0,2}>',re.I)
+               self.brFilter = re.compile('<br[^>]*/{0,1}>',re.I)
                self.blockQuoteFilter = 
re.compile('<blockquote>(.+?)</blockquote>',re.S|re.I)
                self.colorFilter = re.compile('<font 
color="([^>"]+?)">(.+?)</font>',re.I)
                self.colorFilter2 = re.compile('<span[^>]*?style="[^>"]*?color: 
?([^>]+?)"[^>]*?>(.+?)</span>',re.I)
diff --git a/script.web.viewer/lib/webviewer/webviewer.py 
b/script.web.viewer/lib/webviewer/webviewer.py
index 7bd21f6..f06fa51 100644
--- a/script.web.viewer/lib/webviewer/webviewer.py
+++ b/script.web.viewer/lib/webviewer/webviewer.py
@@ -9,7 +9,7 @@ __plugin__ = 'Web Viewer'
 __author__ = 'ruuk (Rick Phillips)'
 __url__ = 'http://code.google.com/p/webviewer-xbmc/'
 __date__ = '01-19-2011'
-__version__ = '0.8.2'
+__version__ = '0.8.6'
 __addon__ = xbmcaddon.Addon(id='script.web.viewer')
 __language__ = __addon__.getLocalizedString
 
@@ -56,6 +56,8 @@ def ERROR(message):
 def LOG(message):
        print 'WEBVIEWER: %s' % ENCODE(str(message))
 
+LOG('Version: ' + __version__)
+LOG('Python Version: ' + sys.version)
 def clearDirFiles(filepath):
        if not os.path.exists(filepath): return
        for f in os.listdir(filepath):
@@ -260,6 +262,9 @@ class WebReader:
 class WebPage:
        def __init__(self, resData, id='', forms=[]):
                self.url = resData.url
+               end = ''
+               #if not '<a ' in resData.data and not '<img ' in resData.data 
and not '<form ' in resData.data: 
+               #       end = '<a href="#END">END OF PAGE</a><a 
name="#END"></a>'
                self.html = resData.data
                self.content = resData.content
                self.contentDisp = resData.contentDisp
@@ -287,6 +292,16 @@ class WebPage:
                        self.forms.append(Form(f, ct))
                        ct += 1
                if self.html: self.processPage()
+               #Fix for pages without elements
+               if not self.elements:
+                       element = Link(HC.linkFilter.search('<a href="#END">NO 
LINKS ON PAGE</a>'), self.url, 0)
+                       element.elementIndex = 0
+                       element.displayPageIndex = len(self._display)
+                       element.lineNumber = 
len(self.forDisplay().split('[CR]'))-1
+                       self._links.append(element)
+                       self.elements.append(element)
+                       self._display += 
HC.linkFilter.sub(HC.linkConvert,'[CR]<a href="#END"> </a>')
+                       self._displayWithIDs += 
HC.linkFilter.sub(HC.linkConvert,'[CR]<a href="#END"> </a>')
                
        def getFileName(self):
                fn_m = re.search('filename="([^"]*)"', self.contentDisp)
@@ -457,7 +472,7 @@ class WebPage:
                if name:
                        idx = 0
                        for f in self.forms:
-                               if name == f.form.name:
+                               if name == f.form.name or name == 
f.form.attrs.get('id'):
                                        if index != None:
                                                if index != idx: continue
                                        return f
@@ -577,21 +592,22 @@ class Link(PageElement, LinkBase):
                return self._isImage
 
 def fullURL(baseUrl, url):
-               if url.startswith('ftp://') or url.startswith('http://') or 
url.startswith('https://'): return url
-               pre = baseUrl.split('://', 1)[0] + '://'
-               if not url.startswith(pre):
-                       base = baseUrl.split('://', 1)[-1]
-                       base = base.rsplit('/', 1)[0]
-                       domain = base.split('/', 1)[0]
-                       if url.startswith('/'):
-                               if url.startswith('//'):
-                                       return pre.split('/', 1)[0] + url
-                               else:
-                                       return pre + domain + url
+       if url.startswith('ftp://') or url.startswith('http://') or 
url.startswith('https://') or url.startswith('file:/'): return url
+       if not (baseUrl.startswith('file://') or 
baseUrl.startswith('file:///')) and baseUrl.startswith('file:/'): baseUrl = 
baseUrl.replace('file:/','file:///')
+       pre = baseUrl.split('://', 1)[0] + '://'
+       if not url.startswith(pre):
+               base = baseUrl.split('://', 1)[-1]
+               base = base.rsplit('/', 1)[0]
+               domain = base.split('/', 1)[0]
+               if url.startswith('/'):
+                       if url.startswith('//'):
+                               url =  pre.split('/', 1)[0] + url
                        else:
-                               if not base.endswith('/'): base += '/'
-                               return pre + base + url
-               return url
+                               url =  pre + domain + url
+               else:
+                       if not base.endswith('/'): base += '/'
+                       url =  pre + base + url
+       return url
 
 class URLHistory:
        def __init__(self, first):
@@ -1490,7 +1506,6 @@ class ViewerWindow(BaseWindow):
                
                self.selectionChanged(self.pageList.getSelectedPosition(), -1)
                for fd in self.autoForms:
-                       LOG(fd)
                        f = self.page.getForm(url=fd.get('url'), 
name=fd.get('name'), action=fd.get('action'), index=fd.get('index'))
                        if f:
                                submit = fd.get('autosubmit') == 'true'
@@ -1504,9 +1519,10 @@ class ViewerWindow(BaseWindow):
                                xbmc.executebuiltin('ACTION(select)')
                                #self.showForm(f.form)
                                if submit:
+                                       self.autoForms = []
                                        self.form = f.form
                                        LOG('displayPage() - END - FORM SUBMIT')
-                                       self.submitForm(None)   
+                                       self.submitForm(None)
                                        return
                                break
                if self.autoClose:
@@ -1536,7 +1552,8 @@ class ViewerWindow(BaseWindow):
                self.getControl(150).reset()
                i = 0
                for url in self.page.imageURLs():
-                       url = fullURL(self.url, url)
+                       #Replace file:// so images display properly in xbmc
+                       url = fullURL(self.url, url).replace('file://','')
                        i += 1
                        item = xbmcgui.ListItem(self.imageReplace % (i, url), 
iconImage=url)
                        item.setProperty('url', url)
@@ -1642,6 +1659,7 @@ class ViewerWindow(BaseWindow):
                        
#xbmcgui.Dialog().ok(__language__(30052),__language__(30146),fname,__language__(30147)
 % ftype)
                
        def showImage(self, url):
+               LOG('SHOWING IMAGE: ' + url)
                base = 
os.path.join(xbmc.translatePath(__addon__.getAddonInfo('profile')), 
'imageviewer')
                if not os.path.exists(base): os.makedirs(base)
                clearDirFiles(base)
@@ -1804,7 +1822,7 @@ class ViewerWindow(BaseWindow):
        def downloadLink(self, url, fname=None):
                base = xbmcgui.Dialog().browse(3, __language__(30128), 'files')
                if not base: return
-               fname, ftype = 
Downloader(message=__language__(30129)).downloadURL(base, url, fname, 
open=WR.browser.open)
+               fname, ftype = 
Downloader(message=__language__(30129)).downloadURL(base, url, fname, 
opener=WR.browser.open)
                if not fname: return
                xbmcgui.Dialog().ok(__language__(30109), __language__(30130), 
fname, __language__(30115) % ftype)
                
@@ -1863,7 +1881,7 @@ class ViewerWindow(BaseWindow):
                
        def settings(self):
                dialog = xbmcgui.Dialog()
-               idx = dialog.select(__language__(30110), [__language__(30133), 
__language__(30142), __language__(30157)])
+               idx = dialog.select(__language__(30110), [__language__(30133), 
__language__(30142), __language__(30157), __language__(30162)])
                if idx < 0: return
                
                if idx == 0:
@@ -1873,6 +1891,8 @@ class ViewerWindow(BaseWindow):
                        xbmcgui.Dialog().ok(__language__(30109), 
__language__(30143), self.page.getTitle())
                elif idx == 2:
                        self.viewPageSource()
+               elif idx == 3:
+                       self.viewReadMode()
        
        def openSettings(self):
                __addon__.openSettings()
@@ -1889,6 +1909,11 @@ class ViewerWindow(BaseWindow):
                w.doModal()
                del w
                
+       def viewReadMode(self):
+               w = SourceDialog("script-webviewer-source.xml" , 
__addon__.getAddonInfo('path'), THEME, source=self.page.forDisplay())
+               w.doModal()
+               del w
+               
        def tagConvert(self, m):
                ret = re.sub('[\n\r]', '', m.group(0))
                #ret = re.sub('[\'"][^"]*?[\'"]','[COLOR 
FF007700]\g<0>[/COLOR]',ret)
diff --git a/script.web.viewer/resources/language/English/strings.xml 
b/script.web.viewer/resources/language/English/strings.xml
index a951768..876b580 100644
--- a/script.web.viewer/resources/language/English/strings.xml
+++ b/script.web.viewer/resources/language/English/strings.xml
@@ -74,5 +74,6 @@
     <string id="30159">Forward</string>
     <string id="30160">Refresh</string>
     <string id="30161">Exit Web Viewer</string>
+    <string id="30162">Read View</string>
 
 </strings>

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

Summary of changes:
 script.tvguide/addon.xml                           |    2 +-
 script.tvguide/changelog.txt                       |   13 ++-
 script.tvguide/clear_cache.py                      |   45 -----
 script.tvguide/gui.py                              |   32 ++--
 .../resources/language/Danish/strings.xml          |    3 +-
 .../resources/language/English/strings.xml         |    3 +-
 .../skins/Default/720p/script-tvguide-main.xml     |    3 +-
 .../skins/skin.rapier/720p/script-tvguide-main.xml |   42 +++--
 script.tvguide/source.py                           |  183 +++++++++++---------
 script.tvguide/strings.py                          |    1 +
 script.web.viewer/addon.xml                        |    2 +-
 script.web.viewer/changelog.txt                    |   22 +++-
 script.web.viewer/lib/webviewer/htmltoxbmc.py      |    2 +-
 script.web.viewer/lib/webviewer/webviewer.py       |   67 +++++---
 .../resources/language/English/strings.xml         |    1 +
 15 files changed, 236 insertions(+), 185 deletions(-)
 delete mode 100644 script.tvguide/clear_cache.py


hooks/post-receive
-- 
Scripts

------------------------------------------------------------------------------
For Developers, A Lot Can Happen In A Second.
Boundary is the first to Know...and Tell You.
Monitor Your Applications in Ultra-Fine Resolution. Try it FREE!
http://p.sf.net/sfu/Boundary-d2dvs2
_______________________________________________
Xbmc-addons mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xbmc-addons

Reply via email to