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