summaryrefslogtreecommitdiff
path: root/plugin.video.mediathekview/resources/lib
diff options
context:
space:
mode:
Diffstat (limited to 'plugin.video.mediathekview/resources/lib')
-rw-r--r--plugin.video.mediathekview/resources/lib/base/Logger.py2
-rw-r--r--plugin.video.mediathekview/resources/lib/channelui.py22
-rw-r--r--plugin.video.mediathekview/resources/lib/exceptions.py3
-rw-r--r--plugin.video.mediathekview/resources/lib/filmui.py13
-rw-r--r--plugin.video.mediathekview/resources/lib/initialui.py18
-rw-r--r--plugin.video.mediathekview/resources/lib/kodi/KodiAddon.py52
-rw-r--r--plugin.video.mediathekview/resources/lib/kodi/KodiUI.py40
-rw-r--r--plugin.video.mediathekview/resources/lib/mvupdate.py6
-rw-r--r--plugin.video.mediathekview/resources/lib/mvutils.py56
-rw-r--r--plugin.video.mediathekview/resources/lib/notifier.py15
-rw-r--r--plugin.video.mediathekview/resources/lib/settings.py2
-rw-r--r--plugin.video.mediathekview/resources/lib/showui.py39
-rw-r--r--plugin.video.mediathekview/resources/lib/storemysql.py136
-rw-r--r--plugin.video.mediathekview/resources/lib/storesqlite.py129
-rw-r--r--plugin.video.mediathekview/resources/lib/ttml2srt.py6
-rw-r--r--plugin.video.mediathekview/resources/lib/updater.py48
16 files changed, 404 insertions, 183 deletions
diff --git a/plugin.video.mediathekview/resources/lib/base/Logger.py b/plugin.video.mediathekview/resources/lib/base/Logger.py
index 3d74680..850ff44 100644
--- a/plugin.video.mediathekview/resources/lib/base/Logger.py
+++ b/plugin.video.mediathekview/resources/lib/base/Logger.py
@@ -28,6 +28,6 @@ class Logger( object ):
def warn( self, message, *args ):
pass
-
+
def error( self, message, *args ):
pass
diff --git a/plugin.video.mediathekview/resources/lib/channelui.py b/plugin.video.mediathekview/resources/lib/channelui.py
index 36743e8..fc9d826 100644
--- a/plugin.video.mediathekview/resources/lib/channelui.py
+++ b/plugin.video.mediathekview/resources/lib/channelui.py
@@ -3,17 +3,19 @@
#
# -- Imports ------------------------------------------------
-import sys, urllib
-import xbmcplugin, xbmcgui
+import xbmcgui
+import xbmcplugin
+
+import resources.lib.mvutils as mvutils
from resources.lib.channel import Channel
# -- Classes ------------------------------------------------
class ChannelUI( Channel ):
- def __init__( self, handle, sortmethods = None, nextdir = 'initial' ):
- self.base_url = sys.argv[0]
+ def __init__( self, plugin, sortmethods = None, nextdir = 'initial' ):
+ self.plugin = plugin
+ self.handle = plugin.addon_handle
self.nextdir = nextdir
- self.handle = handle
self.sortmethods = sortmethods if sortmethods is not None else [ xbmcplugin.SORT_METHOD_TITLE ]
self.count = 0
@@ -24,9 +26,14 @@ class ChannelUI( Channel ):
def Add( self, altname = None ):
resultingname = self.channel if self.count == 0 else '%s (%d)' % ( self.channel, self.count, )
li = xbmcgui.ListItem( label = resultingname if altname is None else altname )
+ icon = 'special://home/addons/' + self.plugin.addon_id + '/resources/icons/' + self.channel.lower() + '-m.png'
+ li.setArt( {
+ 'thumb': icon,
+ 'icon': icon
+ } )
xbmcplugin.addDirectoryItem(
handle = self.handle,
- url = self.build_url( {
+ url = mvutils.build_url( {
'mode': self.nextdir,
'channel': self.id
} ),
@@ -36,6 +43,3 @@ class ChannelUI( Channel ):
def End( self ):
xbmcplugin.endOfDirectory( self.handle )
-
- def build_url( self, query ):
- return self.base_url + '?' + urllib.urlencode( query )
diff --git a/plugin.video.mediathekview/resources/lib/exceptions.py b/plugin.video.mediathekview/resources/lib/exceptions.py
index 53d7f14..b66fb4f 100644
--- a/plugin.video.mediathekview/resources/lib/exceptions.py
+++ b/plugin.video.mediathekview/resources/lib/exceptions.py
@@ -7,3 +7,6 @@ class DatabaseCorrupted( RuntimeError ):
class DatabaseLost( RuntimeError ):
"""This exception is raised when the connection to the database is lost during update"""
+
+class ExitRequested( Exception ):
+ """This exception is thrown if the addon is shut down by Kodi or by another same addon"""
diff --git a/plugin.video.mediathekview/resources/lib/filmui.py b/plugin.video.mediathekview/resources/lib/filmui.py
index af04798..23eaf98 100644
--- a/plugin.video.mediathekview/resources/lib/filmui.py
+++ b/plugin.video.mediathekview/resources/lib/filmui.py
@@ -3,7 +3,8 @@
#
# -- Imports ------------------------------------------------
-import xbmcplugin, xbmcgui
+import xbmcgui
+import xbmcplugin
from resources.lib.film import Film
from resources.lib.settings import Settings
@@ -45,7 +46,7 @@ class FilmUI( Film ):
infoLabels = {
'title' : resultingtitle + videohds,
- 'sorttitle' : resultingtitle,
+ 'sorttitle' : resultingtitle.lower(),
'tvshowtitle' : self.show,
'plot' : self.description
}
@@ -63,9 +64,15 @@ class FilmUI( Film ):
infoLabels['aired'] = airedstring
infoLabels['dateadded'] = airedstring
- li = xbmcgui.ListItem( resultingtitle, self.description )
+ icon = 'special://home/addons/' + self.plugin.addon_id + '/resources/icons/' + self.channel.lower() + '-m.png'
+
+ li = xbmcgui.ListItem( resultingtitle )
li.setInfo( type = 'video', infoLabels = infoLabels )
li.setProperty( 'IsPlayable', 'true' )
+ li.setArt( {
+ 'thumb': icon,
+ 'icon': icon
+ } )
# create context menu
contextmenu = []
diff --git a/plugin.video.mediathekview/resources/lib/initialui.py b/plugin.video.mediathekview/resources/lib/initialui.py
index 71d9aef..b59d409 100644
--- a/plugin.video.mediathekview/resources/lib/initialui.py
+++ b/plugin.video.mediathekview/resources/lib/initialui.py
@@ -3,13 +3,16 @@
#
# -- Imports ------------------------------------------------
-import sys, urllib
-import xbmcplugin, xbmcgui
+import xbmcgui
+import xbmcplugin
+
+import resources.lib.mvutils as mvutils
# -- Classes ------------------------------------------------
class InitialUI( object ):
- def __init__( self, handle, sortmethods = None ):
- self.handle = handle
+ def __init__( self, plugin, sortmethods = None ):
+ self.plugin = plugin
+ self.handle = plugin.addon_handle
self.sortmethods = sortmethods if sortmethods is not None else [ xbmcplugin.SORT_METHOD_TITLE ]
self.channelid = 0
self.initial = ''
@@ -28,7 +31,7 @@ class InitialUI( object ):
li = xbmcgui.ListItem( label = resultingname )
xbmcplugin.addDirectoryItem(
handle = self.handle,
- url = _build_url( {
+ url = mvutils.build_url( {
'mode': "shows",
'channel': self.channelid,
'initial': self.initial,
@@ -40,8 +43,3 @@ class InitialUI( object ):
def End( self ):
xbmcplugin.endOfDirectory( self.handle )
-
-# -- Functions ----------------------------------------------
-
-def _build_url( query ):
- return sys.argv[0] + '?' + urllib.urlencode( query )
diff --git a/plugin.video.mediathekview/resources/lib/kodi/KodiAddon.py b/plugin.video.mediathekview/resources/lib/kodi/KodiAddon.py
index f9c0cd7..4081044 100644
--- a/plugin.video.mediathekview/resources/lib/kodi/KodiAddon.py
+++ b/plugin.video.mediathekview/resources/lib/kodi/KodiAddon.py
@@ -3,14 +3,19 @@
#
# -- Imports ------------------------------------------------
-import sys, urllib
-import xbmc, xbmcgui, xbmcaddon, xbmcplugin
+import os
+import sys
+import urllib
+
+import xbmc
+import xbmcgui
+import xbmcaddon
+import xbmcplugin
from resources.lib.kodi.KodiLogger import KodiLogger
# -- Classes ------------------------------------------------
class KodiAddon( KodiLogger ):
-
def __init__( self ):
self.addon = xbmcaddon.Addon()
self.addon_id = self.addon.getAddonInfo( 'id' )
@@ -29,6 +34,7 @@ class KodiAddon( KodiLogger ):
return self.addon.setSetting( setting_id, value )
def doAction( self, action ):
+ self.debug( 'Triggered action {}', action )
xbmc.executebuiltin( 'Action({})'.format( action ) )
class KodiService( KodiAddon ):
@@ -66,3 +72,43 @@ class KodiPlugin( KodiAddon ):
def endOfDirectory( self, succeeded = True, updateListing = False, cacheToDisc = True ):
xbmcplugin.endOfDirectory( self.addon_handle, succeeded, updateListing, cacheToDisc )
+
+
+class KodiInterlockedMonitor( xbmc.Monitor ):
+ def __init__( self, service, setting_id ):
+ super( KodiInterlockedMonitor, self ).__init__()
+ self.instance_id = ''.join( format( x, '02x' ) for x in bytearray( os.urandom( 16 ) ) )
+ self.setting_id = setting_id
+ self.service = service
+
+ def RegisterInstance( self, waittime = 1 ):
+ if self.BadInstance():
+ self.service.info( 'Found other instance with id {}', self.instance_id )
+ self.service.info( 'Startup delayed by {} second(s) waiting the other instance to shut down', waittime )
+ self.service.setSetting( self.setting_id, self.instance_id )
+ xbmc.Monitor.waitForAbort( self, waittime )
+ else:
+ self.service.setSetting( self.setting_id, self.instance_id )
+
+ def UnregisterInstance( self ):
+ self.service.setSetting( self.setting_id, '' )
+
+ def BadInstance( self ):
+ instance_id = self.service.getSetting( self.setting_id )
+ return len( instance_id ) > 0 and self.instance_id != instance_id
+
+ def abortRequested( self ):
+ return self.BadInstance() or xbmc.Monitor.abortRequested( self )
+
+ def waitForAbort( self, timeout = None ):
+ if timeout is None:
+ # infinite wait
+ while not self.abortRequested():
+ if xbmc.Monitor.waitForAbort( self, 1 ):
+ return True
+ return True
+ else:
+ for _ in range( timeout ):
+ if self.BadInstance() or xbmc.Monitor.waitForAbort( self, 1 ):
+ return True
+ return self.BadInstance()
diff --git a/plugin.video.mediathekview/resources/lib/kodi/KodiUI.py b/plugin.video.mediathekview/resources/lib/kodi/KodiUI.py
index dee8dbb..138af50 100644
--- a/plugin.video.mediathekview/resources/lib/kodi/KodiUI.py
+++ b/plugin.video.mediathekview/resources/lib/kodi/KodiUI.py
@@ -3,15 +3,21 @@
#
# -- Imports ------------------------------------------------
-import xbmc, xbmcgui
+import xbmc
+import xbmcgui
+import xbmcaddon
# -- Classes ------------------------------------------------
class KodiUI( object ):
def __init__( self ):
- self.bgdialog = None
+ self.addon = xbmcaddon.Addon()
+ self.language = self.addon.getLocalizedString
+ self.bgdialog = KodiBGDialog()
- def GetEnteredText( self, deftext = '', heading = '', hidden = False ):
+ def GetEnteredText( self, deftext = None, heading = None, hidden = False ):
+ heading = self.language( heading ) if isinstance( heading, int ) else heading if heading is not None else ''
+ deftext = self.language( deftext ) if isinstance( deftext, int ) else deftext if deftext is not None else ''
keyboard = xbmc.Keyboard( deftext, heading, 1 if hidden else 0 )
keyboard.doModal()
if keyboard.isConfirmed():
@@ -19,39 +25,39 @@ class KodiUI( object ):
return deftext
def ShowNotification( self, heading, message, icon = xbmcgui.NOTIFICATION_INFO, time = 5000, sound = True ):
+ heading = self.language( heading ) if isinstance( heading, int ) else heading
+ message = self.language( message ) if isinstance( message, int ) else message
xbmcgui.Dialog().notification( heading, message, icon, time, sound )
def ShowWarning( self, heading, message, time = 5000, sound = True ):
- xbmcgui.Dialog().notification( heading, message, xbmcgui.NOTIFICATION_WARNING, time, sound )
+ self.ShowNotification( heading, message, xbmcgui.NOTIFICATION_WARNING, time, sound )
def ShowError( self, heading, message, time = 5000, sound = True ):
- xbmcgui.Dialog().notification( heading, message, xbmcgui.NOTIFICATION_ERROR, time, sound )
+ self.ShowNotification( heading, message, xbmcgui.NOTIFICATION_ERROR, time, sound )
def ShowBGDialog( self, heading = None, message = None ):
- if self.bgdialog is None:
- self.bgdialog = xbmcgui.DialogProgressBG()
- self.bgdialog.create( heading, message )
- else:
- self.bgdialog.update( 0, heading, message )
+ self.bgdialog.Create( heading, message )
def UpdateBGDialog( self, percent, heading = None, message = None ):
- if self.bgdialog is not None:
- self.bgdialog.update( percent, heading, message )
+ self.bgdialog.Update( percent, heading, message )
+
+ def HookBGDialog( self, blockcount, blocksize, totalsize ):
+ self.bgdialog.UrlRetrieveHook( blockcount, blocksize, totalsize )
def CloseBGDialog( self ):
- if self.bgdialog is not None:
- self.bgdialog.close()
- del self.bgdialog
- self.bgdialog = None
+ self.bgdialog.Close()
class KodiBGDialog( object ):
def __init__( self ):
+ self.language = xbmcaddon.Addon().getLocalizedString
self.bgdialog= None
def __del__( self ):
self.Close()
def Create( self, heading = None, message = None ):
+ heading = self.language( heading ) if isinstance( heading, int ) else heading
+ message = self.language( message ) if isinstance( message, int ) else message
if self.bgdialog is None:
self.bgdialog = xbmcgui.DialogProgressBG()
self.bgdialog.create( heading, message )
@@ -60,6 +66,8 @@ class KodiBGDialog( object ):
def Update( self, percent, heading = None, message = None ):
if self.bgdialog is not None:
+ heading = self.language( heading ) if isinstance( heading, int ) else heading
+ message = self.language( message ) if isinstance( message, int ) else message
self.bgdialog.update( percent, heading, message )
def UrlRetrieveHook( self, blockcount, blocksize, totalsize ):
diff --git a/plugin.video.mediathekview/resources/lib/mvupdate.py b/plugin.video.mediathekview/resources/lib/mvupdate.py
index 7595417..477139e 100644
--- a/plugin.video.mediathekview/resources/lib/mvupdate.py
+++ b/plugin.video.mediathekview/resources/lib/mvupdate.py
@@ -6,7 +6,7 @@ import os
import sys
import argparse
import datetime
-import xml.etree.ElementTree as ET
+import defusedxml.ElementTree as ET
from resources.lib.base.Logger import Logger
from resources.lib.updater import MediathekViewUpdater
@@ -24,6 +24,8 @@ class Settings( object ):
self.database = args.database
self.nofuture = True
self.minlength = 0
+ self.maxage = 86400
+ self.recentmode = 0
self.groupshows = False
self.updenabled = True
self.updinterval = 3600
@@ -104,6 +106,8 @@ class Notifier( object ):
pass
def UpdateUpdateProgress( self, percent, count, channels, shows, movies ):
pass
+ def HookDownloadProgress( self, blockcount, blocksize, totalsize ):
+ pass
def CloseUpdateProgress( self ):
pass
diff --git a/plugin.video.mediathekview/resources/lib/mvutils.py b/plugin.video.mediathekview/resources/lib/mvutils.py
index d4c7663..7ccaf3a 100644
--- a/plugin.video.mediathekview/resources/lib/mvutils.py
+++ b/plugin.video.mediathekview/resources/lib/mvutils.py
@@ -3,12 +3,21 @@
# -- Imports ------------------------------------------------
import os
+import sys
import stat
import string
+import urllib
import urllib2
-import xbmcvfs
from contextlib import closing
+from resources.lib.exceptions import ExitRequested
+
+# -- Kodi Specific Imports ----------------------------------
+try:
+ import xbmcvfs
+ is_kodi = True
+except ImportError:
+ is_kodi = False
# -- Functions ----------------------------------------------
def dir_exists( name ):
@@ -58,30 +67,29 @@ def cleanup_filename( val ):
search = ''.join( [ c for c in val if c in cset ] )
return search.strip()
-def url_retrieve( url, filename, reporthook, chunk_size = 8192 ):
+def url_retrieve( url, filename, reporthook, chunk_size = 8192, aborthook = None ):
with closing( urllib2.urlopen( url ) ) as u, closing( open( filename, 'wb' ) ) as f:
- total_size = int( u.info().getheader( 'Content-Length' ).strip() ) if u.info() and u.info().getheader( 'Content-Length' ) else 0
- total_chunks = 0
+ _chunked_url_copier( u, f, reporthook, chunk_size, aborthook )
+
+def url_retrieve_vfs( url, filename, reporthook, chunk_size = 8192, aborthook = None ):
+ with closing( urllib2.urlopen( url ) ) as u, closing( xbmcvfs.File( filename, 'wb' ) ) as f:
+ _chunked_url_copier( u, f, reporthook, chunk_size, aborthook )
- while True:
- reporthook( total_chunks, chunk_size, total_size )
- chunk = u.read( chunk_size )
- if not chunk:
- break
- f.write( chunk )
- total_chunks += 1
- return ( filename, [], )
+def build_url( query ):
+ return sys.argv[0] + '?' + urllib.urlencode( query )
-def url_retrieve_vfs( videourl, filename, reporthook, chunk_size = 8192 ):
- with closing( urllib2.urlopen( videourl ) ) as u, closing( xbmcvfs.File( filename, 'wb' ) ) as f:
- total_size = int( u.info().getheader( 'Content-Length' ).strip() ) if u.info() and u.info().getheader( 'Content-Length' ) else 0
- total_chunks = 0
+def _chunked_url_copier( u, f, reporthook, chunk_size, aborthook ):
+ aborthook = aborthook if aborthook is not None else lambda: False
+ total_size = int( u.info().getheader( 'Content-Length' ).strip() ) if u.info() and u.info().getheader( 'Content-Length' ) else 0
+ total_chunks = 0
- while True:
- reporthook( total_chunks, chunk_size, total_size )
- chunk = u.read( chunk_size )
- if not chunk:
- break
- f.write( chunk )
- total_chunks += 1
- return ( filename, [], )
+ while not aborthook():
+ reporthook( total_chunks, chunk_size, total_size )
+ chunk = u.read( chunk_size )
+ if not chunk:
+ # operation has finished
+ return
+ f.write( chunk )
+ total_chunks += 1
+ # abort requested
+ raise ExitRequested( 'Reception interrupted.' )
diff --git a/plugin.video.mediathekview/resources/lib/notifier.py b/plugin.video.mediathekview/resources/lib/notifier.py
index d257a52..517da9e 100644
--- a/plugin.video.mediathekview/resources/lib/notifier.py
+++ b/plugin.video.mediathekview/resources/lib/notifier.py
@@ -14,28 +14,31 @@ class Notifier( KodiUI ):
self.language = xbmcaddon.Addon().getLocalizedString
def ShowDatabaseError( self, err ):
- self.ShowError( self.language( 30951 ), '{}'.format( err ) )
+ self.ShowError( 30951, '{}'.format( err ) )
def ShowDownloadError( self, name, err ):
- self.ShowError( self.language( 30952 ), self.language( 30953 ).format( name, err ) )
+ self.ShowError( 30952, self.language( 30953 ).format( name, err ) )
def ShowMissingExtractorError( self ):
- self.ShowError( self.language( 30952 ), self.language( 30954 ), time = 10000 )
+ self.ShowError( 30952, 30954, time = 10000 )
def ShowLimitResults( self, maxresults ):
- self.ShowNotification( self.language( 30980 ), self.language( 30981 ).format( maxresults ) )
+ self.ShowNotification( 30980, self.language( 30981 ).format( maxresults ) )
def ShowDownloadProgress( self ):
- self.ShowBGDialog( self.language( 30955 ) )
+ self.ShowBGDialog( 30955 )
def UpdateDownloadProgress( self, percent, message = None ):
self.UpdateBGDialog( percent, message = message )
+ def HookDownloadProgress( self, blockcount, blocksize, totalsize ):
+ self.HookBGDialog( blockcount, blocksize, totalsize )
+
def CloseDownloadProgress( self ):
self.CloseBGDialog()
def ShowUpdateProgress( self ):
- self.ShowBGDialog( self.language( 30956 ) )
+ self.ShowBGDialog( 30956 )
def UpdateUpdateProgress( self, percent, count, channels, shows, movies ):
message = self.language( 30957 ) % ( count, channels, shows, movies )
diff --git a/plugin.video.mediathekview/resources/lib/settings.py b/plugin.video.mediathekview/resources/lib/settings.py
index 32bd95a..13d86e0 100644
--- a/plugin.video.mediathekview/resources/lib/settings.py
+++ b/plugin.video.mediathekview/resources/lib/settings.py
@@ -19,6 +19,8 @@ class Settings( object ):
self.minlength = int( float( self.addon.getSetting( 'minlength' ) ) ) * 60
self.groupshows = self.addon.getSetting( 'groupshows' ) == 'true'
self.maxresults = int( self.addon.getSetting( 'maxresults' ) )
+ self.maxage = int( self.addon.getSetting( 'maxage' ) ) * 86400
+ self.recentmode = int( self.addon.getSetting( 'recentmode' ) )
self.downloadpath = self.addon.getSetting( 'downloadpath' )
self.type = self.addon.getSetting( 'dbtype' )
self.host = self.addon.getSetting( 'dbhost' )
diff --git a/plugin.video.mediathekview/resources/lib/showui.py b/plugin.video.mediathekview/resources/lib/showui.py
index b0bf7f9..64aff20 100644
--- a/plugin.video.mediathekview/resources/lib/showui.py
+++ b/plugin.video.mediathekview/resources/lib/showui.py
@@ -3,35 +3,55 @@
#
# -- Imports ------------------------------------------------
-import sys, urllib
-import xbmcplugin, xbmcgui
+import xbmcgui
+import xbmcplugin
+
+import resources.lib.mvutils as mvutils
from resources.lib.show import Show
# -- Classes ------------------------------------------------
class ShowUI( Show ):
- def __init__( self, handle, sortmethods = None ):
- self.base_url = sys.argv[0]
- self.handle = handle
+ def __init__( self, plugin, sortmethods = None ):
+ self.plugin = plugin
+ self.handle = plugin.addon_handle
self.sortmethods = sortmethods if sortmethods is not None else [ xbmcplugin.SORT_METHOD_TITLE ]
self.querychannelid = 0
def Begin( self, channelid ):
- self.querychannelid = channelid
+ self.querychannelid = int( channelid )
for method in self.sortmethods:
xbmcplugin.addSortMethod( self.handle, method )
def Add( self, altname = None ):
if altname is not None:
resultingname = altname
- elif self.querychannelid == '0':
+ elif self.querychannelid == 0:
resultingname = self.show + ' [' + self.channel + ']'
else:
resultingname = self.show
+
+ infoLabels = {
+ 'title' : resultingname,
+ 'sorttitle' : resultingname.lower()
+ }
+
+
+ if self.channel.find( ',' ) == -1:
+ icon = 'special://home/addons/' + self.plugin.addon_id + '/resources/icons/' + self.channel.lower() + '-m.png'
+ else:
+ icon = 'special://home/addons/' + self.plugin.addon_id + '/resources/icons/default-m.png'
+
li = xbmcgui.ListItem( label = resultingname )
+ li.setInfo( type = 'video', infoLabels = infoLabels )
+ li.setArt( {
+ 'thumb': icon,
+ 'icon': icon
+ } )
+
xbmcplugin.addDirectoryItem(
handle = self.handle,
- url = self.build_url( {
+ url = mvutils.build_url( {
'mode': "films",
'show': self.id
} ),
@@ -41,6 +61,3 @@ class ShowUI( Show ):
def End( self ):
xbmcplugin.endOfDirectory( self.handle )
-
- def build_url( self, query ):
- return self.base_url + '?' + urllib.urlencode( query )
diff --git a/plugin.video.mediathekview/resources/lib/storemysql.py b/plugin.video.mediathekview/resources/lib/storemysql.py
index e2419cc..9268eec 100644
--- a/plugin.video.mediathekview/resources/lib/storemysql.py
+++ b/plugin.video.mediathekview/resources/lib/storemysql.py
@@ -20,7 +20,7 @@ class StoreMySQL( object ):
# useful query fragments
self.sql_query_films = "SELECT film.id,`title`,`show`,`channel`,`description`,TIME_TO_SEC(`duration`) AS `seconds`,`size`,`aired`,`url_sub`,`url_video`,`url_video_sd`,`url_video_hd` FROM `film` LEFT JOIN `show` ON show.id=film.showid LEFT JOIN `channel` ON channel.id=film.channelid"
self.sql_query_filmcnt = "SELECT COUNT(*) FROM `film` LEFT JOIN `show` ON show.id=film.showid LEFT JOIN `channel` ON channel.id=film.channelid"
- self.sql_cond_recent = "( TIMESTAMPDIFF(HOUR,`aired`,CURRENT_TIMESTAMP()) < 24 )"
+ self.sql_cond_recent = "( TIMESTAMPDIFF(SECOND,{},CURRENT_TIMESTAMP()) <= {} )".format( "aired" if settings.recentmode == 0 else "film.dtCreated", settings.maxage )
self.sql_cond_nofuture = " AND ( ( `aired` IS NULL ) OR ( TIMESTAMPDIFF(HOUR,`aired`,CURRENT_TIMESTAMP()) > 0 ) )" if settings.nofuture else ""
self.sql_cond_minlength = " AND ( ( `duration` IS NULL ) OR ( TIME_TO_SEC(`duration`) >= %d ) )" % settings.minlength if settings.minlength > 0 else ""
@@ -48,17 +48,21 @@ class StoreMySQL( object ):
self.conn.close()
def Search( self, search, filmui ):
- self._Search_Condition( '( ( `title` LIKE "%%%s%%" ) OR ( `show` LIKE "%%%s%%" ) )' % ( search, search, ), filmui, True, True, self.settings.maxresults )
+ searchmask = '%' + search.decode('utf-8') + '%'
+ self._Search_Condition( '( ( `title` LIKE %s ) OR ( `show` LIKE %s ) )', ( searchmask, searchmask, ), filmui, True, True, self.settings.maxresults )
def SearchFull( self, search, filmui ):
- self._Search_Condition( '( ( `title` LIKE "%%%s%%" ) OR ( `show` LIKE "%%%s%%" ) ) OR ( `description` LIKE "%%%s%%") )' % ( search, search, search ), filmui, True, True, self.settings.maxresults )
+ searchmask = '%' + search.decode('utf-8') + '%'
+ self._Search_Condition( '( ( `title` LIKE %s ) OR ( `show` LIKE %s ) OR ( `description` LIKE %s ) )', ( searchmask, searchmask, searchmask ), filmui, True, True, self.settings.maxresults )
def GetRecents( self, channelid, filmui ):
- sql_cond_channel = ' AND ( film.channelid=' + str( channelid ) + ' ) ' if channelid != '0' else ''
- self._Search_Condition( self.sql_cond_recent + sql_cond_channel, filmui, True, False, 10000 )
+ if channelid != '0':
+ self._Search_Condition( self.sql_cond_recent + ' AND ( film.channelid=%s )', ( int( channelid ), ), filmui, True, False, 10000 )
+ else:
+ self._Search_Condition( self.sql_cond_recent, (), filmui, True, False, 10000 )
def GetLiveStreams( self, filmui ):
- self._Search_Condition( '( show.search="LIVESTREAM" )', filmui, False, False, 10000 )
+ self._Search_Condition( '( show.search="LIVESTREAM" )', (), filmui, False, False, 10000 )
def GetChannels( self, channelui ):
self._Channels_Condition( None, channelui )
@@ -70,18 +74,30 @@ class StoreMySQL( object ):
if self.conn is None:
return
try:
- condition = 'WHERE ( `channelid`=' + str( channelid ) + ' ) ' if channelid != '0' else ''
- self.logger.info( 'MySQL Query: {}',
- 'SELECT LEFT(`search`,1) AS letter,COUNT(*) AS `count` FROM `show` ' +
- condition +
- 'GROUP BY LEFT(search,1)'
- )
+ channelid = int( channelid )
cursor = self.conn.cursor()
- cursor.execute(
- 'SELECT LEFT(`search`,1) AS letter,COUNT(*) AS `count` FROM `show` ' +
- condition +
- 'GROUP BY LEFT(`search`,1)'
- )
+ if channelid != 0:
+ self.logger.info(
+ 'MySQL Query: SELECT LEFT(`search`,1) AS letter,COUNT(*) AS `count` FROM `show` WHERE ( `channelid`={} ) GROUP BY LEFT(search,1)',
+ channelid
+ )
+ cursor.execute( """
+ SELECT LEFT(`search`,1) AS `letter`,
+ COUNT(*) AS `count`
+ FROM `show`
+ WHERE ( `channelid`=%s )
+ GROUP BY LEFT(`search`,1)
+ """, ( channelid, ) )
+ else:
+ self.logger.info(
+ 'MySQL Query: SELECT LEFT(`search`,1) AS letter,COUNT(*) AS `count` FROM `show` GROUP BY LEFT(search,1)'
+ )
+ cursor.execute( """
+ SELECT LEFT(`search`,1) AS `letter`,
+ COUNT(*) AS `count`
+ FROM `show`
+ GROUP BY LEFT(`search`,1)
+ """ )
initialui.Begin( channelid )
for ( initialui.initial, initialui.count ) in cursor:
initialui.Add()
@@ -95,15 +111,57 @@ class StoreMySQL( object ):
if self.conn is None:
return
try:
- if channelid == '0' and self.settings.groupshows:
- query = 'SELECT GROUP_CONCAT(show.id),GROUP_CONCAT(`channelid`),`show`,GROUP_CONCAT(`channel`) FROM `show` LEFT JOIN `channel` ON channel.id=show.channelid WHERE ( `show` LIKE "%s%%" ) GROUP BY `show`' % initial
- elif channelid == '0':
- query = 'SELECT show.id,show.channelid,show.show,channel.channel FROM `show` LEFT JOIN channel ON channel.id=show.channelid WHERE ( `show` LIKE "%s%%" )' % initial
- else:
- query = 'SELECT show.id,show.channelid,show.show,channel.channel FROM `show` LEFT JOIN channel ON channel.id=show.channelid WHERE ( `channelid`=%s ) AND ( `show` LIKE "%s%%" )' % ( channelid, initial )
- self.logger.info( 'MySQL Query: {}', query )
+ channelid = int( channelid )
cursor = self.conn.cursor()
- cursor.execute( query )
+ if channelid == 0 and self.settings.groupshows:
+ cursor.execute( """
+ SELECT GROUP_CONCAT(show.id),
+ GROUP_CONCAT(`channelid`),
+ `show`,
+ GROUP_CONCAT(`channel`)
+ FROM `show`
+ LEFT JOIN `channel`
+ ON ( channel.id = show.channelid )
+ WHERE ( `show` LIKE %s )
+ GROUP BY `show`
+ """, ( initial + '%', ) )
+ elif channelid == 0:
+ cursor.execute( """
+ SELECT show.id,
+ show.channelid,
+ show.show,
+ channel.channel
+ FROM `show`
+ LEFT JOIN `channel`
+ ON ( channel.id = show.channelid )
+ WHERE ( `show` LIKE %s )
+ """, ( initial + '%', ) )
+ elif initial:
+ cursor.execute( """
+ SELECT show.id,
+ show.channelid,
+ show.show,
+ channel.channel
+ FROM `show`
+ LEFT JOIN `channel`
+ ON ( channel.id = show.channelid )
+ WHERE (
+ ( `channelid` = %s )
+ AND
+ ( `show` LIKE %s )
+ )
+ """, ( channelid, initial + '%', ) )
+ else:
+ cursor.execute( """
+ SELECT show.id,
+ show.channelid,
+ show.show,
+ channel.channel
+ FROM `show`
+ LEFT JOIN `channel`
+ ON ( channel.id = show.channelid )
+ WHERE ( `channelid` = %s )
+ """, ( channelid, ) )
showui.Begin( channelid )
for ( showui.id, showui.channelid, showui.show, showui.channel ) in cursor:
showui.Add()
@@ -118,13 +176,10 @@ class StoreMySQL( object ):
return
if showid.find( ',' ) == -1:
# only one channel id
- condition = '( `showid`=%s )' % showid
- showchannels = False
+ self._Search_Condition( '( `showid` = %s )', ( int( showid ), ), filmui, False, False, 10000 )
else:
# multiple channel ids
- condition = '( `showid` IN ( %s ) )' % showid
- showchannels = True
- self._Search_Condition( condition, filmui, False, showchannels, 10000 )
+ self._Search_Condition( '( `showid` IN ( {} ) )'.format( showid ), (), filmui, False, True, 10000 )
def _Channels_Condition( self, condition, channelui):
if self.conn is None:
@@ -132,11 +187,14 @@ class StoreMySQL( object ):
try:
if condition is None:
query = 'SELECT `id`,`channel`,0 AS `count` FROM `channel`'
+ qtail = ''
else:
- query = 'SELECT channel.id AS `id`,`channel`,COUNT(*) AS `count` FROM `film` LEFT JOIN `channel` ON channel.id=film.channelid WHERE ' + condition + ' GROUP BY channel.id'
- self.logger.info( 'MySQL Query: {}', query )
+ query = 'SELECT channel.id AS `id`,`channel`,COUNT(*) AS `count` FROM `film` LEFT JOIN `channel` ON channel.id=film.channelid'
+ qtail = ' WHERE ' + condition + self.sql_cond_nofuture + self.sql_cond_minlength + ' GROUP BY channel.id'
+ self.logger.info( 'MySQL Query: {}', query + qtail )
+
cursor = self.conn.cursor()
- cursor.execute( query )
+ cursor.execute( query + qtail )
channelui.Begin()
for ( channelui.id, channelui.channel, channelui.count ) in cursor:
channelui.Add()
@@ -146,7 +204,7 @@ class StoreMySQL( object ):
self.logger.error( 'Database error: {}', err )
self.notifier.ShowDatabaseError( err )
- def _Search_Condition( self, condition, filmui, showshows, showchannels, maxresults ):
+ def _Search_Condition( self, condition, params, filmui, showshows, showchannels, maxresults ):
if self.conn is None:
return
try:
@@ -164,7 +222,8 @@ class StoreMySQL( object ):
condition +
self.sql_cond_nofuture +
self.sql_cond_minlength +
- ' LIMIT {}'.format( maxresults + 1 ) if maxresults else ''
+ ' LIMIT {}'.format( maxresults + 1 ) if maxresults else '',
+ params
)
( results, ) = cursor.fetchone()
if maxresults and results > maxresults:
@@ -175,7 +234,8 @@ class StoreMySQL( object ):
condition +
self.sql_cond_nofuture +
self.sql_cond_minlength +
- ' LIMIT {}'.format( maxresults + 1 ) if maxresults else ''
+ ' LIMIT {}'.format( maxresults + 1 ) if maxresults else '',
+ params
)
filmui.Begin( showshows, showchannels )
for ( filmui.id, filmui.title, filmui.show, filmui.channel, filmui.description, filmui.seconds, filmui.size, filmui.aired, filmui.url_sub, filmui.url_video, filmui.url_video_sd, filmui.url_video_hd ) in cursor:
@@ -518,10 +578,10 @@ class StoreMySQL( object ):
cursor = self.conn.cursor()
cursor.callproc( 'ftInsertChannel', ( channel, ) )
for result in cursor.stored_results():
- for ( id, added ) in result:
+ for ( idd, added ) in result:
cursor.close()
self.conn.commit()
- return ( id, added )
+ return ( idd, added )
# should never happen
cursor.close()
self.conn.commit()
diff --git a/plugin.video.mediathekview/resources/lib/storesqlite.py b/plugin.video.mediathekview/resources/lib/storesqlite.py
index 601db67..90d10b1 100644
--- a/plugin.video.mediathekview/resources/lib/storesqlite.py
+++ b/plugin.video.mediathekview/resources/lib/storesqlite.py
@@ -23,7 +23,7 @@ class StoreSQLite( object ):
# useful query fragments
self.sql_query_films = "SELECT film.id,title,show,channel,description,duration,size,datetime(aired, 'unixepoch', 'localtime'),url_sub,url_video,url_video_sd,url_video_hd FROM film LEFT JOIN show ON show.id=film.showid LEFT JOIN channel ON channel.id=film.channelid"
self.sql_query_filmcnt = "SELECT COUNT(*) FROM film LEFT JOIN show ON show.id=film.showid LEFT JOIN channel ON channel.id=film.channelid"
- self.sql_cond_recent = "( ( UNIX_TIMESTAMP() - aired ) <= 86400 )"
+ self.sql_cond_recent = "( ( UNIX_TIMESTAMP() - {} ) <= {} )".format( "aired" if settings.recentmode == 0 else "film.dtCreated", settings.maxage )
self.sql_cond_nofuture = " AND ( ( aired IS NULL ) OR ( ( UNIX_TIMESTAMP() - aired ) > 0 ) )" if settings.nofuture else ""
self.sql_cond_minlength = " AND ( ( duration IS NULL ) OR ( duration >= %d ) )" % settings.minlength if settings.minlength > 0 else ""
@@ -55,17 +55,21 @@ class StoreSQLite( object ):
self.conn = None
def Search( self, search, filmui ):
- self._Search_Condition( '( ( title LIKE "%%%s%%" ) OR ( show LIKE "%%%s%%" ) )' % ( search, search ), filmui, True, True, self.settings.maxresults )
+ searchmask = '%' + search.decode('utf-8') + '%'
+ self._Search_Condition( '( ( title LIKE ? ) OR ( show LIKE ? ) )', ( searchmask, searchmask, ), filmui, True, True, self.settings.maxresults )
def SearchFull( self, search, filmui ):
- self._Search_Condition( '( ( title LIKE "%%%s%%" ) OR ( show LIKE "%%%s%%" ) OR ( description LIKE "%%%s%%") )' % ( search, search, search ), filmui, True, True, self.settings.maxresults )
+ searchmask = '%' + search.decode('utf-8') + '%'
+ self._Search_Condition( '( ( title LIKE ? ) OR ( show LIKE ? ) OR ( description LIKE ? ) )', ( searchmask, searchmask, searchmask ), filmui, True, True, self.settings.maxresults )
def GetRecents( self, channelid, filmui ):
- sql_cond_channel = ' AND ( film.channelid=' + str( channelid ) + ' ) ' if channelid != '0' else ''
- self._Search_Condition( self.sql_cond_recent + sql_cond_channel, filmui, True, False, 10000 )
+ if channelid != '0':
+ self._Search_Condition( self.sql_cond_recent + ' AND ( film.channelid=? )', ( int( channelid ), ), filmui, True, False, 10000 )
+ else:
+ self._Search_Condition( self.sql_cond_recent, (), filmui, True, False, 10000 )
def GetLiveStreams( self, filmui ):
- self._Search_Condition( '( show.search="LIVESTREAM" )', filmui, False, False, 10000 )
+ self._Search_Condition( '( show.search="LIVESTREAM" )', (), filmui, False, False, 10000 )
def GetChannels( self, channelui ):
self._Channels_Condition( None, channelui )
@@ -77,18 +81,28 @@ class StoreSQLite( object ):
if self.conn is None:
return
try:
- condition = 'WHERE ( channelid=' + str( channelid ) + ' ) ' if channelid != '0' else ''
- self.logger.info( 'SQlite Query: {}',
- 'SELECT SUBSTR(search,1,1),COUNT(*) FROM show ' +
- condition +
- 'GROUP BY LEFT(search,1)'
- )
+ channelid = int( channelid )
cursor = self.conn.cursor()
- cursor.execute(
- 'SELECT SUBSTR(search,1,1),COUNT(*) FROM show ' +
- condition +
- 'GROUP BY SUBSTR(search,1,1)'
- )
+ if channelid != 0:
+ self.logger.info(
+ 'SQlite Query: SELECT SUBSTR(search,1,1),COUNT(*) FROM show WHERE ( channelid={} ) GROUP BY LEFT(search,1)',
+ channelid
+ )
+ cursor.execute( """
+ SELECT SUBSTR(search,1,1),COUNT(*)
+ FROM show
+ WHERE ( channelid=? )
+ GROUP BY SUBSTR(search,1,1)
+ """, ( channelid, ) )
+ else:
+ self.logger.info(
+ 'SQlite Query: SELECT SUBSTR(search,1,1),COUNT(*) FROM show GROUP BY LEFT(search,1)'
+ )
+ cursor.execute( """
+ SELECT SUBSTR(search,1,1),COUNT(*)
+ FROM show
+ GROUP BY SUBSTR(search,1,1)
+ """ )
initialui.Begin( channelid )
for ( initialui.initial, initialui.count ) in cursor:
initialui.Add()
@@ -102,15 +116,57 @@ class StoreSQLite( object ):
if self.conn is None:
return
try:
- if channelid == '0' and self.settings.groupshows:
- query = 'SELECT GROUP_CONCAT(show.id),GROUP_CONCAT(channelid),show,GROUP_CONCAT(channel) FROM show LEFT JOIN channel ON channel.id=show.channelid WHERE ( show LIKE "%s%%" ) GROUP BY show' % initial
- elif channelid == '0':
- query = 'SELECT show.id,show.channelid,show.show,channel.channel FROM show LEFT JOIN channel ON channel.id=show.channelid WHERE ( show LIKE "%s%%" )' % initial
- else:
- query = 'SELECT show.id,show.channelid,show.show,channel.channel FROM show LEFT JOIN channel ON channel.id=show.channelid WHERE ( channelid=%s ) AND ( show LIKE "%s%%" )' % ( channelid, initial )
- self.logger.info( 'SQLite Query: {}', query )
+ channelid = int( channelid )
cursor = self.conn.cursor()
- cursor.execute( query )
+ if channelid == 0 and self.settings.groupshows:
+ cursor.execute( """
+ SELECT GROUP_CONCAT(show.id),
+ GROUP_CONCAT(channelid),
+ show,
+ GROUP_CONCAT(channel)
+ FROM show
+ LEFT JOIN channel
+ ON ( channel.id = show.channelid )
+ WHERE ( show LIKE ? )
+ GROUP BY show
+ """, ( initial + '%', ) )
+ elif channelid == 0:
+ cursor.execute( """
+ SELECT show.id,
+ show.channelid,
+ show.show,
+ channel.channel
+ FROM show
+ LEFT JOIN channel
+ ON ( channel.id = show.channelid )
+ WHERE ( show LIKE ? )
+ """, ( initial + '%', ) )
+ elif initial:
+ cursor.execute( """
+ SELECT show.id,
+ show.channelid,
+ show.show,
+ channel.channel
+ FROM show
+ LEFT JOIN channel
+ ON ( channel.id = show.channelid )
+ WHERE (
+ ( channelid=? )
+ AND
+ ( show LIKE ? )
+ )
+ """, ( channelid, initial + '%', ) )
+ else:
+ cursor.execute( """
+ SELECT show.id,
+ show.channelid,
+ show.show,
+ channel.channel
+ FROM show
+ LEFT JOIN channel
+ ON ( channel.id = show.channelid )
+ WHERE ( channelid=? )
+ """, ( channelid, ) )
showui.Begin( channelid )
for ( showui.id, showui.channelid, showui.show, showui.channel ) in cursor:
showui.Add()
@@ -125,13 +181,10 @@ class StoreSQLite( object ):
return
if showid.find( ',' ) == -1:
# only one channel id
- condition = '( showid=%s )' % showid
- showchannels = False
+ self._Search_Condition( '( showid=? )', ( int( showid ), ), filmui, False, False, 10000 )
else:
# multiple channel ids
- condition = '( showid IN ( %s ) )' % showid
- showchannels = True
- self._Search_Condition( condition, filmui, False, showchannels, 10000 )
+ self._Search_Condition( '( showid IN ( {} ) )'.format( showid ), (), filmui, False, True, 10000 )
def _Channels_Condition( self, condition, channelui ):
if self.conn is None:
@@ -139,11 +192,13 @@ class StoreSQLite( object ):
try:
if condition is None:
query = 'SELECT id,channel,0 AS `count` FROM channel'
+ qtail = ''
else:
- query = 'SELECT channel.id AS `id`,channel,COUNT(*) AS `count` FROM film LEFT JOIN channel ON channel.id=film.channelid WHERE ' + condition + ' GROUP BY channel'
- self.logger.info( 'SQLite Query: {}', query )
+ query = 'SELECT channel.id AS `id`,channel,COUNT(*) AS `count` FROM film LEFT JOIN channel ON channel.id=film.channelid'
+ qtail = ' WHERE ' + condition + ' GROUP BY channel'
+ self.logger.info( 'SQLite Query: {}', query + qtail )
cursor = self.conn.cursor()
- cursor.execute( query )
+ cursor.execute( query + qtail )
channelui.Begin()
for ( channelui.id, channelui.channel, channelui.count ) in cursor:
channelui.Add()
@@ -153,7 +208,7 @@ class StoreSQLite( object ):
self.logger.error( 'Database error: {}', err )
self.notifier.ShowDatabaseError( err )
- def _Search_Condition( self, condition, filmui, showshows, showchannels, maxresults ):
+ def _Search_Condition( self, condition, params, filmui, showshows, showchannels, maxresults ):
if self.conn is None:
return
try:
@@ -172,7 +227,8 @@ class StoreSQLite( object ):
condition +
self.sql_cond_nofuture +
self.sql_cond_minlength +
- ' LIMIT {}'.format( maxresults + 1 ) if maxresults else ''
+ ' LIMIT {}'.format( maxresults + 1 ) if maxresults else '',
+ params
)
( results, ) = cursor.fetchone()
if maxresults and results > maxresults:
@@ -183,7 +239,8 @@ class StoreSQLite( object ):
condition +
self.sql_cond_nofuture +
self.sql_cond_minlength +
- ' LIMIT {}'.format( maxresults ) if maxresults else ''
+ ' LIMIT {}'.format( maxresults ) if maxresults else '',
+ params
)
filmui.Begin( showshows, showchannels )
for ( filmui.id, filmui.title, filmui.show, filmui.channel, filmui.description, filmui.seconds, filmui.size, filmui.aired, filmui.url_sub, filmui.url_video, filmui.url_video_sd, filmui.url_video_hd ) in cursor:
diff --git a/plugin.video.mediathekview/resources/lib/ttml2srt.py b/plugin.video.mediathekview/resources/lib/ttml2srt.py
index 7bfdc47..5c2c4e3 100644
--- a/plugin.video.mediathekview/resources/lib/ttml2srt.py
+++ b/plugin.video.mediathekview/resources/lib/ttml2srt.py
@@ -27,7 +27,7 @@
import re
import io
from datetime import timedelta
-from xml.etree import ElementTree as ET
+from defusedxml import ElementTree as ET
def ttml2srt( infile, outfile ):
tree = ET.parse( infile )
@@ -59,7 +59,7 @@ def ttml2srt( infile, outfile ):
def parse_time_expression(expression, default_offset=timedelta(0)):
offset_time = re.match(r'^([0-9]+(\.[0-9]+)?)(h|m|s|ms|f|t)$', expression)
if offset_time:
- time_value, fraction, metric = offset_time.groups()
+ time_value, _, metric = offset_time.groups()
time_value = float(time_value)
if metric == 'h':
return default_offset + timedelta(hours=time_value)
@@ -79,7 +79,7 @@ def ttml2srt( infile, outfile ):
clock_time = re.match(
r'^([0-9]{2,}):([0-9]{2,}):([0-9]{2,}(\.[0-9]+)?)$', expression)
if clock_time:
- hours, minutes, seconds, fraction = clock_time.groups()
+ hours, minutes, seconds, _ = clock_time.groups()
return timedelta(hours=int(hours), minutes=int(minutes), seconds=float(seconds))
clock_time_frames = re.match(
diff --git a/plugin.video.mediathekview/resources/lib/updater.py b/plugin.video.mediathekview/resources/lib/updater.py
index afdf840..95c99d0 100644
--- a/plugin.video.mediathekview/resources/lib/updater.py
+++ b/plugin.video.mediathekview/resources/lib/updater.py
@@ -2,9 +2,15 @@
# Copyright (c) 2017-2018, Leo Moll
# -- Imports ------------------------------------------------
-import os, urllib2, subprocess, ijson, datetime, time
-import xml.etree.ElementTree as etree
-
+import os
+import time
+import ijson
+import random
+import urllib2
+import datetime
+import subprocess
+
+import defusedxml.ElementTree as etree
import resources.lib.mvutils as mvutils
from operator import itemgetter
@@ -12,6 +18,7 @@ from operator import itemgetter
from resources.lib.store import Store
from resources.lib.exceptions import DatabaseCorrupted
from resources.lib.exceptions import DatabaseLost
+from resources.lib.exceptions import ExitRequested
# -- Unpacker support ---------------------------------------
upd_can_bz2 = False
@@ -106,7 +113,7 @@ class MediathekViewUpdater( object ):
self.Import( full )
def Import( self, full ):
- ( _, compfile, destfile, avgrecsize ) = self._get_update_info( full )
+ ( _, _, destfile, avgrecsize ) = self._get_update_info( full )
if not mvutils.file_exists( destfile ):
self.logger.error( 'File {} does not exists', destfile )
return False
@@ -178,14 +185,14 @@ class MediathekViewUpdater( object ):
except DatabaseLost as err:
self.logger.error( '{}', err )
self.notifier.CloseUpdateProgress()
- except IOError as err:
+ except Exception as err:
self.logger.error( 'Error {} wile processing {}', err, destfile )
self._update_end( full, 'ABORTED' )
self.notifier.CloseUpdateProgress()
return False
def GetNewestList( self, full ):
- ( url, compfile, destfile, avgrecsize ) = self._get_update_info( full )
+ ( url, compfile, destfile, _ ) = self._get_update_info( full )
if url is None:
self.logger.error( 'No suitable archive extractor available for this system' )
self.notifier.ShowMissingExtractorError()
@@ -199,20 +206,18 @@ class MediathekViewUpdater( object ):
self.logger.error( 'Failure opening {}', url )
self.notifier.ShowDownloadError( url, err )
return False
-
root = etree.fromstring ( data )
urls = []
for server in root.findall( 'Server' ):
try:
URL = server.find( 'URL' ).text
Prio = server.find( 'Prio' ).text
- urls.append( ( self._get_update_url( URL ), Prio ) )
+ urls.append( ( self._get_update_url( URL ), float( Prio ) + random.random() * 1.2 ) )
self.logger.info( 'Found mirror {} (Priority {})', URL, Prio )
except AttributeError:
pass
urls = sorted( urls, key = itemgetter( 1 ) )
urls = [ url[0] for url in urls ]
- result = None
# cleanup downloads
self.logger.info( 'Cleaning up old downloads...' )
@@ -227,17 +232,23 @@ class MediathekViewUpdater( object ):
lasturl = url
self.logger.info( 'Trying to download {} from {}...', os.path.basename( compfile ), url )
self.notifier.UpdateDownloadProgress( 0, url )
- result = mvutils.url_retrieve( url, filename = compfile, reporthook = self._reporthook )
+ mvutils.url_retrieve( url, filename = compfile, reporthook = self.notifier.HookDownloadProgress, aborthook = self.monitor.abortRequested )
break
except urllib2.URLError as err:
self.logger.error( 'Failure downloading {}', url )
+ self.notifier.CloseDownloadProgress()
+ self.notifier.ShowDownloadError( lasturl, err )
+ return False
+ except ExitRequested as err:
+ self.logger.error( 'Immediate exit requested. Aborting download of {}', url )
+ self.notifier.CloseDownloadProgress()
+ self.notifier.ShowDownloadError( lasturl, err )
+ return False
except Exception as err:
self.logger.error( 'Failure writng {}', url )
- if result is None:
- self.logger.info( 'No file downloaded' )
- self.notifier.CloseDownloadProgress()
- self.notifier.ShowDownloadError( lasturl, err )
- return False
+ self.notifier.CloseDownloadProgress()
+ self.notifier.ShowDownloadError( lasturl, err )
+ return False
# decompress filmliste
if self.use_xz is True:
@@ -304,13 +315,6 @@ class MediathekViewUpdater( object ):
self.logger.error( 'Failed to remove {}: error {}', name, err )
return False
- def _reporthook( self, blockcount, blocksize, totalsize ):
- downloaded = blockcount * blocksize
- if totalsize > 0:
- percent = int( (downloaded * 100) / totalsize )
- self.notifier.UpdateDownloadProgress( percent )
- self.logger.debug( 'Downloading blockcount={}, blocksize={}, totalsize={}', blockcount, blocksize, totalsize )
-
def _update_start( self, full ):
self.logger.info( 'Initializing update...' )
self.add_chn = 0