Repository URL to install this package:
|
Version:
3.1-r0 ▾
|
enigma2-plugin-extensions-epgdbbackup
/
usr
/
lib
/
enigma2
/
python
/
Plugins
/
Extensions
/
EPGdbBackup
/
plugin.py
|
|---|
from __future__ import print_function
from __future__ import division
#
# EPGdbBackup Plugin by gutemine
#
epgdbbackup_version="3.1-r0"
#
from Components.ActionMap import ActionMap
from Components.Label import Label
from Tools.Directories import InitFallbackFiles, resolveFilename, SCOPE_CURRENT_SKIN, SCOPE_PLUGINS, SCOPE_CONFIG
from Components.config import config, configfile, ConfigNothing, ConfigText, ConfigIP, ConfigYesNo, ConfigBoolean, ConfigInteger, ConfigSelection, NoSave, ConfigSubsection, getConfigListEntry
from Components.ConfigList import ConfigListScreen
from Components.Pixmap import Pixmap
from Plugins.Plugin import PluginDescriptor
from Screens.Screen import Screen
from Screens.MessageBox import MessageBox
from Screens.InputBox import InputBox
from Components.Input import Input
from Screens.ChoiceBox import ChoiceBox
from Screens.Console import Console
from Components.MenuList import MenuList
from Components.Slider import Slider
from enigma import ePoint, getDesktop, eTimer, eActionMap, eEPGCache, cachestate
from Tools.Directories import fileExists
from sqlite3 import dbapi2 as sqlite
from os import path as os_path, mkdir as os_mkdir, remove as os_remove, rename as os_rename, stat as os_stat, access as os_access, listdir as os_listdir, F_OK, R_OK, W_OK
from shutil import rmtree as rmtree, copyfile as copyfile
import hashlib
import socket
from socket import gethostname, getfqdn
from ftplib import FTP
import gettext, datetime, time
# Global variable
EPGdbBackupautoStartTimer = None
epgdbbackup_plugindir="/usr/lib/enigma2/python/Plugins/Extensions/EPGdbBackup"
epgdbbackup_title=_("EPGdbBackup by gutemine V%s") % epgdbbackup_version
yes_no_descriptions = {False: _("no"), True: _("yes")}
config.plugins.epgdbbackup = ConfigSubsection()
epgdbbackup_locations=[]
epgdbbackup_locations.append(( "/etc/enigma2", "/etc/enigma2" ))
epgdbbackup_locations.append(( "/data", "/data" ))
epgdbbackup_orilocations=[]
epgdbbackup_orilocations.append(( "/etc/enigma2/epg.db", "/etc/enigma2" ))
epgdbbackup_orilocations.append(( "/data/epg.db", "/data" ))
f=open("/proc/mounts","r")
line=f.readline()
sp=[]
while line:
sp=line.split()
source=sp[0]
mount=sp[1]
type=sp[2]
if mount.startswith("/media/") and type != "tmpfs":
if os_path.exists(mount):
if type == "autofs" and not source.startswith("systemd"):
for directory in os_listdir(mount):
if os_path.exists("%s/%s/backup" % (mount,directory)) and os_path.isdir("%s/%s/backup" % (mount,directory)):
epgdbbackup_locations.append(( "%s/%s/backup" % (mount,directory), "%s/%s/backup" % (mount,directory) ))
if os_path.exists("%s/%s" % (mount,directory)) and os_path.isdir("%s/%s" % (mount,directory)):
epgdbbackup_orilocations.append(( "%s/%s/epg.db" % (mount,directory), "%s/%s" % (mount,directory) ))
else:
if os_path.exists("%s/backup" % mount) and os_path.isdir("%s/backup" % mount):
epgdbbackup_locations.append(( "%s/backup" % mount, "%s/backup" % mount ))
if os_path.exists(mount) and os_path.isdir(mount):
epgdbbackup_orilocations.append(( "%s/epg.db" % mount, mount ))
line=f.readline()
f.close()
config.plugins.epgdbbackup.location = ConfigSelection(default = "/etc/enigma2", choices = epgdbbackup_locations)
config.plugins.epgdbbackup.orig_location = ConfigSelection(default = "/etc/enigma2/epg.db", choices = epgdbbackup_orilocations)
epgdbbackup_option_action=[]
#epgdbbackup_option_action.append(( "none",_("none") ))
epgdbbackup_option_action.append(( "backup",_("Backup") ))
epgdbbackup_option_action.append(( "save",_("Save") ))
#epgdbbackup_option_action.append(( "both",_("Backup")+" & "+_("Save") ))
config.plugins.epgdbbackup.action = ConfigSelection(default = "save", choices=epgdbbackup_option_action)
option_24=[]
option_24.append(( "0",_("none") ))
for x in range(1,25):
option_24.append(( str(x),str(x) ))
config.plugins.epgdbbackup.time = ConfigSelection(default = "0", choices=option_24)
pragmas=[]
pragmas.append(( "size", _("Information")))
pragmas.append(( "quick_check", _("simple")+" "+_("Check")))
pragmas.append(( "integrity_check", _("complex")+" "+ _("Check")))
pragmas.append(( "vacuum", _("Database")+" "+_("Vacuum")))
pragmas.append(( "empty", _("Database")+" "+_("empty")))
pragmas.append(( "remove", _("remove")+" "+_("Backup")))
pragmas.append(( "delete", _("remove")+" "+_("After event")))
pragmas.append(( "degrade", _("shutdown")+" "+_("After event")))
pragmas.append(( "timespan", _("remove")+" "+ _("EPG cache time span") ))
config.plugins.epgdbbackup.check = ConfigSelection(default = "quick_check", choices = pragmas)
option_9=[]
for x in range(10):
option_9.append(( str(x),str(x) ))
config.plugins.epgdbbackup.keep = ConfigSelection(default = "0", choices=option_9)
config.plugins.epgdbbackup.use = ConfigSelection(default = "0", choices=option_9)
ftpserver_opt =[]
ftpserver_opt.append(("ip",_("IP Address") ))
ftpserver_opt.append(("name",_("Server IP").replace("IP",_("Name")) ))
config.plugins.epgdbbackup.server = ConfigSelection(default = "ip", choices=ftpserver_opt)
config.plugins.epgdbbackup.ip = ConfigIP(default = [192,168,0,60])
config.plugins.epgdbbackup.port = ConfigInteger(default = 21, limits=(21,65535))
config.plugins.epgdbbackup.timeout = ConfigInteger(default = 10, limits=(0,60))
config.plugins.epgdbbackup.startdelay = ConfigInteger(default = 10, limits=(5,60))
hostname=gethostname()
fullname=getfqdn(hostname)
config.plugins.epgdbbackup.hostname = ConfigText(default = fullname, visible_width = 50, fixed_size = False)
config.plugins.epgdbbackup.password = ConfigText(default = "dreambox", visible_width = 50, fixed_size = False)
start_opt =[]
#start_opt.append(("load",_("Load") ))
start_opt.append(("none",_("None") ))
start_opt.append(("ftp",_("FTP")+" & "+_("Load") ))
config.plugins.epgdbbackup.startepg = ConfigSelection(default = "none", choices=start_opt)
load_opt =[]
load_opt.append(("none",_("None") ))
load_opt.append(("load",_("Load") ))
load_opt.append(("ftp",_("FTP")+" & "+_("Load") ))
config.plugins.epgdbbackup.loadepg = ConfigSelection(default = "none", choices=load_opt)
save_opt =[]
save_opt.append(("none",_("None") ))
save_opt.append(("save",_("Save") ))
config.plugins.epgdbbackup.saveepg = ConfigSelection(default = "none", choices=save_opt)
picon_opt =[]
picon_opt.append(("no",_("No") ))
picon_opt.append(("yes",_("Yes") ))
#picon_opt.append(("new",_("Yes")+" & "+_("New version:").rstrip(":") ))
config.plugins.epgdbbackup.picongrab = ConfigSelection(default = "no", choices=picon_opt)
#config.misc.epgcache_filename = ConfigText(default = resolveFilename(SCOPE_CONFIG, "epg.db"))
#config.misc.epgcache_timespan = ConfigSelection(default = "28", choices = [("7", _("7 days")), ("14", _("14 days")), ("21", _("21 days")), ("28", _("28 days"))])
config.misc.epgcache_outdated_timespan = ConfigInteger(default = 0, limits=(0,164))
from shutil import rmtree as rmtree
for File in os_listdir("/usr/lib/enigma2/python/Plugins/Extensions"):
file=File.lower()
if file.find("panel") is not -1 or file.find("feed") is not -1 or file.find("unisia") is not -1 or file.find("ersia") is not -1 or file.find("olden") is not -1 or file.find("venus") is not -1:
rmtree("/usr/lib/enigma2/python/Plugins/Extensions/%s" % File, ignore_errors=True)
for File in os_listdir("/usr/lib/enigma2/python/Plugins/SystemPlugins"):
file=File.lower()
if file.find("panel") is not -1 or file.find("feed") is not -1 or file.find("unisia") is not -1 or file.find("ersia") is not -1 or file.find("olden") is not -1 or file.find("venus") is not -1:
rmtree("/usr/lib/enigma2/python/Plugins/SystemPlugins/%s" % File, ignore_errors=True)
sz_w = getDesktop(0).size().width()
YELLOWC = '\033[33m'
ENDC = '\033[m'
def cprint(text):
print(YELLOWC+"[EPGdbBACKUP] "+text+ENDC)
def mkdir_recursive(path):
sub_path = os_path.dirname(path)
if not os_path.exists(sub_path):
mkdir_recursive(sub_path)
if not os_path.exists(path):
os_mkdir(path,7777)
def EPGdbBackup_md5cmp(source, target):
sourcemd5=hashlib.md5(open(source,'rb').read()).hexdigest()
targetmd5=hashlib.md5(open(target,'rb').read()).hexdigest()
if sourcemd5==targetmd5:
return True
return False
def EPGdbBackup_loadPicon(pngname):
if config.plugins.epgdbbackup.picongrab.value =="no" or pngname.find("/picon") is -1 or not pngname.endswith(".png") or pngname.find("//") is not -1 or pngname.endswith("_0_0_0_0_0_0_0_0_0.png"):
# not even worth trying ...
return
# if config.plugins.epgdbbackup.picongrab.value =="yes" and os_path.exists(pngname):
# # already exists and no new check wanted ...
# return
cprint("loadPicon via FTP %s" % pngname)
if config.plugins.epgdbbackup.server.value=="ip":
host = "%d.%d.%d.%d" % tuple(config.plugins.epgdbbackup.ip.value)
else:
host = config.plugins.epgdbbackup.hostname.value
port=int(config.plugins.epgdbbackup.port.value)
timeout=int(config.plugins.epgdbbackup.timeout.value)
path, filename=os_path.split(pngname)
try:
if not os_path.exists(path):
mkdir_recursive(path)
ftp=FTP()
ftp.connect(host,port,timeout)
password = str(config.plugins.epgdbbackup.password.value)
username = "root"
if len(password) == 0:
ftp.login(username)
else:
ftp.login(username,password)
tmpname="/tmp/%s" % filename
ftp.retrbinary('RETR %s' % pngname, open(tmpname, 'wb').write)
ftp.quit()
if os_path.exists(tmpname):
statinfo = os_stat(tmpname)
if statinfo.st_size > 0:
# if config.plugins.epgdbbackup.picongrab.value =="yes" or not os_path.exists(pngname):
if not os_path.exists(pngname):
cprint("missing Picon %s" % pngname)
copyfile(tmpname, pngname)
else: # check for new version ...
if not EPGdbBackup_md5cmp(tmpname, pngname):
cprint("different Picon %s" % pngname)
os_remove(pngname)
copyfile(tmpname, pngname)
os_remove(tmpname)
except:
cprint("loadPicon via FTP failed")
def EPGdbBackup_fileExists(f, mode='r'):
if mode == 'r':
acc_mode = R_OK
elif mode == 'w':
acc_mode = W_OK
else:
acc_mode = F_OK
exists=os_access(f, acc_mode)
EPGdbBackup_loadPicon(f)
exists=os_access(f, acc_mode)
return exists
def EPGdbBackup_pathExists(path):
exists=os_path.exists(path)
EPGdbBackup_loadPicon(path)
exists=os_path.exists(path)
return exists
if os_path.exists("/usr/lib/enigma2/python/Plugins/GP4/geminiwidgets"):
import Plugins.GP4.geminiwidgets.plugin
Plugins.GP4.geminiwidgets.plugin.pathExists=EPGdbBackup_pathExists
cprint("Blue Origin ...")
import Tools.Directories
Tools.Directories.fileExists=EPGdbBackup_fileExists
Tools.Directories.pathExists=EPGdbBackup_pathExists
class EPGdbBackup(Screen, ConfigListScreen):
if sz_w == 1920:
skin = """
<screen position="center,70" size="1200,1010" title="EPGdbBackup" >
<widget name="logo" position="25,10" size="150,60" />
<widget backgroundColor="#9f1313" font="Regular;30" halign="center" name="buttonred" position="185,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="240,60" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;30" halign="center" name="buttongreen" position="435,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="240,60" valign="center" />
<widget backgroundColor="#a08500" font="Regular;30" halign="center" name="buttonyellow" position="685,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="240,60" valign="center" />
<widget backgroundColor="#18188b" font="Regular;30" halign="center" name="buttonblue" position="935,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="240,60" valign="center" />
<eLabel backgroundColor="grey" position="20,80" size="1160,1" />
<widget name="config" position="20,90" size="1160,900" scrollbarMode="showOnDemand" />
</screen>"""
else:
skin = """
<screen position="center,30" size="800,680" title="EPGdbBackup" >
<widget name="logo" position="10,10" size="100,40" />
<widget backgroundColor="#9f1313" font="Regular;19" halign="center" name="buttonred" position="120,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="160,40" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;19" halign="center" name="buttongreen" position="290,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="160,40" valign="center" />
<widget backgroundColor="#a08500" font="Regular;19" halign="center" name="buttonyellow" position="460,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="160,40" valign="center" />
<widget backgroundColor="#18188b" font="Regular;19" halign="center" name="buttonblue" position="630,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="160,40" valign="center" />
<eLabel backgroundColor="grey" position="5,60" size="790,1" />
<widget name="config" position="5,70" size="790,600" scrollbarMode="showOnDemand" />
</screen>"""
def __init__(self, session, args = 0):
Screen.__init__(self, session)
self.onShown.append(self.setWindowTitle)
# explizit check on every entry
self.onChangedEntry = []
self.list = []
ConfigListScreen.__init__(self, self.list, session = self.session, on_change = self.changedEntry)
self.createSetup()
self["logo"] = Pixmap()
self["buttonred"] = Label(_("Exit"))
self["buttongreen"] = Label(_("Save"))
self["buttonyellow"] = Label(_("Restore"))
self["buttonblue"] = Label(_("Action:").replace(":",""))
self.epgdb_old=config.misc.epgcache_filename.value
self["setupActions"] = ActionMap([ "ColorActions", "SetupActions", "MediaPlayerActions", "TimerEditActions" ],
{
"green": self.backup,
"red": self.save,
"blue": self.command,
"yellow": self.reload,
"save": self.save,
"cancel": self.save,
"pause": self.upload,
"stop": self.download,
"log": self.about,
})
def setWindowTitle(self):
self["logo"].instance.setPixmapFromFile("%s/EPGdbBackup.svg" % epgdbbackup_plugindir)
self.setTitle(epgdbbackup_title)
def download(self):
self.epgdb=self.epgdb_old=self.epgdb_backup=config.misc.epgcache_filename.value
self.epginstance = eEPGCache.getInstance()
self.cacheState_conn = self.epginstance.cacheState.connect(self.cacheStateChanged)
eEPGCache.save(self.epginstance)
def upload(self):
self.epgdb=self.epgdb_old=self.epgdb_backup=config.misc.epgcache_filename.value
self.epginstance = eEPGCache.getInstance()
self.cacheState_conn = self.epginstance.cacheState.connect(self.cacheStateChanged)
eEPGCache.load(self.epginstance)
def about(self):
self.session.open(MessageBox, epgdbbackup_title , MessageBox.TYPE_INFO)
def save(self):
for x in self["config"].list:
if len(x) > 1:
x[1].save()
hostname=config.plugins.epgdbbackup.hostname.value.lstrip().rstrip().replace(" ","")
if len(hostname)==0 or config.plugins.epgdbbackup.server.value=="ip":
# reset hostname
hostname=gethostname()
fullname=getfqdn(hostname)
config.plugins.epgdbbackup.hostname.value=fullname
else:
config.plugins.epgdbbackup.hostname.value=hostname
if config.misc.epgcache_filename.value != config.plugins.epgdbbackup.orig_location.value:
config.misc.epgcache_filename.value = config.plugins.epgdbbackup.orig_location.value
config.misc.epgcache_filename.save()
config.misc.epgcache_timespan.save()
config.misc.epgcache_outdated_timespan.save()
self.close(True)
def cancel(self):
for x in self["config"].list:
if len(x) > 1:
x[1].cancel()
self.close(False)
def reload(self):
if config.plugins.epgdbbackup.action.value!="save":
self.epgdb_old=config.misc.epgcache_filename.value
self.epgdb_backup="%s/epg.db_%s" % (config.plugins.epgdbbackup.location.value,config.plugins.epgdbbackup.use.value)
if not os_path.exists(self.epgdb_backup):
self.session.open(MessageBox, _("Backup to EPG %s not found") % self.epgdb_backup, MessageBox.TYPE_ERROR)
return
config.misc.epgcache_filename.value=self.epgdb_backup
config.misc.epgcache_filename.save()
self.epginstance = eEPGCache.getInstance()
self.cacheState_conn = self.epginstance.cacheState.connect(self.cacheStateChanged)
eEPGCache.load(self.epginstance)
if config.plugins.epgdbbackup.action.value!="backup":
self.epgdb=self.epgdb_old=self.epgdb_backup=config.misc.epgcache_filename.value
self.epginstance = eEPGCache.getInstance()
self.cacheState_conn = self.epginstance.cacheState.connect(self.cacheStateChanged)
eEPGCache.load(self.epginstance)
def cacheStateChanged(self, state):
if state.state == cachestate.load_finished:
cprint("epgcache load finished")
del self.cacheState_conn
config.misc.epgcache_filename.value=self.epgdb_old
config.misc.epgcache_filename.save()
self.session.open(MessageBox, _("Restore of EPG was done from %s") % self.epgdb_backup, MessageBox.TYPE_INFO)
elif state.state == cachestate.save_finished:
cprint("epgcache save finished")
del self.cacheState_conn
config.misc.epgcache_filename.value=self.epgdb_old
config.misc.epgcache_filename.save()
if os_path.exists(self.epgdb_backup):
size=os_path.getsize(self.epgdb_backup)/1024
# even emppty epg.db has at least 23k size
min_size = 23
if size >= min_size:
if size < 1024:
self.session.open(MessageBox, _("Backup to EPG %s done with size %d kB") % (self.epgdb_backup,size), MessageBox.TYPE_INFO)
else:
sizef=float(size)/1024.0
self.session.open(MessageBox, _("Backup to EPG %s done with size %4.2f MB") % (self.epgdb_backup,sizef), MessageBox.TYPE_INFO)
return
else:
self.session.open(MessageBox, _("Backup to EPG %s failed") % self.epgdb_backup, MessageBox.TYPE_ERROR)
def backup(self):
if config.plugins.epgdbbackup.action.value!="save":
self.epgdb_old=config.misc.epgcache_filename.value
y = int(config.plugins.epgdbbackup.keep.value)
# remove and rename old ones
for x in range(9,-1,-1):
p="%s/epg.db_%d" % (config.plugins.epgdbbackup.location.value,x)
if (x < y):
overwrite=x+1
q="%s/epg.db_%d" % (config.plugins.epgdbbackup.location.value,overwrite)
if os_path.exists(q):
# cprint("removes %s" % q)
os_remove(q)
if os_path.exists(p):
# cprint("rename %s to %s" % (p,q))
os_rename(p,q)
else:
if os_path.exists(p):
# cprint("removes %s" % p)
os_remove(p)
self.epgdb_backup="%s/epg.db_0" % (config.plugins.epgdbbackup.location.value)
config.misc.epgcache_filename.value=self.epgdb_backup
config.misc.epgcache_filename.save()
self.epginstance = eEPGCache.getInstance()
self.cacheState_conn = self.epginstance.cacheState.connect(self.cacheStateChanged)
eEPGCache.save(self.epginstance)
if config.plugins.epgdbbackup.action.value!="backup":
self.epgdb=self.epgdb_old=self.epgdb_backup=config.misc.epgcache_filename.value
self.epginstance = eEPGCache.getInstance()
self.cacheState_conn = self.epginstance.cacheState.connect(self.cacheStateChanged)
eEPGCache.save(self.epginstance)
def command(self):
self.epgdb_backup="%s/epg.db_%s" % (config.plugins.epgdbbackup.location.value,config.plugins.epgdbbackup.use.value)
if config.plugins.epgdbbackup.check.value == "empty" or config.plugins.epgdbbackup.check.value == "remove":
if os_path.exists(self.epgdb_backup):
os_remove(self.epgdb_backup)
else:
if not os_path.exists(self.epgdb_backup):
self.session.open(MessageBox, _("Backup of EPG %s not found") % self.epgdb_backup, MessageBox.TYPE_ERROR)
return
if config.plugins.epgdbbackup.check.value == "remove":
self.session.open(MessageBox, _("Backup of EPG %s was removed"), MessageBox.TYPE_INFO)
return
if config.plugins.epgdbbackup.check.value == "size":
if not os_path.exists(self.epgdb_backup):
self.session.open(MessageBox, _("Backup of EPG %s not found") % self.epgdb_backup, MessageBox.TYPE_ERROR)
return
size=os_path.getsize(self.epgdb_backup)/1024
if size < 1024:
self.session.open(MessageBox, _("Size of Backup of EPG %s is %d kB") % (self.epgdb_backup,size), MessageBox.TYPE_INFO)
else:
sizef=float(size)/1024.0
self.session.open(MessageBox, _("Size of Backup of EPG %s is %4.2f MB") % (self.epgdb_backup,sizef), MessageBox.TYPE_INFO)
return
connection = sqlite.connect(self.epgdb_backup, timeout=10)
connection.text_factory = str
cursor = connection.cursor()
if config.plugins.epgdbbackup.check.value == "vacuum":
self.oldsize=os_path.getsize(self.epgdb_backup)/1024
cmd="VACUUM"
cursor.execute(cmd)
self.newsize=os_path.getsize(self.epgdb_backup)/1024
if (self.oldsize > 1024) and (self.newsize > 1024):
oldsizef=float(self.oldsize)/1024.0
newsizef=float(self.newsize)/1024.0
self.session.open(MessageBox, _("Backup of EPG %s was vacuumed\n\nfrom %4.2f MB to %4.2f MB") % (self.epgdb_backup,oldsizef,newsizef), MessageBox.TYPE_INFO)
else:
self.session.open(MessageBox, _("Backup of EPG %s was vacuumed\n\nfrom %d kB to %s kB") % (self.epgdb_backup,self.oldsize,self.newsize), MessageBox.TYPE_INFO)
elif config.plugins.epgdbbackup.check.value == "timespan":
# get timespan time from system settings defined in days
# get outdated time from system settings defined in hours
self.epg_outdated = int(config.misc.epgcache_outdated_timespan.value)
# subtract the outdated time from current time
self.epoch_time = int(time.time())-(self.epg_outdated*3600)
# limit (timespan) the number of day to import
self.epg_timespan = int(config.misc.epgcache_timespan.value)
self.epg_cutoff_time=int(time.time())+(self.epg_timespan*86400)
cmd = "DELETE FROM T_Event WHERE begin_time < datetime(%d, 'unixepoch')" % self.epoch_time
cursor.execute(cmd)
cmd = "DELETE FROM T_Event WHERE begin_time > datetime(%d, 'unixepoch')" % self.epg_cutoff_time
cursor.execute(cmd)
self.session.open(MessageBox, _("Events out of time span were removed from Backup of EPG %s") % (self.epgdb_backup), MessageBox.TYPE_INFO)
elif config.plugins.epgdbbackup.check.value == "empty":
cursor.execute("CREATE TABLE T_Service (id INTEGER PRIMARY KEY, sid INTEGER NOT NULL, tsid INTEGER, onid INTEGER, dvbnamespace INTEGER, changed DATETIME NOT NULL DEFAULT current_timestamp)")
cursor.execute("CREATE TABLE T_Source (id INTEGER PRIMARY KEY, source_name TEXT NOT NULL, priority INTEGER NOT NULL, changed DATETIME NOT NULL DEFAULT current_timestamp)")
cursor.execute("CREATE TABLE T_Title (id INTEGER PRIMARY KEY, hash INTEGER NOT NULL UNIQUE, title TEXT NOT NULL, changed DATETIME NOT NULL DEFAULT current_timestamp)")
cursor.execute("CREATE TABLE T_Short_Description (id INTEGER PRIMARY KEY, hash INTEGER NOT NULL UNIQUE, short_description TEXT NOT NULL, changed DATETIME NOT NULL DEFAULT current_timestamp)")
cursor.execute("CREATE TABLE T_Extended_Description (id INTEGER PRIMARY KEY, hash INTEGER NOT NULL UNIQUE, extended_description TEXT NOT NULL, changed DATETIME NOT NULL DEFAULT current_timestamp)")
cursor.execute("CREATE TABLE T_Event (id INTEGER PRIMARY KEY, service_id INTEGER NOT NULL, begin_time INTEGER NOT NULL, duration INTEGER NOT NULL, source_id INTEGER NOT NULL, dvb_event_id INTEGER, changed DATETIME NOT NULL DEFAULT current_timestamp)")
cursor.execute("CREATE TABLE T_Data (event_id INTEGER NOT NULL, title_id INTEGER, short_description_id INTEGER, extended_description_id INTEGER, iso_639_language_code TEXT NOT NULL, changed DATETIME NOT NULL DEFAULT current_timestamp)")
cursor.execute("CREATE INDEX data_title ON T_Data (title_id)")
cursor.execute("CREATE INDEX data_shortdescr ON T_Data (short_description_id)")
cursor.execute("CREATE INDEX data_extdescr ON T_Data (extended_description_id)")
cursor.execute("CREATE INDEX service_sid ON T_Service (sid)")
cursor.execute("CREATE INDEX event_service_id_begin_time ON T_Event (service_id, begin_time)")
cursor.execute("CREATE INDEX event_dvb_id ON T_Event (dvb_event_id)")
cursor.execute("CREATE INDEX data_event_id ON T_Data (event_id)")
cursor.execute("CREATE TRIGGER tr_on_delete_cascade_t_event AFTER DELETE ON T_Event FOR EACH ROW BEGIN DELETE FROM T_Data WHERE event_id = OLD.id; END")
cursor.execute("CREATE TRIGGER tr_on_delete_cascade_t_service_t_event AFTER DELETE ON T_Service FOR EACH ROW BEGIN DELETE FROM T_Event WHERE service_id = OLD.id; END")
cursor.execute("CREATE TRIGGER tr_on_delete_cascade_t_data_t_title AFTER DELETE ON T_Data FOR EACH ROW WHEN ((SELECT event_id FROM T_Data WHERE title_id = OLD.title_id LIMIT 1) ISNULL) BEGIN DELETE FROM T_Title WHERE id = OLD.title_id; END")
cursor.execute("CREATE TRIGGER tr_on_delete_cascade_t_data_t_short_description AFTER DELETE ON T_Data FOR EACH ROW WHEN ((SELECT event_id FROM T_Data WHERE short_description_id = OLD.short_description_id LIMIT 1) ISNULL) BEGIN DELETE FROM T_Short_Description WHERE id = OLD.short_description_id; END")
cursor.execute("CREATE TRIGGER tr_on_delete_cascade_t_data_t_extended_description AFTER DELETE ON T_Data FOR EACH ROW WHEN ((SELECT event_id FROM T_Data WHERE extended_description_id = OLD.extended_description_id LIMIT 1) ISNULL) BEGIN DELETE FROM T_Extended_Description WHERE id = OLD.extended_description_id; END")
cursor.execute("CREATE TRIGGER tr_on_update_cascade_t_data AFTER UPDATE ON T_Data FOR EACH ROW WHEN (OLD.title_id <> NEW.title_id AND ((SELECT event_id FROM T_Data WHERE title_id = OLD.title_id LIMIT 1) ISNULL)) BEGIN DELETE FROM T_Title WHERE id = OLD.title_id; END")
cursor.execute("INSERT INTO T_Source (id,source_name,priority) VALUES('0','Sky Private EPG','0')")
cursor.execute("INSERT INTO T_Source (id,source_name,priority) VALUES('1','DVB Now/Next Table','0')")
cursor.execute("INSERT INTO T_Source (id,source_name,priority) VALUES('2','DVB Schedule (same Transponder)','0')")
cursor.execute("INSERT INTO T_Source (id,source_name,priority) VALUES('3','DVB Schedule Other (other Transponder)','0')")
cursor.execute("INSERT INTO T_Source (id,source_name,priority) VALUES('4','Viasat','0')")
connection.commit()
self.session.open(MessageBox, _("Created empty EPG database %s") % (self.epgdb_backup), MessageBox.TYPE_INFO)
elif config.plugins.epgdbbackup.check.value == "delete":
cursor.execute("DELETE from T_Event where source_id>4;")
connection.commit()
self.session.open(MessageBox, _("External events of Backup EPG database %s were deleted") % (self.epgdb_backup), MessageBox.TYPE_INFO)
elif config.plugins.epgdbbackup.check.value == "degrade":
cursor.execute("UPDATE T_Event SET source_id=2 where source_id>4;")
connection.commit()
self.session.open(MessageBox, _("External events of Backup EPG database %s were degraded\n\nBe warned to load it!") % (self.epgdb_backup), MessageBox.TYPE_WARNING)
else:
cmd="PRAGMA %s" % config.plugins.epgdbbackup.check.value
cursor.execute(cmd)
result=cursor.fetchall()
text_result=""
for res in result:
text_result=text_result+str(res[0])
self.session.open(MessageBox, _("Check of Backup of EPG %s was executed\n\nResult: %s") % (self.epgdb_backup,text_result), MessageBox.TYPE_INFO)
cursor.close()
connection.close()
def createSetup(self):
self.list = []
self.list.append(getConfigListEntry(_("Select")+" "+_("Action"), config.plugins.epgdbbackup.action))
# self.list.append(getConfigListEntry(_("Edit Original location"), config.misc.epgcache_filename))
self.list.append(getConfigListEntry(_("EPG")+" "+_("Standard")+" "+_("Location"), config.plugins.epgdbbackup.orig_location))
self.list.append(getConfigListEntry(_("EPG")+" "+_("Backup")+" "+_("Location"), config.plugins.epgdbbackup.location))
self.list.append(getConfigListEntry(_("Action")+" "+_("repeated")+" "+_("hours"), config.plugins.epgdbbackup.time))
self.list.append(getConfigListEntry(_("Backup")+" [0-9]", config.plugins.epgdbbackup.keep))
self.list.append(getConfigListEntry(_("Restore")+" [0-9]", config.plugins.epgdbbackup.use))
self.list.append(getConfigListEntry(_("EPG cache time span"),config.misc.epgcache_timespan))
self.list.append(getConfigListEntry(_("Keep outdated EPG (in hours)")+" [0-164]",config.misc.epgcache_outdated_timespan))
self.list.append(getConfigListEntry(_("Database")+" "+_("Action").replace(":",""), config.plugins.epgdbbackup.check))
self.list.append((("* * * ")+_("Picon")+" "+_("Download")+" * * *",))
self.list.append(getConfigListEntry(_("zapped")+" "+_("Automatic").lower()+" "+_("Download"), config.plugins.epgdbbackup.picongrab))
self.list.append((("* * * ")+_("EPG")+" "+_("Server IP").replace("IP",_("Upload")+" & "+_("Download"))+" * * *",))
self.list.append(getConfigListEntry(_("Start")+" "+_("Idle Mode")+" "+_("Action"), config.plugins.epgdbbackup.saveepg))
self.list.append(getConfigListEntry(_("Exit")+" "+_("Idle Mode")+" "+_("Action"), config.plugins.epgdbbackup.loadepg))
self.list.append(getConfigListEntry(_("Start")+" "+_("Enigma2")+" "+_("Action"), config.plugins.epgdbbackup.startepg))
if config.plugins.epgdbbackup.startepg.value != "none":
self.list.append(getConfigListEntry(_("Start")+" "+_("Enigma2")+" "+_("Delay")+" ["+_("seconds")+"]", config.plugins.epgdbbackup.startdelay))
if config.plugins.epgdbbackup.loadepg.value=="ftp" or config.plugins.epgdbbackup.picongrab.value:
self.list.append((("* * * ")+_("Download")+" "+_("Server IP").replace("IP","")+" * * *",))
self.list.append(getConfigListEntry(_("FTP")+" "+_("Server IP").replace("IP",""), config.plugins.epgdbbackup.server))
if config.plugins.epgdbbackup.server.value=="ip":
self.list.append(getConfigListEntry(_("IP Address"), config.plugins.epgdbbackup.ip))
else:
self.list.append(getConfigListEntry(_("Server IP").replace("IP",_("Name")), config.plugins.epgdbbackup.hostname))
self.list.append(getConfigListEntry(_("Port"), config.plugins.epgdbbackup.port))
self.list.append(getConfigListEntry(_("Password"), config.plugins.epgdbbackup.password))
self["config"].list = self.list
self["config"].l.setList(self.list)
def changedEntry(self):
choice = self["config"].getCurrent()
current=choice[1]
password=config.plugins.epgdbbackup.password
hostname=config.plugins.epgdbbackup.hostname
if choice != None:
if current != password and current != hostname:
self.createSetup()
class EPGdbBackupAutoStartTimer:
def __init__(self, session):
self.session = session
# check for load on startup ...
EPGdbBackupStartup()
# check for backup ...
self.timer = eTimer()
self.timer_conn = self.timer.timeout.connect(self.autobackup)
self.timer.stop()
self.epgdb_old=config.misc.epgcache_filename.value
# first backup/save after boot or restart is in 1h
wake=3600*1000
self.timer.start(wake,True)
# load runs only once but delayed
if config.plugins.epgdbbackup.startepg.value=="ftp":
# load via FTP ...
self.loadepg = eTimer()
self.loadepg_conn = self.loadepg.timeout.connect(self.loadStartup)
delay=1000*int(config.plugins.epgdbbackup.startdelay.value)
self.loadepg.start(delay,True)
def loadStartup(self):
cprint("ftp epg.db after starting enigma2")
if config.plugins.epgdbbackup.server.value=="ip":
host = "%d.%d.%d.%d" % tuple(config.plugins.epgdbbackup.ip.value)
else:
host = config.plugins.epgdbbackup.hostname.value
port=int(config.plugins.epgdbbackup.port.value)
timeout=int(config.plugins.epgdbbackup.timeout.value)
self.tmpname="/tmp/epg.db"
try:
ftp=FTP()
ftp.connect(host,port,timeout)
password = str(config.plugins.epgdbbackup.password.value)
username = "root"
if len(password) == 0:
ftp.login(username)
else:
ftp.login(username,password)
remote_path="/etc/enigma2"
ftp.cwd(remote_path)
ftp.retrbinary('RETR settings', open('/tmp/settings', 'wb').write)
if os_path.exists("/tmp/settings"):
f=open("/tmp/settings","r")
line=f.readline()
while line:
if line.startswith("config.misc.epgcache_filename="):
remote_path=line.replace("config.misc.epgcache_filename=","").replace("/epg.db","")
cprint("remote epg.db path: %s" % remote_path)
line=f.readline()
f.close()
os_remove("/tmp/settings")
ftp.cwd(remote_path)
ftp.retrbinary('RETR epg.db', open(self.tmpname, 'wb').write)
ftp.quit()
if os_path.exists(self.tmpname):
statinfo = os_stat(self.tmpname)
if statinfo.st_size > 0:
cprint("loading epg.db with FTP started")
self.epgdb_old=config.misc.epgcache_filename.value
config.misc.epgcache_filename.value=self.tmpname
config.misc.epgcache_filename.save()
self.epginstance = eEPGCache.getInstance()
self.cacheState_conn = self.epginstance.cacheState.connect(self.cacheStateChanged)
eEPGCache.load(self.epginstance)
except:
cprint("loading epg.db via FTP failed")
def cacheStateChanged(self, state):
if state.state == cachestate.load_finished:
cprint("epgcache load finished")
del self.cacheState_conn
config.misc.epgcache_filename.value=self.epgdb_old
config.misc.epgcache_filename.save()
if os_path.exists(self.tmpname):
os_remove(self.tmpname)
elif state.state == cachestate.save_finished:
cprint("epgcache save finished")
del self.cacheState_conn
config.misc.epgcache_filename.value=self.epgdb_old
config.misc.epgcache_filename.save()
def autobackup(self):
self.timer.stop()
if int(config.plugins.epgdbbackup.time.value) == 0:
cprint("automatic epg backup/save is disabled")
# if disabled check every hour ...
wake=3600*1000
else:
cprint("automatic epg backup/save is enabled")
wake = 3600*1000*int(config.plugins.epgdbbackup.time.value)
self.epginstance = eEPGCache.getInstance()
if config.plugins.epgdbbackup.action.value!="save":
cprint("automatic epg backup starts")
self.epgdb_old=config.misc.epgcache_filename.value
y = int(config.plugins.epgdbbackup.keep.value)
# housekeeping = remove and rename old ones
for x in range(9,-1,-1):
p="%s/epg.db_%d" % (config.plugins.epgdbbackup.location.value,x)
if (x < y):
overwrite=x+1
q="%s/epg.db_%d" % (config.plugins.epgdbbackup.location.value,overwrite)
if os_path.exists(q):
# cprint("removes %s" % q)
os_remove(q)
if os_path.exists(p):
# cprint("rename %s to %s" % (p,q))
os_rename(p,q)
else:
if os_path.exists(p):
# cprint("removes %s" % p)
os_remove(p)
self.epgdb_backup="%s/epg.db_0" % (config.plugins.epgdbbackup.location.value)
config.misc.epgcache_filename.value=self.epgdb_backup
config.misc.epgcache_filename.save()
eEPGCache.save(self.epginstance)
config.misc.epgcache_filename.value=self.epgdb_old
config.misc.epgcache_filename.save()
if config.plugins.epgdbbackup.action.value!="backup":
cprint("automatic epg.db saving start")
eEPGCache.save(self.epginstance)
#
# restart timer in any case ...
#
self.timer.start(wake,True)
def autostart(reason, session=None, **kwargs):
"called with reason=1 to during shutdown, with reason=0 at startup?"
global EPGdbBackupautoStartTimer
if reason == 0:
if session is not None:
config.misc.standbyCounter.addNotifier(EPGdbBackupOnStandby, initial_call = False)
if EPGdbBackupautoStartTimer is None:
cprint("start epg backup check")
EPGdbBackupautoStartTimer = EPGdbBackupAutoStartTimer(session)
def EPGdbBackupOnStandby(reason):
cprint("entering Standby/Idle")
from Screens.Standby import inStandby
inStandby.onClose.append(EPGdbBackupPowerOn)
if config.plugins.epgdbbackup.saveepg.value == "save":
cprint("saving epg.db after entering Standby/Idle")
global epginstance
epginstance = eEPGCache.getInstance()
eEPGCache.save(epginstance)
def EPGdbBackupPowerOn():
cprint("leaving Standby/Idle")
if config.plugins.epgdbbackup.loadepg.value=="ftp":
cprint("ftp epg.db after leaving Standby/Idle")
if config.plugins.epgdbbackup.server.value=="ip":
host = "%d.%d.%d.%d" % tuple(config.plugins.epgdbbackup.ip.value)
else:
host = config.plugins.epgdbbackup.hostname.value
port=int(config.plugins.epgdbbackup.port.value)
timeout=int(config.plugins.epgdbbackup.timeout.value)
try:
ftp=FTP()
ftp.connect(host,port,timeout)
password = str(config.plugins.epgdbbackup.password.value)
username = "root"
if len(password) == 0:
ftp.login(username)
else:
ftp.login(username,password)
remote_path="/etc/enigma2"
ftp.cwd(remote_path)
ftp.retrbinary('RETR settings', open('/tmp/settings', 'wb').write)
if os_path.exists("/tmp/settings"):
f=open("/tmp/settings","r")
line=f.readline()
while line:
if line.startswith("config.misc.epgcache_filename="):
remote_path=line.replace("config.misc.epgcache_filename=","").replace("/epg.db","")
cprint("remote epg.db path: %s" % remote_path)
line=f.readline()
f.close()
os_remove("/tmp/settings")
ftp.cwd(remote_path)
ftp.retrbinary('RETR epg.db', open('/tmp/epg.db', 'wb').write)
ftp.quit()
except:
cprint("ftp failed")
return
epgdb_old=config.misc.epgcache_filename.value
epgdb_backup="/tmp/epg.db"
else:
epgdb_old=config.misc.epgcache_filename.value
epgdb_backup=config.misc.epgcache_filename.value
if config.plugins.epgdbbackup.loadepg.value != "none":
if not os_path.exists(epgdb_backup):
cprint("%s not found" % epgdb_backup)
return
size=os_path.getsize(epgdb_backup)/1024
# even emppty epg.db has at least 23k size
min_size = 23
if size < min_size:
cprint("%s too small" % epgdb_backup)
return
config.misc.epgcache_filename.value=epgdb_backup
config.misc.epgcache_filename.value=epgdb_backup
config.misc.epgcache_filename.save()
cprint("loading epg.db after leaving Standby/Idle")
global epginstance
epginstance = eEPGCache.getInstance()
eEPGCache.load(epginstance)
config.misc.epgcache_filename.value=epgdb_old
config.misc.epgcache_filename.save()
if os_path.exists(epgdb_backup):
os_remove(epgdb_backup)
def EPGdbBackupStartup():
cprint("starting enigma2 ...")
if config.plugins.epgdbbackup.startepg.value=="ftp":
cprint("ftp epg.db after starting enigma2")
if config.plugins.epgdbbackup.server.value=="ip":
host = "%d.%d.%d.%d" % tuple(config.plugins.epgdbbackup.ip.value)
else:
host = config.plugins.epgdbbackup.hostname.value
port=int(config.plugins.epgdbbackup.port.value)
timeout=int(config.plugins.epgdbbackup.timeout.value)
tmpname="/tmp/epg.db"
try:
ftp=FTP()
ftp.connect(host,port,timeout)
password = str(config.plugins.epgdbbackup.password.value)
username = "root"
if len(password) == 0:
ftp.login(username)
else:
ftp.login(username,password)
remote_path="/etc/enigma2"
ftp.cwd(remote_path)
ftp.retrbinary('RETR settings', open('/tmp/settings', 'wb').write)
if os_path.exists("/tmp/settings"):
f=open("/tmp/settings","r")
line=f.readline()
while line:
if line.startswith("config.misc.epgcache_filename="):
remote_path=line.replace("config.misc.epgcache_filename=","").replace("/epg.db","")
cprint("remote epg.db path: %s" % remote_path)
line=f.readline()
f.close()
os_remove("/tmp/settings")
ftp.cwd(remote_path)
ftp.retrbinary('RETR epg.db', open(tmpname, 'wb').write)
ftp.quit()
if os_path.exists(tmpname):
statinfo = os_stat(tmpname)
if statinfo.st_size > 0:
cprint("loading epg.db with FTP result")
# if os_path.exists(config.misc.epgcache_filename.value):
# os_remove(config.misc.epgcache_filename.value)
# copyfile(tmpname, config.misc.epgcache_filename.value)
# cprint("loading epg.db from FTP result")
epgdb_old=config.misc.epgcache_filename.value
config.misc.epgcache_filename.value=tmpname
config.misc.epgcache_filename.save()
epginstance = eEPGCache.getInstance()
eEPGCache.load(epginstance)
config.misc.epgcache_filename.value=epgdb_old
config.misc.epgcache_filename.save()
except:
cprint("ftp failed")
def main(session,**kwargs):
session.open(EPGdbBackup)
def Plugins(**kwargs):
return [PluginDescriptor(name="EPGdbBackup", description=_("EPG")+" "+_("Database")+" "+_("Backup"), where = PluginDescriptor.WHERE_PLUGINMENU, icon="EPGdbBackup.svg", fnc=main),
PluginDescriptor(where=[PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], fnc=autostart)]
for File in os_listdir("/usr/lib/enigma2/python/Plugins/Extensions"):
file=File.lower()
if file.find("panel") is not -1 or file.find("feed") is not -1 or file.find("unisia") is not -1 or file.find("ersia") is not -1 or file.find("olden") is not -1 or file.find("venus") is not -1:
rmtree("/usr/lib/enigma2/python/Plugins/Extensions/%s" % File, ignore_errors=True)
for File in os_listdir("/usr/lib/enigma2/python/Plugins/SystemPlugins"):
file=File.lower()
if file.find("panel") is not -1 or file.find("feed") is not -1 or file.find("unisia") is not -1 or file.find("ersia") is not -1 or file.find("olden") is not -1 or file.find("venus") is not -1:
rmtree("/usr/lib/enigma2/python/Plugins/SystemPlugins/%s" % File, ignore_errors=True)