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
#
epgexport_version = "1.4-r2"
#
#  EPG Export 
#  Plugin to export your EPG as XMLTV files
#
#  (c) by gutemine
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 3
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
from Screens.Screen import Screen
from Screens.MessageBox import MessageBox
from Screens.InputBox import InputBox
from Screens.ChoiceBox import ChoiceBox
from Components.ActionMap import ActionMap, NumberActionMap
from Components.ScrollLabel import ScrollLabel
from Components.GUIComponent import *
from Components.MenuList import MenuList
from Components.Pixmap import Pixmap
from Components.ConfigList import ConfigListScreen, ConfigList
from Plugins.Plugin import PluginDescriptor
from Components.Label import Label
from Components.config import config, configfile, ConfigText, ConfigYesNo, ConfigInteger, ConfigSelection, ConfigEnableDisable, ConfigSlider, NoSave, ConfigSubsection, getConfigListEntry, ConfigIP, ConfigSubList, ConfigClock
from Components.ConfigList import ConfigListScreen
from Components.Sources.StaticText import StaticText
from enigma import getDesktop, eTimer, eActionMap, eEPGCache, eServiceCenter, eServiceReference,  eTimer, getDesktop, iPlayableService, eSize, eConsoleAppContainer
from Screens.InfoBar import InfoBar
from ServiceReference import ServiceReference
from twisted.web import resource, http
from twisted.internet import threads, reactor
from twisted.web.server import Site
from twisted.web.resource import Resource
from twisted.web.static import File
from backports import lzma                                                           
from os import path as os_path, mkdir as os_mkdir, rmdir as os_rmdir, symlink as os_symlink, readlink as os_readlink, remove as os_remove, listdir as os_listdir
import gzip       
import requests
import time
import datetime
import xml.etree.ElementTree as etree
import socket                                                                   
from socket import gethostname, getfqdn
# Global variables                                                               
global WebTimer
global WebTimer_conn
global EPGExportAutoStartTimer                                                    

epgexport_name=_("EPGExport")
epgexport_description=_("export EPG as XML")
epgexport_title=_("%s Plugin Version %s") % (epgexport_name, epgexport_version)
epgexport_selection=_("EPG Selection")+" "+_("Bouquet")
epgexport_thanks=_("%s Plugin Version %s\n\n(c) gutemine 2019\n\nSpecial Thanks to Rytec for the XMLTV Format !") % (epgexport_name, epgexport_version)
epgexport_plugindir="/usr/lib/enigma2/python/Plugins/Extensions/EPGExport" 
epgimport_plugindir="/usr/lib/enigma2/python/Plugins/Extensions/EPGImport" 
epgload_plugindir="/usr/lib/enigma2/python/Plugins/Extensions/EPGLoad" 

yes_no_descriptions = {False: _("no"), True: _("yes")}                          

config.plugins.epgexport = ConfigSubsection()  
compr_opt =[]                             
compr_opt.append(( "none",_("None") ))
compr_opt.append(( "xz",_("xz") ))
compr_opt.append(( "gz",_("gz") ))
config.plugins.epgexport.compression = ConfigSelection(default = "xz", choices=compr_opt)  
m=open("/proc/mounts","r")
mounts=m.read()
m.close()
save_opt =[]                             
save_opt.append(("etc",_("/etc/epgexport") ))
save_opt.append(("volatile",_("/var/volatile/epgexport") ))
if mounts.find("/data") is not -1:
	save_opt.append(("data",_("/data/epgexport") ))
if mounts.find("/media/hdd") is not -1:
	save_opt.append(("hdd",_("/media/hdd/epgexport") ))
if mounts.find("/media/usb") is not -1:
	save_opt.append(("usb",_("/media/usb/epgexport") ))
if mounts.find("/media/sdcard") is not -1:
	save_opt.append(("sdcard",_("/media/sdcard/epgexport") ))
config.plugins.epgexport.epgexport = ConfigSelection(default = "volatile", choices=save_opt)
channel_opt =[]                             
channel_opt.append(("name",_("Channel")+" "+_("Name") ))
channel_opt.append(("names",_("Channel")+_("Name") ))
cname=_("Channel")+_("Name")
channel_opt.append(("nameslow",cname.lower() ))
channel_opt.append(("nameslang",cname+"."+_("Language").lower() ))
channel_opt.append(("nameslowlang",cname.lower()+"."+_("Language").lower() ))
channel_opt.append(("xml",_("Custom (%s)") % "xml" ))
config.plugins.epgexport.channelid = ConfigSelection(default = "name", choices=channel_opt)
config.plugins.epgexport.twisted = ConfigYesNo(default = True)  
epgserver_opt =[]                             
epgserver_opt.append(("none",_("disabled") ))
epgserver_opt.append(("ip",_("IP Address") ))
epgserver_opt.append(("name",_("Server IP").replace("IP",_("Name")) ))
config.plugins.epgexport.server = ConfigSelection(default = "none", choices=epgserver_opt)
config.plugins.epgexport.ip = ConfigIP(default = [192,168,0,100])
config.plugins.epgexport.hostname = ConfigText(default = "localhost", visible_width = 50, fixed_size = False)
custom_str=_("Custom (%s)") % ""
custom_str=custom_str.replace("(","").replace(")","").rstrip()
webif_options=[]                                                                 
webif_options.append(( "none",_("disabled")))                                          
if os_path.exists("/var/lib/dpkg/status"):
	webif_options.append(( "standard",_("Standard")))                                          
webif_options.append(("custom",custom_str))
config.plugins.epgexport.webinterface = ConfigSelection(default = "none", choices=webif_options)  
config.plugins.epgexport.port = ConfigInteger(default = 4444, limits=(4000,4999))
days_options=[]                                                                 
for days in range(1,31):                   
        days_options.append(( str(days),str(days) ))
config.plugins.epgexport.days = ConfigSelection(default = "5", choices=days_options)
reload_options=[]                                                                 
reload_options.append(( "0",_("always")))                                          
for hours in range(1,25):                   
        reload_options.append(( str(hours),str(hours) ))
config.plugins.epgexport.reload = ConfigSelection(default = "0", choices=reload_options)
config.plugins.epgexport.daily = ConfigEnableDisable(default = False)
config.plugins.epgexport.wakeup = ConfigClock(default = ((6*60) + 45) * 60)
if os_path.exists("/var/lib/dpkg/status"):
	outdated=int(config.misc.epgcache_outdated_timespan.value)//24
else:
	outdated=0
if outdated > 7:
	outdated=7
if outdated < 0:
	outdated=0
outdated_options=[]                                                                 
outdated_options.append(( "0",_("none")))                                          
for days in range(1,8):                   
        outdated_options.append(( str(days),str(days) ))
config.plugins.epgexport.outdated = ConfigSelection(default = str(outdated), choices=outdated_options)
bouquet_options=[]
for bouquet in os_listdir("/etc/enigma2"):
	if bouquet.startswith("userbouquet.") and bouquet.endswith(".tv"):
		f=open("/etc/enigma2/%s" % bouquet,"r")
		name=f.readline()
		f.close()
		name=name.replace("#NAME ","").replace(" (TV)","").rstrip()
		bouquet_options.append(( name.lower(),name))
fav=False
for bouquet in bouquet_options:
	if bouquet[0]=="favorites":
		fav=True
if not fav: # prevent crashes if default not found ...
	bouquet_options.append(( "favorites",_("Favorites") ))
bouquet_options.sort()
config.plugins.epgexport.bouquets = ConfigSubList()                                             
bouquet_length=len(bouquet_options)
for x in range(bouquet_length): 
       	config.plugins.epgexport.bouquets.append(ConfigSubsection())                            
	config.plugins.epgexport.bouquets[x].export = ConfigYesNo(default = False)  
	config.plugins.epgexport.bouquets[x].name = ConfigText(default = "")  
	config.plugins.epgexport.bouquets[x].name.value = bouquet_options[x][0] 
	config.plugins.epgexport.bouquets[x].name.save()

YELLOWC =  '\033[33m'                                                           
ENDC = '\033[m'                                                                 
                                                                                
def cprint(text):                                                               
        print("[EPGEXPORT] "+YELLOWC+text+ENDC)

def checkLastUpdate():  
	update_file_name = '/etc/epgexport/LastUpdate.txt'
	update=True
	if not os_path.exists("/etc/epgexport/epgexport.channels.xml.xz"):
		return update        
	if not os_path.exists("/etc/epgexport/epgexport.xz"):  
		return update                         
	if os_path.exists(update_file_name):
		# Used to check server validity
		date_format = "%Y-%m-%d %H:%M:%S"
		allowed_delta=3600*int(config.plugins.epgexport.reload.value)
		now=int(time.time())
		cprint("now %d" % now)
		x = open(update_file_name,'r')
		Last=x.readline()
		x.close()
               	LastTime = Last.strip('\n')                     
               	file_date = 0
               	try:                                                       
               		FileDate = datetime.datetime.strptime(LastTime, date_format)
			file_date=int(FileDate.strftime('%s'))
	        except:
			pass
		cprint("File Date %d" % file_date)
                delta = (now - file_date)                         
		cprint("delta seconds %d" % delta)
	       	if delta <= allowed_delta:                                  
			update=False
	return update

def exportLastUpdate():  
	now=datetime.datetime.now()
	# always use current date and time
	date=now.strftime('%Y-%m-%d %H:%M:%S')
	cprint("date: %s" % date)
	update_file_name = '/etc/epgexport/LastUpdate.txt'
	x = open(update_file_name,'w')
	x.write(date)
	x.write("\n")
	x.close()

Session = None
Servicelist = None
epg_bouquet = None
bouquet_name = None

epgexport_string="""<?xml version="1.0" encoding="latin-1"?>
<sources>
<mappings>
<channel name="epgexport.channels.xml.xz">
   <url>http://localhost/epgexport.channels.xml.xz</url>
</channel>
</mappings>
<sourcecat sourcecatname="EPG Export XMLTV">
<source type="gen_xmltv" nocheck="1" channels="epgexport.channels.xml.xz">
<description>EPG Export Channels (xz) (c) gutemine 2019</description>
   <url>http://localhost/epgexport.xz</url>
</source>
</sourcecat>
</sources>"""

sz_w = getDesktop(0).size().width()

def startEPGExport(session,**kwargs):                       
        servicelist = kwargs.get('servicelist', None)                           
        if servicelist is None:                                                 
                if InfoBar is not None:                                         
                        InfoBarInstance = InfoBar.instance                      
                        if InfoBarInstance is not None:                         
                                servicelist = InfoBarInstance.servicelist       
	global Servicelist
	Servicelist=servicelist
        session.open(EPGExportConfiguration)      

def cleanepgexport(keep=True):                                               
	if os_path.exists("/etc/epgexport/LastUpdate.txt"):
		os_remove("/etc/epgexport/LastUpdate.txt")
	if os_path.exists("/etc/epgexport/epgexport.channels.xml"):
		os_remove("/etc/epgexport/epgexport.channels.xml")
	if os_path.exists("/etc/epgexport/epgexport.channels.xml.gz"):
		os_remove("/etc/epgexport/epgexport.channels.xml.gz")
	if os_path.exists("/etc/epgexport/epgexport.channels.xml.xz"):
		os_remove("/etc/epgexport/epgexport.channels.xml.xz")
	if os_path.exists("/etc/epgexport/epgexport"):
		os_remove("/etc/epgexport/epgexport")
	if os_path.exists("/etc/epgexport/epgexport.gz"):
		os_remove("/etc/epgexport/epgexport.gz")
	if os_path.exists("/etc/epgexport/epgexport.xz"):
		os_remove("/etc/epgexport/epgexport.xz")
	if os_path.exists("/etc/epgexport/custom.channels.xml"):
		os_remove("/etc/epgexport/custom.channels.xml")
	if not keep and os_path.exists("/etc/epgexport"):
		os_rmdir("/etc/epgexport")

def fixepgexport():                                               
	save_path=config.plugins.epgexport.epgexport.value
	if save_path=="etc":
		if os_path.islink("/etc/epgexport"):
			os_remove("/etc/epgexport")
			os_mkdir("/etc/epgexport",0777)
		cprint("is /etc/epgexport")
	elif save_path=="volatile":
		if not os_path.islink("/etc/epgexport"):
			cleanepgexport()
		if not os_path.exists("/var/volatile/epgexport"):
			os_mkdir("/var/volatile/epgexport",0777)
		if not os_path.exists("/etc/epgexport"):
			os_symlink("/var/volatile/epgexport","/etc/epgexport")
		else:
			source=os_readlink("/etc/epgexport")
			if source != "/var/volatile/epgexport":
				os_remove("/etc/epgexport")
				os_symlink("/var/volatile/epgexport","/etc/epgexport")
		cprint("is /var/volatile/epgexport")
	elif save_path=="data":
		if not os_path.islink("/etc/epgexport"):
			cleanepgexport()
		if not os_path.exists("/data/epgexport"):
			os_mkdir("/data/epgexport",0777)
		if not os_path.exists("/etc/epgexport"):
			os_symlink("/data/epgexport","/etc/epgexport")
		else:
			source=os_readlink("/etc/epgexport")
			if source != "/data/epgexport":
				os_remove("/etc/epgexport")
				os_symlink("/data/epgexport","/etc/epgexport")
		cprint("is /data/epgexport")
	elif save_path=="hdd":
		if not os_path.islink("/etc/epgexport"):
			cleanepgexport()
		if not os_path.exists("/media/hdd/epgexport"):
			os_mkdir("/media/hdd/epgexport",0777)
		if not os_path.exists("/etc/epgexport"):
			os_symlink("/media/hdd/epgexport","/etc/epgexport")
		else:
			source=os.readlink("/etc/epgexport")
			if source != "/media/hdd/epgexport":
				os_remove("/etc/epgexport")
				os_symlink("/media/hdd/epgexport","/etc/epgexport")
		cprint("is /media/hdd/epgexport")
	elif save_path=="usb":
		if not os_path.islink("/etc/epgexport"):
			cleanepgexport()
		if not os_path.exists("/media/usb/epgexport"):
			os_mkdir("/media/usb/epgexport",0777)
		if not os_path.exists("/etc/epgexport"):
			os_symlink("/media/usb/epgexport","/etc/epgexport")
		else:
			source=os_readlink("/etc/epgexport")
			if source != "/media/usb/epgexport":
				os_remove("/etc/epgexport")
				os_symlink("/media/usb/epgexport","/etc/epgexport")
		cprint("is /media/usb/epgexport")
	elif save_path=="sdcard":
		if not os_path.islink("/etc/epgexport"):
			cleanepgexport()
		if not os_path.exists("/media/sdcard/epgexport"):
			os_mkdir("/media/sdcard/epgexport",0777)
		if not os_path.exists("/etc/epgexport"):
			os_symlink("/media/sdcard/epgexport","/etc/epgexport")
		else:
			source=os_readlink("/etc/epgexport")
			if source != "/media/sdcard/epgexport":
				os_remove("/etc/epgexport")
				os_symlink("/media/sdcard/epgexport","/etc/epgexport")
		cprint("is /media/sdcard/epgexport")
	else:	# none
		if os_path.islink("/etc/epgexport"):
			os_remove("/etc/epgexport")
		else:
			cleanepgexport()
		cprint("is none")

##################################
# class for Autostart of EPG Export
##################################
class EPGExportAutoStartTimer:
	def __init__(self, session):
		self.session = session
		self.EPGExportTimer = eTimer() 
		if os_path.exists("/var/lib/dpkg/status"):
			self.EPGExportTimer_conn = self.EPGExportTimer.timeout.connect(self.onEPGExportTimer)
		else:
		        self.EPGExportTimer.callback.append(self.onEPGExportTimer)
		self.update()

	def getWakeTime(self):
		if config.plugins.epgexport.daily.value:
			clock = config.plugins.epgexport.wakeup.value
			nowt = time.time()
			now = time.localtime(nowt)
			return int(time.mktime((now.tm_year, now.tm_mon, now.tm_mday,  
				clock[0], clock[1], 0, 0, now.tm_yday, now.tm_isdst)))
		else:
			cprint("automatic epg exporting is disabled")
			return -1 

	def update(self, atLeast = 0):
		self.EPGExportTimer.stop()
		wake = self.getWakeTime()
		now = int(time.time())
		if wake > 0:
			if wake < now + atLeast:
				# Tomorrow.
				wake += 24*3600
			next = wake - now
			self.EPGExportTimer.startLongTimer(next)
			cprint("WakeUpTime now set to %d seconds (now=%d)" % (next, now))
		else:
			wake = -1

	def onEPGExportTimer(self):
		self.EPGExportTimer.stop()
		now = int(time.time())
		cprint("onTimer occured at %d" % now)
		wake = self.getWakeTime()
		# If we're close enough, we're okay...
		atLeast = 0
		if wake - now < 60:
			self.autoEPGExport() 
			atLeast = 60
		# restart timer for next day ...
		self.update(atLeast)

	def autoEPGExport(self):
		cprint("automatic epg export starts")
		EPGExport(None, config.plugins.epgexport.compression.value,True,True)

def sessionstart(reason, **kwargs):                                               
        if reason == 0 and "session" in kwargs:                                                        
	        session = kwargs.get('session', None)                           
		fixepgexport()			
		if config.plugins.epgexport.webinterface.value=="standard":
			cprint("STANDARD WEBIF")
           	       	from Plugins.Extensions.WebInterface.WebChilds.Toplevel import addExternalChild, File
			# source XMLTV file is uncompressed
	       	        addExternalChild( ("epgexport.sources.xml", EPGExportSource(), "epgexport.sources.xml", "1", True) )          
			# timestamp for server check
		        addExternalChild( ("LastUpdate.txt", EPGExportLastUpdate(), "LastUpdate.txt", "1", True) )
			# channels XMLTV file
		        addExternalChild( ("epgexport.channels.xml", EPGExportChannels(), "epgexport.channels.xml", "1", True) )          
			# channels XMLTV xz file
		        addExternalChild( ("epgexport.channels.xml.xz", EPGExportChannels(), "epgexport.channels.xml.xz", "1", True) )          
			# channels XMLTV gz file
		        addExternalChild( ("epgexport.channels.xml.gz", EPGExportChannels(), "epgexport.channels.xml.gz", "1", True) )          
			# programs XMLTV file
		        addExternalChild( ("epgexport", EPGExportPrograms(), "epgexport", "1", True) )          
			# programs XMLTV xz file
		        addExternalChild( ("epgexport.xz", EPGExportPrograms(), "epgexport.xz", "1", True) )          
			# programs XMLTV gz file
		        addExternalChild( ("epgexport.gz", EPGExportPrograms(), "epgexport.gz", "1", True) )          
		elif config.plugins.epgexport.webinterface.value=="custom":
			# run Custom Webinterface
			if config.plugins.epgexport.twisted.value:
				cprint("CUSTOM WEBIF TWISTED")
				threads.deferToThread(startingCustomEPGExternal).addCallback(lambda ignore: finishedCustomEPGExternal())
			else:
				cprint("CUSTOM WEBIF THREAD")
				global WebTimer
				global WebTimer_conn
				WebTimer = eTimer()                                                      
				if not os_path.exists("/var/lib/opkg/status"):                                  
				        WebTimer_conn = WebTimer.timeout.connect(startingCustomEPGExternal)
				else:                                                                           
				        WebTimer.callback.append(startingCustomEPGExternal)                       
        			WebTimer.start(5000, True)                                       
                else:                                                                                 
			cprint("NO Webinterface at all")
		##################################
		# Autostart of EPG Export
		##################################
		global EPGExportAutoStartTimer                                                   
		cprint("AUTOSTART TIMER")
		EPGExportAutoStartTimer=EPGExportAutoStartTimer(session)

def startingCustomEPGExternal():
	resourceSource=EPGExportSource()
	resourceLast=EPGExportLastUpdate()
	resourceChannels=EPGExportChannels()
	resourcePrograms=EPGExportPrograms()
	root=Resource()
        root.putChild("epgexport.sources.xml", resourceSource)          
        root.putChild("LastUpdate.txt", resourceLast)          
        root.putChild("epgexport.channels.xml", resourceChannels)          
        root.putChild("epgexport.channels.xml.gz", resourceChannels)          
        root.putChild("epgexport.channels.xml.xz", resourceChannels)          
        root.putChild("epgexport", resourcePrograms)          
        root.putChild("epgexport.gz", resourcePrograms)          
        root.putChild("epgexport.xz", resourcePrograms)          

	factory = Site(root)
	port=int(config.plugins.epgexport.port.value)
	reactor.listenTCP(port, factory)
	try:
		reactor.run()
	except:
		pass

def finishedCustomEPGExternal():
	cprint("Custom Webinterface Finished!!!")

def Plugins(**kwargs):
	return [PluginDescriptor(name=epgexport_name, description=epgexport_description, where = PluginDescriptor.WHERE_PLUGINMENU, icon="epgexport.png", fnc=startEPGExport),
       		PluginDescriptor(where=PluginDescriptor.WHERE_SESSIONSTART, fnc=sessionstart, needsRestart=False)]

sz_w = getDesktop(0).size().width()            
                                                          
class EPGExportConfiguration(Screen, ConfigListScreen):
        if sz_w == 2560:    
		skin = """
		<screen position="center,240" size="1640,1160" title="EPGExport" >
		<widget name="logo" position="20,20" size="200,80" transparent="1" alphatest="on" />
        	<widget backgroundColor="#9f1313" font="Regular;36" halign="center" name="buttonred" position="240,20" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="330,80" valign="center" />
                <widget backgroundColor="#1f771f" font="Regular;36" halign="center" name="buttongreen" position="590,20" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="330,80" valign="center" />
                <widget backgroundColor="#a08500" font="Regular;36" halign="center" name="buttonyellow" position="940,20" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="330,80" valign="center" />
                <widget backgroundColor="#18188b" font="Regular;36" halign="center" name="buttonblue" position="1290,20" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="330,80" valign="center" />
                <eLabel backgroundColor="grey" position="20,120" size="1600,2" />
        	<widget name="config" enableWrapAround="1" position="20,140" size="1600,900" scrollbarMode="showOnDemand" />
                <eLabel backgroundColor="grey" position="20,1060" size="1600,2" />
		<widget name="statustext" position="20,1070" size="1600,80" font="Regular;48" halign="center" valign="center" foregroundColor="white"/>
		</screen>"""
        elif sz_w == 1920:    
		skin = """
		<screen position="center,170" size="1200,870" title="EPGExport" >
		<widget name="logo" position="20,10" size="150,60" transparent="1" alphatest="on" />
        	<widget backgroundColor="#9f1313" font="Regular;24" halign="center" name="buttonred" position="190,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="230,60" valign="center" />
                <widget backgroundColor="#1f771f" font="Regular;24" halign="center" name="buttongreen" position="440,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="230,60" valign="center" />
                <widget backgroundColor="#a08500" font="Regular;24" halign="center" name="buttonyellow" position="690,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="230,60" valign="center" />
                <widget backgroundColor="#18188b" font="Regular;24" halign="center" name="buttonblue" position="940,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="230,60" valign="center" />
                <eLabel backgroundColor="grey" position="20,80" size="1160,1" />
                <widget name="config" enableWrapAround="1" position="20,90" scrollbarMode="showOnDemand" size="1160,680" />
                <eLabel backgroundColor="grey" position="20,780" size="1160,1" />
		<widget name="statustext" position="20,790" size="1160,70" font="Regular;36" halign="center" valign="center" foregroundColor="white"/>
		</screen>"""
	else:
		skin = """
		<screen position="center,120" size="820,580" title="EPGExport" >
		<widget name="logo" position="10,10" size="100,40" transparent="1" alphatest="on" />
        	<widget backgroundColor="#9f1313" font="Regular;18" halign="center" name="buttonred" position="120,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="165,40" valign="center" />
                <widget backgroundColor="#1f771f" font="Regular;18" halign="center" name="buttongreen" position="295,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="165,40" valign="center" />
                <widget backgroundColor="#a08500" font="Regular;18" halign="center" name="buttonyellow" position="470,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="165,40" valign="center" />
                <widget backgroundColor="#18188b" font="Regular;18" halign="center" name="buttonblue" position="645,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="165,40" valign="center" />
                <eLabel backgroundColor="grey" position="10,60" size="800,1" />
        	<widget name="config" enableWrapAround="1" position="10,70" size="800,450" scrollbarMode="showOnDemand" />
                <eLabel backgroundColor="grey" position="10,530" size="800,1" />
		<widget name="statustext" position="10,535" size="800,40" font="Regular;24" halign="center" valign="center" foregroundColor="white"/>
		</screen>"""
	def __init__(self, session, args = 0):
		Screen.__init__(self, session)
        	self.skin = EPGExportConfiguration.skin  
		self.session = session
		self.onShown.append(self.setWindowTitle)
	        # explicit check on every entry
		self.onChangedEntry = []
	        self.list = []                                                  
	       	ConfigListScreen.__init__(self, self.list, session = self.session, on_change = self.changedEntry)
	       	self.createSetup()       
		self.onLayoutFinish.append(self.refreshLayout)  
		self["statustext"] = Label("")
		self["logo"] = Pixmap() 
		self["buttonred"] = Label(_("Exit"))
		self["buttongreen"] = Label(_("Save"))
		self["buttonyellow"] = Label(_("Downloading"))
		self["buttonblue"] = Label(_("Select")+" "+_("Bouquets"))
        	self["actions"] = ActionMap(["SetupActions", "ColorActions", "ChannelSelectEPGActions", "InfobarTeletextActions"],{"ok": self.save,  "exit": self.cancel, "cancel": self.cancel, "red": self.cancel, "green": self.save, "yellow": self.yellow_key, "blue": self.blue_key, "showEPGList": self.about, "startTeletext": self.getText })

	def setWindowTitle(self):                                   
        	self["logo"].instance.setPixmapFromFile("%s/epgexport.png" % epgexport_plugindir)
		if config.plugins.epgexport.compression.value == "xz":
			self["buttonyellow"].setText(_("Downloading")+" (xz)")
		elif config.plugins.epgexport.compression.value == "gz":
			self["buttonyellow"].setText(_("Downloading")+" (gz)")
		else:
			self["buttonyellow"].setText(_("Downloading"))
    		self.setTitle(epgexport_title)
	
	def save(self):
		self["statustext"].setText(_("Saving")+" "+_("Configuration")+" "+_("..."))
		if config.plugins.epgexport.channelid.value=="xml" and not os_path.exists("/etc/epgexport/custom.channels.xml"):
			config.plugins.epgexport.channelid.value="name"

		for x in self["config"].list:
			if len(x) > 1:
       				x[1].save()

		if config.plugins.epgexport.server.value != "none":
			if config.plugins.epgexport.server.value=="ip":
               			host = "%d.%d.%d.%d" % tuple(config.plugins.epgexport.ip.value)
			else:
				host = config.plugins.epgexport.hostname.value 
			epg_string=epgexport_string.replace("localhost",host)
			if config.plugins.epgexport.compression.value == "xz":
				epg_string=epgexport_string.replace("localhost",host)
			elif config.plugins.epgexport.compression.value == "gz":
				epg_string=epgexport_string.replace("localhost",host).replace("xz","gz")
			else:
				epg_string=epgexport_string.replace("localhost",host).replace(".xz","").replace("(xz) ","")
			# add port for custom webinterface
			if config.plugins.epgexport.webinterface.value=="custom":
				port=config.plugins.epgexport.port.value
				epg_string=epg_string.replace("/epgexport",":%s/epgexport" % port)
			if not os_path.exists("/etc/epgimport"):
				os_mkdir("/etc/epgimport",7777)
			f=open("/etc/epgimport/epgexport.sources.xml","w+")
			f.write(epg_string)
			f.close()
			if not os_path.exists("/etc/epgload"):
				os_mkdir("/etc/epgload",7777)
			f=open("/etc/epgload/epgexport.sources.xml","w+")
			f.write(epg_string)
			f.close()
		else:
			if os_path.exists("/etc/epgimport/epgexport.sources.xml"):
				os_remove("/etc/epgimport/epgexport.sources.xml")
			if os_path.exists("/etc/epgload/epgexport.sources.xml"):
				os_remove("/etc/epgload/epgexport.sources.xml")
		fixepgexport()			
		self.close(True)

	def cancel(self):
		self["statustext"].setText(_("Leaving")+" "+_("Configuration")+" "+_("..."))
		for x in self["config"].list:
			if len(x) > 1:
				x[1].cancel()
		self.close(False)

        def createSetup(self):                                                  
                # init only on first run                                        
                self.refreshLayout(True)                 

	def refreshLayout(self, first=False):                                                  
	       	self.list = []
		self.list.append((("* * * ")+_("Electronic Program Guide")+" "+_("XML")+" * * *",))  
		self.list.append(getConfigListEntry(_("Location"), config.plugins.epgexport.epgexport))
		self.list.append(getConfigListEntry(_("EPG")+" "+_("Download")+" ("+_("Days")+")", config.plugins.epgexport.days))
		self.list.append(getConfigListEntry(_("EPG")+" "+_("Update")+" ("+_("hours")+")", config.plugins.epgexport.reload))
		self.list.append(getConfigListEntry(_("Keep outdated EPG (in hours)").replace(_("hours"),_("Days")), config.plugins.epgexport.outdated))
		self.list.append(getConfigListEntry(_("daily")+" "+_("EPG")+" "+_("Download"), config.plugins.epgexport.daily))
		if config.plugins.epgexport.daily.value:                                                     
			self.list.append(getConfigListEntry(_("daily")+" "+_("StartTime"), config.plugins.epgexport.wakeup))
		self.list.append(getConfigListEntry(_("Compression"), config.plugins.epgexport.compression))
		self.list.append(getConfigListEntry(_("Channel")+" "+_("ID"), config.plugins.epgexport.channelid))
		self.list.append(getConfigListEntry(_("Twisted")+" "+_("Background"), config.plugins.epgexport.twisted))
		self.list.append((("* * * ")+_("Source")+" "+_("XML")+" * * *",))  
		self.list.append(getConfigListEntry(_("Choose upgrade source"), config.plugins.epgexport.server))
		if config.plugins.epgexport.server.value=="ip":
			self.list.append(getConfigListEntry(_("IP Address"), config.plugins.epgexport.ip))
		if config.plugins.epgexport.server.value=="name":
			self.list.append(getConfigListEntry(_("Server IP").replace("IP",_("Name")), config.plugins.epgexport.hostname))
		self.list.append((("* * * ")+_("Configuration for the Webinterface")+" * * *",))  
		self.list.append(getConfigListEntry(_("Select")+" ("+_("Restart GUI")+")", config.plugins.epgexport.webinterface))
		if config.plugins.epgexport.webinterface.value == "custom":
			self.list.append(getConfigListEntry(_("Server IP").replace("IP",_("Port")), config.plugins.epgexport.port))

		if first:                                                       
                	self.menuList = ConfigList(self.list)                   
                	self.menuList.list = self.list                          
                	self.menuList.l.setList(self.list)                      
                	self["config"] = self.menuList  
                	self["config"].onSelectionChanged.append(self.selectionChanged)
		else:
                	self.menuList.list = self.list                          
                	self.menuList.l.setList(self.list)                      

        def selectionChanged(self):    
        	choice = self["config"].getCurrent()                                    
        	current=choice[1]                
		hostname=config.plugins.epgexport.hostname
		ip=config.plugins.epgexport.ip
		if current==ip: 
			self["buttonyellow"].setText(_("Server IP"))
		elif current==hostname:
			self["buttonyellow"].setText(_("Hostname"))
		else:
			if config.plugins.epgexport.compression.value == "xz":
				self["buttonyellow"].setText(_("Downloading")+" (xz)")
			elif config.plugins.epgexport.compression.value == "gz":
				self["buttonyellow"].setText(_("Downloading")+" (gz)")
			else:
				self["buttonyellow"].setText(_("Downloading"))


	def changedEntry(self):                                                 
        	choice = self["config"].getCurrent()                                    
        	current=choice[1]                
		hostname=config.plugins.epgexport.hostname
		if config.plugins.epgexport.channelid.value=="xml" and not os_path.exists("/etc/epgexport/custom.channels.xml"):
			config.plugins.epgexport.channelid.value="name"
        	if choice != None:        
			if current != hostname:
        			self.refreshLayout()

	def yellow_key(self):
        	choice = self["config"].getCurrent()                                    
        	current=choice[1]                
		hostname=config.plugins.epgexport.hostname
		ip=config.plugins.epgexport.ip
		if current==ip: 
			ip=self.getIP()
			lip=ip.split(".")
			# make tuple by hand ...
			localip=[int(lip[0]),int(lip[1]),int(lip[2]),int(lip[3])]
			config.plugins.epgexport.ip.value=localip
			self.refreshLayout()
		elif current==hostname:
			hostname=gethostname()
			fullname=getfqdn(hostname)
			config.plugins.epgexport.hostname.value=fullname
			self.refreshLayout()
		else:
			selected=0
			for x in range(bouquet_length): 
				if config.plugins.epgexport.bouquets[x].export.value:
					selected+=1
			if selected < 1:
				for x in range(bouquet_length): 
					if config.plugins.epgexport.bouquets[x].name.value=="favorites":
						config.plugins.epgexport.bouquets[x].export.value=True
						config.plugins.epgexport.bouquets[x].export.save()
						cprint("nothing selected, means Favorites")
			fixepgexport()
			self["statustext"].setText(_("EPG")+" "+_("Downloading"))
			if config.plugins.epgexport.twisted.value:
				threads.deferToThread(self.startingEPGExport).addCallback(lambda ignore: self.finishedEPGExport())
			else:
				self.startingEPGExport()
				self.finishedEPGExport()

	def startingEPGExport(self):
		self["statustext"].setText(_("EPG")+" "+_("Downloading")+" "+_("..."))
		EPGExport(self,config.plugins.epgexport.compression.value,True,True)

	def finishedEPGExport(self):
		loaded=""
		for x in range(bouquet_length): 
			if config.plugins.epgexport.bouquets[x].export.value:
				loaded+="%s\n" % config.plugins.epgexport.bouquets[x].name.value
		if config.plugins.epgexport.compression.value == "xz":
        		self.session.open(MessageBox, _("EPG")+" "+_("Downloading")+" (xz):\n\n"+loaded.upper()+"\n"+_("Execution finished!!"), MessageBox.TYPE_INFO)
		elif config.plugins.epgexport.compression.value == "gz":
        		self.session.open(MessageBox, _("EPG")+" "+_("Downloading")+" (gz):\n\n"+loaded.upper()+"\n"+_("Execution finished!!"), MessageBox.TYPE_INFO)
		else:
        		self.session.open(MessageBox, _("EPG")+" "+_("Downloading")+":\n\n"+loaded.upper()+"\n\n"+_("Execution finished!!"), MessageBox.TYPE_INFO)

	def about(self):
        	self.session.open(MessageBox, epgexport_thanks,  MessageBox.TYPE_INFO)

	def getText(self):
		cprint("CLEANING EXPORT")
		cleanepgexport(True)
       		self.session.open(MessageBox, _("EPG")+" "+_("Download")+" "+_("Cache")+" "+_("Reset"), MessageBox.TYPE_INFO)

	def getIP(self):
		ip=None
		lip="localhost"
		if os_path.exists("/var/lib/dpkg/status"):
			from Components.Network import iNetworkInfo
			ifaces = iNetworkInfo.getConfiguredInterfaces()         
        	        for iface in ifaces.itervalues():
                		ip = iface.getIpv4()
                	        if not ip:
                	 	       ip = iface.getIpv6()
			if ip is not None:
				lip=ip.getAddress()
		else:
			from Components.Network import iNetwork
			ifaces = iNetwork.getConfiguredAdapters()
        	        for iface in ifaces:
				ip = iNetwork.getAdapterAttribute(iface, "ip")
				if not ip or len(ip) != 4:
					continue
			if ip is not None:
				lip = '.'.join(str(x) for x in ip)
		cprint("local ip %s" % (lip))
		return lip

	def blue_key(self):
       		self.session.open(EPGExportSelection)

class EPGExport(Screen):
        def __init__(self,main,compressed="xz", channels=True, programs=True):
		self.main=main
		self.compressed=compressed
		self.channels=channels
		self.programs=programs
		self.cur_event = None
		self.cur_service = None
		self.offs = 0
		self.epgcache = eEPGCache.getInstance()
		self.time_base = int(time.time())-int(config.plugins.epgexport.outdated.value)*60*24
		self.time_epoch = int(config.plugins.epgexport.days.value)*60*24
		self.slist = None
		global Servicelist
		self.tree = None
                if Servicelist is None:                                         
                        InfoBarInstance = InfoBar.instance                      
                        if InfoBarInstance is not None:                         
                                Servicelist = InfoBarInstance.servicelist       
		cprint("servicelist: %s" % Servicelist)
		new=checkLastUpdate()
		if new:
			if config.plugins.epgexport.channelid.value=="xml":
				if os_path.exists("/etc/epgexport/custom.channels.xml"):
					cprint("loading custom.channels.xml")
					if self.main is not None:
						self.main["statustext"].setText(_("Custom (%s)") % "xml"+" "+_("Channels")+" "+_("Downloading")+" "+_("..."))
					epgtree = etree.parse("/etc/epgexport/custom.channels.xml")
					self.tree = epgtree.getroot()
				else:
					cprint("custom.channels.xml not found")
					if self.main is not None:
						self.main["statustext"].setText(_("Custom (%s)") % "xml"+" "+_("not found"))
					return	
#			cprint("tree %s" % self.tree)
			cprint("extracting ...")
			self.startingEPGExport()  
		else:
			cprint("still valid ...")
			if self.main is not None:
				self.main["statustext"].setText(_("EPG")+" "+_("Download")+" "+_("Reload")+" "+_("Finished"))

	def startingEPGExport(self):  
		cprint("starting EPG export ...")
		lang=config.osd.language.value
		sp=[]
		sp=lang.split("_")
		self.language=sp[0].lower()
		# use current bouquet if none is found ...
		bouquet=Servicelist.getRoot()
                serviceHandler = eServiceCenter.getInstance()                   
                info = serviceHandler.info(bouquet)                             
                bouquet_name = info.getName(bouquet)     
		cprint("DEFAULT bouquet %s" % bouquet_name)
		global Servicelist
		all_bouquets = Servicelist.getBouquetList()
		self.services=[]
		for bouquets in all_bouquets:
			bt=tuple(bouquets)
			bouquet_name = bt[0].replace(" (TV)","").replace(" (Radio)","").lower()
			cprint("CHECKS bouquet %s" % bouquet_name)
			for x in range(bouquet_length): 
				if bouquet_name==config.plugins.epgexport.bouquets[x].name.value and config.plugins.epgexport.bouquets[x].export.value:
					bouquet=bouquets[1]
					cprint("FOUND bouquet %s" % bouquet_name)
                			self.services = self.services+self.getBouquetServices(bouquet)                          
		if self.channels:
			self.exportChannels()
		if self.programs:
			cprint("extracting ...")
			exportLastUpdate()  
	        	self.extractEPG()
			self.exportEPG()

	def getBouquetServices(self, bouquet):  
		services = [ ]
		Servicelist = eServiceCenter.getInstance().list(bouquet)
		if not Servicelist is None:
			while True:
				service = Servicelist.getNext()
				if not service.valid(): #check if end of list
					break
				if service.flags & (eServiceReference.isDirectory | eServiceReference.isMarker): #ignore non playable services
					continue
				services.append(ServiceReference(service))
		return services

	def extractEPG(self):  
		self.cur_event = None
		self.cur_service = None
		test = [ (service.ref.toString(), 0, self.time_base, self.time_epoch) for service in self.services ]
#		print "test:", test
		test.insert(0, 'XRnITBDSE') # N = ServiceName, n = short ServiceName

		epg_data = self.queryEPG(test)
		self.program = [ ]
		tmp_list = None
		service = ""
		sname = ""
		for x in epg_data:
			if service != x[0]:
				if tmp_list is not None:
					self.program.append((service, sname, tmp_list[0][0] is not None and tmp_list or None))
				service = x[0]
				sname = ServiceReference(service).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')
				sname = x[1]
#				cprint("buildEPG service, sname: %s %s" % (service, sname))
				tmp_list = [ ]
			tmp_list.append((x[2], x[3], x[4], x[5], x[6], x[7]))
		if tmp_list and len(tmp_list):
			self.program.append((service, sname, tmp_list[0][0] is not None and tmp_list or None))
		
	def queryEPG(self, list, buildFunc=None):
		if self.epgcache is not None:
			if buildFunc is not None:
				return self.epgcache.lookupEvent(list, buildFunc)
			else:
				return self.epgcache.lookupEvent(list)
		return [ ]

	def exportChannels(self):
		xmltv_string = self.generateChannels()
		xml_file_name = '/etc/epgexport/epgexport.channels.xml'
		if self.compressed == "xz":
			x = lzma.open(xml_file_name+".xz",'wb')
		elif self.compressed == "gz":
			x = gzip.open(xml_file_name+".gz",'wb')
		else:
			x = open(xml_file_name,'w')
		x.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
		x.write (xmltv_string)
		x.close()

	def exportEPG(self):
		xmltv_string = self.generateEPG()
		xml_file_name = '/etc/epgexport/epgexport'
		if self.compressed == "xz":
			x = lzma.open(xml_file_name+".xz",'wb')
		elif self.compressed == "gz":
			x = gzip.open(xml_file_name+".gz",'wb')
		else:
			x = open(xml_file_name,'w')
		x.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
		x.write (xmltv_string)
		x.close()

	def indent(self, elem, level=0):
	    i = "\n" + level*"  "
	    if len(elem):
	        if not elem.text or not elem.text.strip():
	            elem.text = i + "  "
	        if not elem.tail or not elem.tail.strip():
	            elem.tail = i
	        for elem in elem:
	            self.indent(elem, level+1)
	        if not elem.tail or not elem.tail.strip():
	            elem.tail = i
	    else:
		if level and (not elem.tail or not elem.tail.strip()):
	            elem.tail = i

	def channelID(self, service):
		service_name = service.getServiceName().encode('ascii', 'ignore')
		service_ref = service.ref.toString()
		service_id=service_name.replace(" ","").replace("(","").replace(")","").replace("-","").replace(".","").replace("+","").replace("_","").replace("/","").replace('\xc2\x86', '').replace('\xc2\x87', '').decode('utf8')
		if self.tree is not None:
			# fallback is nameslang
			channel_id=service_id+"."+self.language
			for child in self.tree:
				if child.text==service_ref:
					if len(child.attrib["id"]) > 0:
						# first find will win because
						# good custom file has only one find
						channel_id=child.attrib["id"]
						return channel_id
						break
#			cprint("NOT found %s channel_id %s" % (service_ref, channel_id))
		elif config.plugins.epgexport.channelid.value=="names":
			channel_id=service_id
		elif config.plugins.epgexport.channelid.value=="nameslang":
			channel_id=service_id+"."+self.language
		elif config.plugins.epgexport.channelid.value=="nameslow":
			channel_id=service_id.lower()
		elif config.plugins.epgexport.channelid.value=="nameslowlang":
			channel_id=service_id.lower()+"."+self.language
		else:   # default = channel name
			channel_id=service_name
		return channel_id

	def generateChannels(self):
		cprint("Building XMLTV channel list file")
		sp=[]
		root = etree.Element('channels')
		# write all channel id's and service references at beginning of file 
		for service in self.services:
			service_name = service.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '').decode('utf8')
			service_ref = service.ref.toString()
			sp=service_ref.split("::")
			service_ref=sp[0]
			if len(service_name) > 0 and service_ref.find("//") is -1 and service_ref.find("BOUQUET") is -1:
				service_id=self.channelID(service)
				xmltv_channel = etree.SubElement(root,'channel')
				xmltv_channel.set('id', service_id)
				xmltv_channel.text = service_ref
		# etree.tostring has no pretty print to make indent in xml
		self.indent(root)
		return etree.tostring(root,encoding='utf-8')

	def getTimezoneOffset(self):
		from datetime import datetime
		from datetime import timedelta
		# utc time
		ts=time.time()
		# local time == (utc time + utc offset)
		tl=time.localtime()

		# summertime is not needed ...
#		td = timedelta(minutes=int(tl.tm_isdst)*60)
#		cprint("summer time delta %s" % td)
#		offset = datetime.fromtimestamp(ts) - datetime.utcfromtimestamp(ts) - td

		offset = datetime.fromtimestamp(ts) - datetime.utcfromtimestamp(ts)
		# make nice string form XMLTV local time offset ...
		delta=str(offset).rstrip("0").replace(":","")
		if abs(int(delta)) < 1000:
			if int(delta) > 0:
				local_offset = '+0'+delta
			else:
				local_offset = '-0'+delta
		else:
			if int(delta) > 0:
				local_offset = '+'+delta
			else:
				local_offset = '-'+delta
		cprint("local offset: %s" % local_offset)
		return local_offset

	def generateEPG(self):
		cprint("Building XMLTV electronic program guide file")
		root = etree.Element('tv')
		generator_info_name='EPG Export Plugin (c) gutemine 2019'
		generator_info_url='https://gemfury.com/gm3'
		root.set('generator-info-name',generator_info_name)
		root.set('generator-info-url',generator_info_url)
		cn=0
		for service in self.services:
			service_name = service.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '').decode('utf8') 
			service_ref = service.ref.toString()
			if len(service_name) > 0 and service_ref.find("//") is -1:
				service_id=self.channelID(service)
				xmltv_channel = etree.SubElement(root,'channel')
				xmltv_channel.set('id', service_id)
				xmltv_cname = etree.SubElement(xmltv_channel,'display-name',lang=self.language)
				xmltv_cname.text = service_name
				cn+=1
		cprint("channel number: %d" % cn)

		local_time_offset=self.getTimezoneOffset()
		en=0
		for program in self.program:
			if program[2] is not None:
				service = ServiceReference(program[0])
				service_name = service.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')
				service_ref = service.ref.toString()
				if len(service_name) > 0 and service_ref.find("//") is -1:
					service_id=self.channelID(service)
					for event in program[2]:
						prog=dict()
						title=event[1].strip().encode('utf8')
						start=int(event[2])
						duration=int(event[3])
						subtitletext=event[4].strip().encode('utf8')
						description=event[5].strip().encode('utf8')
						stop=start+duration
						start_time = time.strftime('%Y%m%d%H%M00', time.localtime(start))
						stop_time  = time.strftime('%Y%m%d%H%M00', time.localtime(stop))
#						cprint(">>> %s" % title)
#						cprint(">>>>>> %s" % subtitletext)
#						cprint(">>>>>>>>> %" % description)
						xmltv_program = etree.SubElement(root,'programme')
						xmltv_program.set('start',start_time + ' ' + local_time_offset)
						xmltv_program.set('stop', stop_time + ' ' + local_time_offset)
						xmltv_program.set('channel',service_id)

						en+=1

						if title != None:
							if len(title) > 120:
								title_text = title.split('. ')
							else:
								title_text=[]
								title_text.append(title)
							title = etree.SubElement(xmltv_program,'title',lang=self.language)
							title.text = title_text[0].strip().decode('utf8')
							if len(subtitletext) > 1:
								subtitle = etree.SubElement(xmltv_program,'sub-title',lang=self.language)
								subtitle.text = subtitletext
							else:
								if len(title_text) > 1:
									subtitle = etree.SubElement(xmltv_program,'sub-title',lang=self.language)
									subtitle.text = title_text[1].strip().decode('utf8')
    
						if description != None:
							if len(description) > 1:
								desc = etree.SubElement(xmltv_program,'desc',lang=self.language)
								desc.text = description.decode('utf8')
		cprint("event number: %d" % en)
      
		# etree.tostring has no pretty print to make indent in xml
		self.indent(root)
		if self.main is not None:
			self.main["statustext"].setText(_("EPG")+" "+_("Download")+" "+_("Channels")+": %d " % cn+_("EPG")+" "+_("Info")+" "+_("Details")+": %d" % en)
		return etree.tostring(root,encoding='utf-8')

class EPGExportSource(resource.Resource):
	def render_GET(self, req):
		cprint("SOURCE REQUEST ...")
#		cprint(req)
		sources=""
		if os_path.exists("/etc/epgload/epgexport.sources.xml"):
			f=open("/etc/epgload/epgexport.sources.xml","r")
			sources=f.read()
			f.close()
		elif os_path.exists("/etc/epgimport/epgexport.sources.xml"):
			f=open("/etc/epgimport/epgexport.sources.xml","r")
			sources=f.read()
			f.close()
		else:
			pass
		cprint("sources: %s" % sources)
		req.setResponseCode(http.OK)
		req.setHeader('Content-type', 'text/html')
		req.setHeader('charset', 'UTF-8')
		return sources

class EPGExportLastUpdate(resource.Resource):
	# always return current date for a web request 
	def render_GET(self, req):
		cprint("last update request ...")
#		cprint(req)
		now=datetime.datetime.now()
		date=now.strftime('%Y-%m-%d')
		cprint("last update: %s" % date)
		req.setResponseCode(http.OK)
		req.setHeader('Content-type', 'text/html')
		req.setHeader('charset', 'UTF-8')
		return date

class EPGExportChannels(resource.Resource):
	def render_GET(self, req):
		cprint("CHANNELS REQUEST: %s" % req.uri)
		channels=""
		new=checkLastUpdate()
		if req.uri.find("epgexport.channels.xml.xz") is not -1:
			if new or not os_path.exists("/etc/epgexport/epgexport.channels.xml.xz"):
				# web request for xz file
				cprint("EXPORTING CHANNELS xz")
				EPGExport(None,"xz",True, False)
			f=open("/etc/epgexport/epgexport.channels.xml.xz","rb")
		elif req.uri.find("epgexport.channels.xml.gz") is not -1:
			if new or not os_path.exists("/etc/epgexport/epgexport.channels.xml.gz"):
				# web request for gz file
				cprint("EXPORTING CHANNELS gz")
				EPGExport(None,"gz",True, False)
			f=open("/etc/epgexport/epgexport.channels.xml.gz","rb")
		else:
			if new or not os_path.exists("/etc/epgexport/epgexport.channels.xml"):
				# web request for uncompressed file
				cprint("EXPORTING CHANNELS")
				EPGExport(None,"none",True, False)
			f=open("/etc/epgexport/epgexport.channels.xml","rb")
		channels=f.read()
		f.close()
		req.setResponseCode(http.OK)
		req.setHeader('Content-type', 'text/html')
		req.setHeader('charset', 'UTF-8')
		return channels

class EPGExportPrograms(resource.Resource):
	def render_GET(self, req):
		cprint("PROGRAMS REQUEST: %s" % req.uri)
		programs=""
		new=checkLastUpdate()
		if req.uri.find("epgexport.xz") is not -1:
			if new or not os_path.exists("/etc/epgexport/epgexport.xz"):
				# web request for xz file
				cprint("EXPORTING PROGRAMS xz")
				EPGExport(None,"xz",False,True)
			f=open("/etc/epgexport/epgexport.xz","rb")
		elif req.uri.find("epgexport.gz") is not -1:
			if new or not os_path.exists("/etc/epgexport/epgexport.gz"):
				# web request for gz file
				cprint("EXPORTING PROGRAMS gz")
				EPGExport(None,"gz",False,True)
			f=open("/etc/epgexport/epgexport.gz","rb")
		else:
			if new or not os_path.exists("/etc/epgexport/epgexport"):
				# web request for uncompressed file
				cprint("EXPORTING PROGRAMS")
				EPGExport(None,"none",False,True)
			f=open("/etc/epgexport/epgexport","rb")
		programs=f.read()
		f.close()
		req.setResponseCode(http.OK)
		req.setHeader('Content-type', 'text/html')
		req.setHeader('charset', 'UTF-8')
		return programs

class EPGExportSelection(Screen, ConfigListScreen):
        if sz_w == 2560:    
		skin = """
		<screen position="center,240" size="1640,960" title="EPGExport Selection" >
		<widget name="logo" position="20,20" size="200,80" transparent="1" alphatest="on" />
        	<widget backgroundColor="#9f1313" font="Regular;32" halign="center" name="buttonred" position="240,20" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="330,80" valign="center" />
                <widget backgroundColor="#1f771f" font="Regular;32" halign="center" name="buttongreen" position="590,20" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="330,80" valign="center" />
                <widget backgroundColor="#a08500" font="Regular;32" halign="center" name="buttonyellow" position="940,20" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="330,80" valign="center" />
                <widget backgroundColor="#18188b" font="Regular;32" halign="center" name="buttonblue" position="1290,20" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="330,80" valign="center" />
                <eLabel backgroundColor="grey" position="20,120" size="1600,2" />
        	<widget name="config" enableWrapAround="1" position="20,140" size="1600,800" scrollbarMode="showOnDemand" />
		</screen>"""
        elif sz_w == 1920:    
		skin = """
		<screen position="center,170" size="1200,710" title="EPGExport Selection" >
		<widget name="logo" position="20,10" size="150,60" transparent="1" alphatest="on" />
        	<widget backgroundColor="#9f1313" font="Regular;24" halign="center" name="buttonred" position="190,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="230,60" valign="center" />
                <widget backgroundColor="#1f771f" font="Regular;24" halign="center" name="buttongreen" position="440,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="230,60" valign="center" />
                <widget backgroundColor="#a08500" font="Regular;24" halign="center" name="buttonyellow" position="690,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="230,60" valign="center" />
                <widget backgroundColor="#18188b" font="Regular;24" halign="center" name="buttonblue" position="940,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="230,60" valign="center" />
                <eLabel backgroundColor="grey" position="20,80" size="1160,1" />
                <widget name="config" enableWrapAround="1" position="20,90" scrollbarMode="showOnDemand" size="1160,610" />
		</screen>"""
	else:
		skin = """
		<screen position="center,120" size="820,480" title="EPGExport Selection" >
		<widget name="logo" position="10,10" size="100,40" transparent="1" alphatest="on" />
        	<widget backgroundColor="#9f1313" font="Regular;16" halign="center" name="buttonred" position="120,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="165,40" valign="center" />
                <widget backgroundColor="#1f771f" font="Regular;16" halign="center" name="buttongreen" position="295,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="165,40" valign="center" />
                <widget backgroundColor="#a08500" font="Regular;16" halign="center" name="buttonyellow" position="470,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="165,40" valign="center" />
                <widget backgroundColor="#18188b" font="Regular;16" halign="center" name="buttonblue" position="645,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="165,40" valign="center" />
                <eLabel backgroundColor="grey" position="10,60" size="800,1" />
        	<widget name="config" enableWrapAround="1" position="10,70" size="800,400" scrollbarMode="showOnDemand" />
		</screen>"""
	def __init__(self, session, args = 0):
		Screen.__init__(self, session)
        	self.skin = EPGExportSelection.skin  
		self.session = session
                self.onShown.append(self.setWindowTitle)
	        # explicit check on every entry
		self.onChangedEntry = []
	        self.list = []                                                  
	       	ConfigListScreen.__init__(self, self.list, session = self.session, on_change = self.changedEntry)
		self["logo"] = Pixmap() 
		self["buttonred"] = Label(_("Exit"))
		self["buttongreen"] = Label(_("Save"))
		self["buttonyellow"] = Label(_("Reset"))
		self["buttonblue"] = Label(_("About"))
        	self["actions"] = ActionMap(["SetupActions", "ColorActions"],{"ok": self.save,  "exit": self.cancel, "cancel": self.cancel, "red": self.cancel, "green": self.save, "yellow": self.resetting, "blue": self.about, })
		selected=0
		for x in range(bouquet_length): 
			if config.plugins.epgexport.bouquets[x].export.value:
				selected+=1
		if selected < 1:
			self.resetting()
	       	self.createSetup()       

	def setWindowTitle(self):                                   
        	self["logo"].instance.setPixmapFromFile("%s/epgexport.png" % epgexport_plugindir)
    		self.setTitle(epgexport_selection)
	
	def save(self):
		selected=0
		for x in range(bouquet_length): 
			if config.plugins.epgexport.bouquets[x].export.value:
				selected+=1
		if selected < 1:
			self.resetting()
		for x in range(bouquet_length): 
			config.plugins.epgexport.bouquets[x].export.save()
			config.plugins.epgexport.bouquets[x].name.save()
		self.close(True)

	def cancel(self):
		for x in range(bouquet_length): 
			config.plugins.epgexport.bouquets[x].export.cancel()
			config.plugins.epgexport.bouquets[x].name.cancel()
		self.close(False)

	def createSetup(self):                                                  
	       	self.list = []
		for x in range(bouquet_length): 
			self.list.append(getConfigListEntry(bouquet_options[x][1], config.plugins.epgexport.bouquets[x].export))
	        self["config"].list = self.list                                 
	        self["config"].l.setList(self.list)         

	def changedEntry(self):                                                 
        	choice = self["config"].getCurrent()                                    
        	current=choice[1]                
        	if choice != None:        
        		self.createSetup()

	def resetting(self):                                                 
		for x in range(bouquet_length): 
			config.plugins.epgexport.bouquets[x].export.value=False
			if config.plugins.epgexport.bouquets[x].name.value=="favorites":
				config.plugins.epgexport.bouquets[x].export.value=True
				cprint("nothing selected, means Favorites")
			config.plugins.epgexport.bouquets[x].export.save()
			config.plugins.epgexport.bouquets[x].name.save()
       		self.createSetup()

	def about(self):
        	self.session.open(MessageBox, epgexport_thanks,  MessageBox.TYPE_INFO)