Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
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)