Repository URL to install this package:
|
Version:
0.1-r15 ▾
|
enigma2-plugin-extensions-svenhfeedplugin
/
usr
/
lib
/
enigma2
/
python
/
Plugins
/
Extensions
/
SvenHPlugins
/
MainPlugin.py
|
|---|
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import generators
from __future__ import division
from __future__ import absolute_import
from __future__ import with_statement
from __future__ import print_function
#
# Software Feed Plugin by Sven H
plugin_version="0.1-r15"
from Components.ActionMap import ActionMap, HelpableActionMap
from Components.config import config, configfile, ConfigSubsection, ConfigBoolean, ConfigSelection, getConfigListEntry, ConfigDirectory
from Components.ConfigList import ConfigListScreen
from Components.Pixmap import Pixmap
from Components.Label import Label
from Components.Ipkg import IpkgComponent
from Components.ScrollLabel import ScrollLabel
from Tools.LoadPixmap import LoadPixmap
from Screens.Screen import Screen
from Screens.MessageBox import MessageBox
from Screens.ChoiceBox import ChoiceBox
from Screens.HelpMenu import HelpableScreen
from Screens.Standby import TryQuitMainloop
from Components.FileList import FileList
from Components.Sources.StaticText import StaticText
from Components.PluginComponent import PluginComponent, plugins
from enigma import getDesktop, eActionMap, eTimer, eFileWatch, eFileEvent, eConsoleAppContainer, ePoint
from twisted.web.client import getPage
from os import path as os_path, stat as os_stat, remove as os_remove, listdir as os_listdir, kill as os_kill
from re import sub as re_sub, search as re_search
from socket import gethostbyname
from Plugins.Extensions.WebInterface.WebChilds.Toplevel import addExternalChild, externalChildren
from backports import lzma
import Plugins.Extensions.SvenHPlugins.unix_ar as unix_ar
import tarfile
from distutils.version import LooseVersion as Version
import hashlib
import signal
import gzip
from . import _
#get rid of calender import
def abbr_to_num(abbr):
calendar=[("01","Jan"),("02","Feb"),("03","Mar"),("04","Apr"),("05","May"),("06","Jun"),("07","Jul"),("08","Aug"),("09","Sep"),("10","Oct"),("11","Nov"),("12","Dec")]
for month in calendar:
if month[1]==abbr:
#cprint("Month found: %s %s" % (month[0],month[1]))
return month[0]
plugin_timeout=5
INSTALLABLE=0
INSTALLED=1
UPDATENEEDED=2
UNINSTALL=3
DOWNGRADE=4
def setConfigSelection(configName, choices, default):
if not hasattr(config.plugins.svenh,configName):
#print("set new configSelection")
setattr(config.plugins.svenh, configName, ConfigSelection(default = default, choices = choices))
else:
configEntry = config.plugins.svenh.__getattr__(configName)
if configEntry.getChoices() != choices:
#print("change choices", choices)
configEntry.setChoices(choices = choices, default = default)
else:
pass
#print("nothing to do", choices)
def createConfig():
yes_no_descriptions = {False: _("no"), True: _("yes")}
if not hasattr(config.plugins,"svenh"):
config.plugins.svenh = ConfigSubsection()
if not hasattr(config.plugins.svenh,"feed"):
config.plugins.svenh.feed = ConfigBoolean(default = True, descriptions=yes_no_descriptions)
if not hasattr(config.plugins.svenh,"hide"):
config.plugins.svenh.hide = ConfigBoolean(default = False, descriptions=yes_no_descriptions)
if not hasattr(config.plugins.svenh,"version"):
config.plugins.svenh.version = ConfigBoolean(default = True, descriptions=yes_no_descriptions)
if not hasattr(config.plugins.svenh,"size"):
config.plugins.svenh.size = ConfigBoolean(default = False, descriptions=yes_no_descriptions)
if not hasattr(config.plugins.svenh,"local_user_path"):
config.plugins.svenh.local_user_path = ConfigDirectory(default = "/")
if not hasattr(config.plugins.svenh,"show_update_section"):
config.plugins.svenh.show_update_section = ConfigBoolean(default = True, descriptions=yes_no_descriptions)
view_options=[]
#view_options.append(( "false",_("no")))
view_options.append(( "true",_("Sorting A-Z")))
view_options.append(( "sort",_("Sorting install state")))
setConfigSelection(configName = "listview", default = "true", choices = view_options)
local_options=[]
local_options.append(( "none",_("no")))
local_options.append(( "tmp","/tmp"))
local_options.append(( "data","/data"))
local_options.append(( "user",_("User defined")))
setConfigSelection(configName = "local", default = "none", choices = local_options)
confirm_options=[]
confirm_options.append(( "false",_("no")))
confirm_options.append(( "true",_("yes")))
confirm_options.append(( "info",_("Message")))
setConfigSelection(configName = "confirm", choices = confirm_options, default = "true")
info_options=[]
info_options.append(( "name",_("Name")))
info_options.append(( "desc",_("Description")))
setConfigSelection(configName = "show_info", choices = info_options, default = "desc")
# dummy configs ...
if not hasattr(config.plugins.svenh,"package_install"):
plugin_options_install=[]
plugin_options_install.append(( "install1",_("Installation available")))
plugin_options_install.append(( "install2",_("Installation available")))
config.plugins.svenh.package_install = ConfigSelection(default = "install1", choices=plugin_options_install)
if not hasattr(config.plugins.svenh,"package_uninstall"):
plugin_options_uninstall=[]
plugin_options_uninstall.append(( "uninstall1",_("Installation finished")))
plugin_options_uninstall.append(( "uninstall2",_("Installation finished")))
config.plugins.svenh.package_uninstall = ConfigSelection(default = "uninstall1", choices=plugin_options_uninstall)
if not hasattr(config.plugins.svenh,"package_update"):
plugin_options_update=[]
plugin_options_update.append(( "update1",_("Update available")))
plugin_options_update.append(( "update2",_("Update available")))
config.plugins.svenh.package_update = ConfigSelection(default = "update1", choices=plugin_options_update)
if not hasattr(config.plugins.svenh,"package_downgrade"):
plugin_options_downgrade=[]
plugin_options_downgrade.append(( "downgrade1",_("Downgrade")))
plugin_options_downgrade.append(( "downgrade2",_("Downgrade")))
config.plugins.svenh.package_downgrade = ConfigSelection(default = "downgrade1", choices=plugin_options_downgrade)
if not hasattr(config.plugins.svenh,"package_empty"):
plugin_options_empty=[]
plugin_options_empty.append(( "empty1"," "))
plugin_options_empty.append(( "empty2"," "))
config.plugins.svenh.package_empty = ConfigSelection(default = "empty1", choices=plugin_options_empty)
return
def cprint(text):
print("[SvenHPlugins] " + text)
def audio2Help():
cprint("AUDIO pressed")
#Device Types
TYPE_STANDARD = "dreambox remote control (native)"
TYPE_ADVANCED = "dreambox advanced remote control (native)"
TYPE_KEYBOARD = "dreambox ir keyboard"
#Advanced remote or standard?
if config.misc.rcused.value == 0:
remotetype = TYPE_ADVANCED
else:
remotetype = TYPE_STANDARD
eam = eActionMap.getInstance()
# press the key with the desired flag
keycode=138 # HELP key
cprint("NOW WRITES OUT: %i = HELP" % (keycode))
eam.keyPressed(remotetype, keycode, 0)
# release the key
eam.keyPressed(remotetype, keycode, 1)
createConfig() # check inside ...
plugin_status_file="/var/lib/dpkg/status"
plugindir="/usr/lib/enigma2/python/Plugins/Extensions/SvenHPlugins"
plugin_log="/tmp/svenhPlugins.log"
plugin_feedlist="/etc/apt/sources.list.d/svenh-feed.list"
plugin_feedName = "svenh-feed"
feedPlugin_PackageName = "enigma2-plugin-extensions-svenhfeedplugin"
statusfile_data = ""
def getTitle():
feed = "Sven H - " + _("Feed Plugin")
return feed
def getFeedUrl():
feedurl = "deb [trusted=yes] https://apt.fury.io/%s/ ./\n" % plugin_feedName
cprint("getFeedUrl: %s" % feedurl)
return feedurl
def getPackages(feed=""):
packages_file = "/var/lib/apt/lists/apt.fury.io_%s_._Packages" % (plugin_feedName)
cprint("get packages file: %s" % packages_file)
return packages_file
def getPackagesList(getAll=False):
packagesList=[]
packagesList.append(getPackages())
return packagesList
def sortPackages(packages):
cprint(">>>> sortPackages")
try:
sort_packages = []
for package in packages:
package_list = package.strip("\n").split("\n")
package = dict([(x.split(":")[0].strip(),x.split(":")[1].strip()) for x in package_list])
desc=package['Description'].split(",")
sp=desc[0].split(" ")
print(sp)
if len(sp)>1:
name="%s %s" % (sp[0],sp[1])
else:
name="%s" % (sp[0])
package['PackageName'] = name
sort_packages.append(package)
sort_packages = sorted(sort_packages, key=lambda k: k['PackageName'].lower())
return sort_packages
except:
import traceback, sys
traceback.print_exc()
return ""
sz_w = getDesktop(0).size().width()
gheader = " " * 6
gtrailer = ""
def getArch():
boxtype="dreamone"
if os_path.exists("/proc/stb/info/model"):
f=open("/proc/stb/info/model")
boxtype=f.read()
f.close()
boxtype=boxtype.replace("\n","").replace("\l","")
if boxtype == "dm525":
boxtype="dm520"
if boxtype == "one":
boxtype="dreamone"
if boxtype == "two":
boxtype="dreamtwo"
arch="arm64"
if boxtype=="dm900" or boxtype=="dm920":
arch="armhf"
if boxtype=="dm7080" or boxtype=="dm820" or boxtype=="dm520":
arch="mipsel"
return arch
def addFeed(update=True):
cprint("ADDING FEED")
feedurl=getFeedUrl()
packages=getPackages()
if not os_path.exists(plugin_feedlist):
f=open(plugin_feedlist,"w")
f.write(feedurl)
f.close()
else:
f=open(plugin_feedlist,"r")
feed=f.read()
f.close()
if feed!=feedurl:
f=open(plugin_feedlist,"w")
f.write(feedurl)
f.close()
if os_path.exists(packages):
metaDreamy(True)
if update:
aptUpdate()
def removeFeed():
cprint("REMOVING FEED")
if os_path.exists(plugin_feedlist):
os_remove(plugin_feedlist)
metaDreamy(False)
packagesList = getPackagesList()
for package in packagesList:
if os_path.exists(package):
cprint("remove packages file: %s" % package)
os_remove(package)
def aptUpdate():
cprint("apt-get update")
ipkg = IpkgComponent()
ipkg.startCmd(IpkgComponent.CMD_UPDATE)
def checkCompression(file_start):
compressed_magic_dict = { "\x1f\x8b\x08": "gz", "\xfd\x37\x7a": "xz" }
hex_start=":".join("{:02x}".format(ord(c)) for c in file_start)
for magic, filetype in compressed_magic_dict.items():
if file_start.startswith(str(magic)):
cprint("COMPRESSION %s %s" % (filetype, hex_start[:6]))
return filetype
cprint("COMPRESSION UNKNOWN %s" % (hex_start[:6]))
return "unknown"
def parseControl(controlstr):
control=controlstr.split("\n")
name="none"
desc=[]
status=INSTALLABLE
new=""
depends=[]
deb=""
line="none"
package=False
for line in control:
if package:
# cprint(">>>>>> %s" % line)
if line.startswith("Description:"):
sp=line.split(":")
if len(sp) > 1:
dd=sp[1].strip()
sp=dd.split(" ")
ll=len(sp)
if ll > 5: # name shows maximum 5 words
ll=5
i=1
name=sp[0]
while i < ll:
name="%s %s" % (name,sp[i])
i+=1
# cprint(">>>>>> Description: %s" % name)
if line.startswith("Version:"):
sp=line.split(":")
if len(sp) > 1:
new=sp[1].strip()
# cprint(">>>>>> Version: %s" % new)
if line.startswith("Depends:"):
sp=line.split(":")
if len(sp) > 1:
depends=sp[1].split(",")
# cprint(">>>>>> Depends: %s" % depends)
if line.startswith(("\t"," ")):
desc.append(line.lstrip("\t").lstrip(" ").rstrip("\n"))
# cprint(">>>>>> Description: %s" % desc)
if line.find("Package:") != -1:
package=True
sp=line.split(":")
if len(sp) > 1:
# cprint(">>>>>> Package: %s" % sp[1])
deb=sp[1].strip()
# this has to come to an end ...
if line.find("postinst") != -1 or line.find("postrm") != -1 or line.find("preinst") != -1 or line.find("prerm") != -1:
package=False
return (name,desc,deb,status,new,depends)
def parseDoc(directory, file):
sp=file.split("_")
kit=sp[0]
cprint(kit)
f=open(directory+"/"+file,"r")
header = f.read(32)
changelog=""
readme=""
copyright=""
if header[:7] != "!<arch>":
cprint("WRONG HEADER %s" % header[:7])
f.close()
return (changelog,copyright,readme)
#cprint("%s has ar file format" % file)
f.seek(0)
debian=f.read(1024*50) # 50kB should be enought for debian.tar
f.close()
ar_file=unix_ar.open(directory+"/"+file)
if debian.find("data.tar.gz/") != -1:
#cprint("data.tar.gz/")
data_tar=ar_file.open("data.tar.gz/")
elif debian.find("data.tar.gz") != -1:
#cprint("data.tar.gz")
data_tar=ar_file.open("data.tar.gz")
elif debian.find("data.tar.xz/") != -1:
#cprint("data.tar.xz/")
data_tar=ar_file.open("data.tar.xz/")
data=data_tar.read()
uncomp=lzma.decompress(data)
c=open("/tmp/data.tar","w")
c.write(uncomp)
c.close()
data_tar.close()
data_tar=open("/tmp/data.tar")
elif debian.find("data.tar.xz") != -1:
#cprint("data.tar.xz")
# python 2.7 tarfile has no xz support
data_tar=ar_file.open("data.tar.xz")
data=data_tar.read()
uncomp=lzma.decompress(data)
c=open("/tmp/data.tar","w")
c.write(uncomp)
c.close()
data_tar.close()
data_tar=open("/tmp/data.tar")
else:
cprint("STRANGE data")
del debian
data_tar.close()
return (changelog,copyright,readme)
del debian
data=tarfile.open(fileobj=data_tar)
found=False
try:
dtr=data.extractfile("./usr/share/doc/%s/copyright" % kit)
copyright=dtr.read()
dtr.close()
except:
pass
try:
dtr=data.extractfile("./usr/share/doc/%s/README" % kit)
readme=dtr.read()
dtr.close()
except:
pass
if len(readme)==0:
try:
dtr=data.extractfile("./usr/share/doc/%s/README.Debian" % kit)
readme=dtr.read()
dtr.close()
except:
pass
try:
dtr=data.extractfile("./usr/share/doc/%s/changelog" % kit)
changelog=dtr.read()
dtr.close()
except:
pass
if len(changelog)==0:
try:
dtr=data.extractfile("./usr/share/doc/%s/changelog.gz" % kit)
changelog=dtr.read()
dtr.close()
# gzip.decompress not yet in python 2.7
f=open("/tmp/changelog.gz","w")
f.write(changelog)
f.close()
f=gzip.open("/tmp/changelog.gz","r")
changelog=f.read()
f.close()
except:
pass
if len(changelog)==0:
try:
dtr=data.extractfile("./usr/share/doc/%s/changelog.Debian.gz" % kit)
changelog=dtr.read()
dtr.close()
# gzip.decompress not yet in python 2.7
f=open("/tmp/changelog.gz","w")
f.write(changelog)
f.close()
f=gzip.open("/tmp/changelog.gz","r")
changelog=f.read()
f.close()
except:
pass
#
# here we should add further variants of filenames
# ....
data.close()
data_tar.close()
return (changelog,copyright,readme)
def parseDeb(directory, file):
# FALLBACK for failed control parsing from deb filename
md5sums=""
ff=file.split("_")
deb=ff[0]
nn=deb.split("-")
name=nn[-1]
desc=name
boxkit="_"+getArch()+".deb"
if len(ff) > 1:
new=ff[1].replace("_all.deb","").replace(boxkit,"")
else:
new=_("unknown")
status=INSTALLABLE
depends=[]
arendchar=chr(0x60)+chr(0x0A)
f=open(directory+"/"+file,"r")
header = f.read(32)
if header[:7] != "!<arch>":
print("WRONG HEADER %s" % header[:7])
f.close()
return (name,desc,deb,status,new,depends,md5sums)
#cprint("%s has ar file format" % file)
f.seek(0)
debian=f.read(1024*50) # 20kB should be enought for control.tar
f.close()
ar_file=unix_ar.open(directory+"/"+file)
if debian.find("control.tar.gz/") != -1:
control_tar=ar_file.open("control.tar.gz/")
elif debian.find("control.tar.gz") != -1:
control_tar=ar_file.open("control.tar.gz")
elif debian.find("control.tar.xz/") != -1:
control_tar=ar_file.open("control.tar.xz/")
control=control_tar.read()
uncomp=lzma.decompress(control)
c=open("/tmp/control.tar","w")
c.write(uncomp)
c.close()
control_tar.close()
control_tar=open("/tmp/control.tar")
elif debian.find("control.tar.xz") != -1:
# python 2.7 tarfile has no xz support
control_tar=ar_file.open("control.tar.xz")
control=control_tar.read()
uncomp=lzma.decompress(control)
c=open("/tmp/control.tar","w")
c.write(uncomp)
c.close()
control_tar.close()
control_tar=open("/tmp/control.tar")
else:
cprint("STRANGE control")
del debian
return (name,desc,deb,status,new,depends,md5sums)
del debian
control=tarfile.open(fileobj=control_tar)
ctrl=control.extractfile("./control")
control_content=ctrl.read()
ctrl.close()
try:
md5=control.extractfile("./md5sums")
md5sums=md5.read()
md5.close()
cprint("%s with MD5SUM: %s" % (file,md5sums))
except:
pass
control.close()
control_tar.close()
name,desc,deb,status,new,depends=parseControl(control_content)
return (name,desc,deb,status,new,depends,md5sums)
plugin_skin=config.skin.primary_skin.value.replace("/skin.xml","")
def getPiconPath(name):
if os_path.exists("/usr/share/enigma2/%s/skin_default/%s.svg" % (plugin_skin,name)):
return "/usr/share/enigma2/%s/skin_default/%s.svg" % (plugin_skin,name)
if os_path.exists("/usr/share/enigma2/%s/skin_default/%s.png" % (plugin_skin,name)):
return "/usr/share/enigma2/%s/skin_default/%s.png" % (plugin_skin,name)
if os_path.exists("/usr/share/enigma2/%s/skin_default/icons/%s.png" % (plugin_skin,name)):
return "/usr/share/enigma2/%s/skin_default/icons/%s.png" % (plugin_skin,name)
if os_path.exists("/usr/share/enigma2/%s/skin_default/icons/%s.svg" % (plugin_skin,name)):
return "/usr/share/enigma2/%s/skin_default/icons/%s.svg" % (plugin_skin,name)
if os_path.exists("/usr/share/enigma2/skin_default/%s.svg" % (name)):
return "/usr/share/enigma2/skin_default/%s.svg" % (name)
if os_path.exists("/usr/share/enigma2/skin_default/icons/%s.png" % (name)):
return "/usr/share/enigma2/skin_default/icons/%s.png" % (name)
if os_path.exists("/usr/share/enigma2/skin_default/buttons/key_%s.png" % (name)):
return "/usr/share/enigma2/skin_default/buttons/key_%s.png" % (name)
return "/usr/share/enigma2/skin_default/%s.png" % (name)
class Console(Screen):
skin = """
<screen position="100,100" size="550,400" title="Command execution..." >
<widget name="text" position="0,0" size="550,400" font="Console;14" />
</screen>"""
def __init__(self, session, title = "Console", cmdlist = None, finishedCallback = None, closeOnSuccess = False, logfile = None, start_text=""):
Screen.__init__(self, session)
self.finishedCallback = finishedCallback
self.closeOnSuccess = closeOnSuccess
self["text"] = ScrollLabel("")
self["actions"] = ActionMap(["WizardActions", "DirectionActions"],
{
"ok": self.cancel,
"back": self.cancel,
"up": self["text"].pageUp,
"down": self["text"].pageDown
}, -1)
self.cmdlist = cmdlist
self.newtitle = title
self.logfile = logfile
self.start_text = start_text
self.onShown.append(self.updateTitle)
self.container = eConsoleAppContainer()
self.run = 0
self.appClosed_conn = self.container.appClosed.connect(self.runFinished)
self.dataAvail_conn = self.container.dataAvail.connect(self.dataAvail)
self.onLayoutFinish.append(self.startRun) # dont start before gui is finished
def updateTitle(self):
self.setTitle(self.newtitle)
def startRun(self):
if self.start_text:
self["text"].setText(_("Execution Progress:") + "\n\n" + self.start_text + "\n\n")
else:
self["text"].setText(_("Execution Progress:") + "\n\n")
if not self.logfile is None:
if os_path.exists(self.logfile):
os_remove(self.logfile)
self.output=open(self.logfile,"w")
cprint("console: executing in run %s the command: %s" % (self.run, self.cmdlist[self.run]))
self.last_str = ""
if self.container.execute(self.cmdlist[self.run]): #start of container application failed...
self.runFinished(-1) # so we must call runFinished manual
def runFinished(self, retval):
self.run += 1
if self.run != len(self.cmdlist):
if self.container.execute(self.cmdlist[self.run]): #start of container application failed...
self.runFinished(-1) # so we must call runFinished manual
else:
str = self["text"].getText().rstrip("\n")
str += "\n\n" + _("Execution finished!!");
self["text"].setText(str)
self["text"].lastPage()
if not self.finishedCallback is None:
self.finishedCallback()
if not retval and self.closeOnSuccess:
self.cancel()
def cancel(self):
if self.run == len(self.cmdlist):
if not self.logfile is None:
self.output.close()
self.close()
self.appClosed_conn = None
self.dataAvail_conn = None
def dataAvail(self, str):
out_str = ""
#print(">>> dataAvail str", str)
for char in str:
#print(">>> char", char, ord(char))
self.last_str += char
if len(self.last_str)>1 and ord(char)==10:
#print(">>> dataAvail last_str", self.last_str)
if self.last_str.startswith("W: Size of file") \
or self.last_str == "Reading package lists...\n" \
or self.last_str == "Building dependency tree...\n" \
or self.last_str == "Reading state information...\n" \
or self.last_str.startswith("0 upgraded, 0 newly installed"):
#print(">>> dataAvail remove", self.last_str)
self.last_str = ""
else:
self.last_str = re_sub('W: Size of file.*server reported \d* \d*', '', self.last_str)
self.last_str = self.last_str.replace('Reading state information...\n', '')
out_str += self.last_str # save str to write in console
self.last_str = ""
if out_str:
#print(">>> dataAvail write", out_str)
self["text"].setText(self["text"].getText() + out_str)
if not self.logfile is None:
self.output.write(out_str)
def dataAvail_old(self, str):
if str == "\n" and self.last_str_remove:
return
self.last_str_remove = True
if str.startswith("W: Size of file") or str in ("W", "W:", ": "):
#print(">>> remove in dataAvail '%s'" % str)
return
if str.find("is not what the server reported") != -1:
#print(">>> remove in dataAvail '%s'" % str)
return
if "Reading package lists..." in str or "Building dependency tree..." in str or "Reading state information..." in str:
#print(">>> remove in dataAvail '%s'" % str)
return
if str.startswith("0 upgraded, 0 newly installed"):
#print(">>> remove in dataAvail '%s'" % str)
return
self.last_str_remove = False
#print(">>> write in dataAvail '%s'" % str)
self["text"].setText(self["text"].getText() + str)
if not self.logfile is None:
self.output.write(str)
class SvenH_Main(Screen, ConfigListScreen, HelpableScreen):
if sz_w == 1920:
skin = """
<screen name="SvenH_Main" position="center,170" size="1200,890">
<widget name="logo" position="20,10" size="150,60" />
<widget backgroundColor="#9f1313" font="Regular;26" halign="center" name="buttonred" position="180,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="180,60" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;26" halign="center" name="buttongreen" position="370,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="180,60" valign="center" />
<widget backgroundColor="#a08500" font="Regular;26" halign="center" name="buttonyellow" position="560,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="180,60" valign="center" />
<widget backgroundColor="#18188b" font="Regular;26" halign="center" name="buttonblue" position="750,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="180,60" valign="center" />
<widget name="gemfury" position="1002,12" size="177,56" alphatest="on" />
<widget name="info" position="935,10" size="60,30" alphatest="on" />
<widget name="menu" position="935,40" size="60,30" alphatest="on" />
<eLabel backgroundColor="grey" position="20,90" size="1160,1" />
<widget name="config" enableWrapAround="1" position="30,110" scrollbarMode="showOnDemand" size="1140,720" />
<eLabel backgroundColor="grey" position="20,840" size="1160,1" />
<widget name="text" foregroundColor="white" backgroundColor="background" position="30,850" size="1100,35" font="Regular;26" zPosition="1" halign="center" valign="center" transparent="0"/>
</screen>"""
elif sz_w == 2560:
skin = """
<screen name="SvenH_Main" position="center,200" size="1640,1160" >
<widget name="logo" position="20,10" size="200,80" />
<widget backgroundColor="#9f1313" font="Regular;32" halign="center" name="buttonred" position="230,10" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="240,80" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;32" halign="center" name="buttongreen" position="490,10" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="240,80" valign="center" />
<widget backgroundColor="#a08500" font="Regular;32" halign="center" name="buttonyellow" position="750,10" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="240,80" valign="center" />
<widget backgroundColor="#18188b" font="Regular;32" halign="center" name="buttonblue" position="1010,10" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="240,80" valign="center" />
<widget name="gemfury" position="1380,12" size="228,72" alphatest="on" />
<widget name="info" position="1270,10" size="80,40" alphatest="on" />
<widget name="menu" position="1270,50" size="80,40" alphatest="on" />
<eLabel backgroundColor="grey" position="20,100" size="1600,2" />
<widget name="config" position="30,120" size="1580,960" enableWrapAround="1" scrollbarMode="showOnDemand" />
<eLabel backgroundColor="grey" position="20,1090" size="1600,2" />
<widget name="text" foregroundColor="white" backgroundColor="background" position="20,1100" size="1620,50" font="Regular;42" zPosition="1" halign="center" valign="center" transparent="0" />
</screen>"""
else:
skin = """
<screen name="SvenH_Main" position="center,100" size="820,580">
<widget name="logo" position="10,5" size="100,40" />
<widget backgroundColor="#9f1313" font="Regular;16" halign="center" name="buttonred" position="115,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="120,40" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;16" halign="center" name="buttongreen" position="245,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="120,40" valign="center" />
<widget backgroundColor="#a08500" font="Regular;16" halign="center" name="buttonyellow" position="375,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="120,40" valign="center" />
<widget backgroundColor="#18188b" font="Regular;16" halign="center" name="buttonblue" position="505,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="120,40" valign="center" />
<widget name="gemfury" position="690,6" size="114,36" alphatest="on" />
<widget name="info" position="635,5" size="40,20" alphatest="on" />
<widget name="menu" position="635,25" size="40,20" alphatest="on" />
<eLabel backgroundColor="grey" position="10,50" size="800,1" />
<widget name="config" position="15,60" size="790,480" enableWrapAround="1" scrollbarMode="showOnDemand" />
<eLabel backgroundColor="grey" position="10,545" size="800,1" />
<widget name="text" foregroundColor="white" backgroundColor="background" position="10,550" size="810,25" font="Regular;21" zPosition="1" halign="center" valign="center" transparent="0"/>
</screen>"""
def __init__(self, session, args = 0):
Screen.__init__(self, session)
url=getFeedUrl().split()[2]
self.host,self.resolv = checkHost(url)
cprint("FEED: %s HOST: %s" % (url,self.host))
self.list = []
# explizit check on every entry
self.onChangedEntry = []
self.onConfigEntryChanged = []
ConfigListScreen.__init__(self, self.list, session = self.session, on_change = self.changedEntry)
self.updates=[]
self.onShown.append(self.setWindowTitle)
self.updates=self.createSetup(True)
self["buttonred"] = Label(_("Exit"))
self["buttongreen"] = Label(_("Actions"))
self["buttonyellow"] = Label(_("Update"))
self["buttonblue"] = Label(_("About"))
self["text"] = Label()
self["logo"] = Pixmap()
self["menu"] = Pixmap()
self["info"] = Pixmap()
self["gemfury"] = Pixmap()
self.ipkg = IpkgComponent()
self.ipkg.addCallback(self.ipkgCallback)
cprint("restart not (yet) needed")
self.restartNeeded=False
HelpableScreen.__init__(self)
self["colorActions"] = HelpableActionMap(self, "ColorActions",
{
"red": (self.redPressed,_("Exit")),
"green": (self.greenPressed,_("select actions")),
"yellow": (self.okPressed,_("Package action")),
"blue": (self.bluePressed,_("About")),
}, -2)
self["setupActions"] = HelpableActionMap(self, "SetupActions",
{
#"save": (self.save,_("Save")),
"cancel": (self.redPressed,_("Exit")),
"ok": (self.okPressed,_("Select")),
"left": (self.ownKeyLeft,_("Left")),
"right": (self.ownKeyRight,_("Right")),
}, -2)
self["channelSelectActions"] = HelpableActionMap(self, "ChannelSelectEPGActions",
{
"showEPGList": (self.infoPressed,_("Information about the package")),
}, -2)
text_menu=_("Setup open")
self["menuActions"] = HelpableActionMap(self, "MenuActions",
{
"menu": (self.openSetup,text_menu),
}, -2)
# for new RC use Audio key as Help key alternative
self["InfobarAudioSelectionActions"] = HelpableActionMap(self,"InfobarAudioSelectionActions",
{
"audioSelection": (self.audioPressed,_("show Help screen")),
}, -3)
#watch for filechanges
self.filewatchStart()
self.filewatchDebStart()
if config.plugins.svenh.feed.value:
addFeed(False) # if feed changed ...
self.updateFeed(True) # quiet update on startup
def audioPressed(self):
audio2Help()
def ownKeyLeft(self):
self["config"].pageUp()
def ownKeyRight(self):
self["config"].pageDown()
def filewatchStart(self):
#Package-File
self.md5_package = {}
packagesList = getPackagesList()
for packagefile in packagesList:
if os_path.exists(packagefile):
self.md5_package[packagefile] = hashlib.md5(open(packagefile,'rb').read()).hexdigest()
self.filewatch_package = eFileWatch("/var/lib/apt/lists", False, eFileEvent.MOVE)
self.filewatch_package_conn = self.filewatch_package.fileChanged.connect(self.filewatchEvent)
self.filewatch_package.startWatching()
self.md5_status = ""
if os_path.exists(plugin_status_file):
self.md5_status = hashlib.md5(open(plugin_status_file,'rb').read()).hexdigest()
self.filewatch_status = eFileWatch("/var/lib/dpkg", False, eFileEvent.MOVE)
self.filewatch_status_conn = self.filewatch_status.fileChanged.connect(self.filewatchEvent)
self.filewatch_status.startWatching()
def filewatchEvent(self, watch, event):
dir = watch.getDirectory()
filename = event.getFullPath()
if filename == plugin_status_file:
if os_path.exists(plugin_status_file):
md5_status = hashlib.md5(open(plugin_status_file,'rb').read()).hexdigest()
if md5_status != self.md5_status:
cprint("CHANGED %s, %s call createSetup, %s, %s" % (dir, filename, self.md5_status, md5_status))
self.md5_status = md5_status
self.updates=self.createSetup()
self.updateWindowTitle()
packagesList=getPackagesList()
#print(">>>> filename, packages", filename, packagesList)
if filename in packagesList:
if os_path.exists(filename):
md5_package = hashlib.md5(open(filename,'rb').read()).hexdigest()
if md5_package != self.md5_package.get(filename,0):
cprint("CHANGED %s, %s call createSetup, %s, %s" % (dir, filename, self.md5_package.get(filename,0), md5_package))
self.md5_package[filename] = md5_package
self.updates=self.createSetup()
self.updateWindowTitle()
def filewatchDebStart(self):
#local feed
if config.plugins.svenh.local.value != "none":
deb_directory = self.getLocalPath()
self.filewatch_deb = eFileWatch(deb_directory, False, eFileEvent.CLOSE_WRITE | eFileEvent.DELETE)
self.filewatch_deb_conn = self.filewatch_deb.fileChanged.connect(self.filewatchEventDeb)
self.filewatch_deb.startWatching()
else:
self.filewatch_deb = None
def filewatchDebStop(self):
if self.filewatch_deb and self.filewatch_deb.isWatching():
self.filewatch_deb.stopWatching()
def filewatchEventDeb(self, watch, event):
filename = event.getFullPath()
directory = self.getLocalPath()
boxkit=getArch()+".deb"
if filename.endswith("all.deb") or filename.endswith(boxkit):
cprint("CHANGED LOCAL FEED %s, %s call createSetup" % (dir, filename))
self.updates=self.createSetup()
self.updateWindowTitle()
def getLocalPath(self):
if config.plugins.svenh.local.value == "user":
deb_directory = "%s" % config.plugins.svenh.local_user_path.value
else:
deb_directory = "/%s" % config.plugins.svenh.local.value
return deb_directory
def infoPressed(self):
self.open_info()
def bluePressed(self):
self.session.open(MessageBox, _("Feed Plugin v%s by Sven H (2022)") % plugin_version, MessageBox.TYPE_INFO, timeout=plugin_timeout)
def showLastLog(self):
if os_path.exists(plugin_log):
cmd = "cat %s" % plugin_log
self.session.open(Console,plugin_log,[cmd])
else:
self.session.open(MessageBox, _("none")+ " "+plugin_log, MessageBox.TYPE_ERROR)
def changeFeedCallback(self, answer):
cprint(">>>>>>> changeFeedCallback, %s %s" % (answer,self.new_feed))
if answer:
removeFeed()
config.plugins.svenh.feed_version.value = self.new_feed
config.plugins.svenh.feed_version.save()
cprint("new feed_version: %s" % config.plugins.svenh.feed_version.value)
self.md5_package = {}
addFeed(update=False)
self.aptUpdate()
self.session.open(MessageBox, _("Trying to download a new packetlist. Please wait..."), MessageBox.TYPE_INFO, timeout=plugin_timeout)
def greenPressed(self):
cur = self["config"].getCurrentIndex()
list = []
list.append((_("Package list update"), "feed_update"))
list.append((_("Package list update complete (upgrade)"), "feed_upgrade"))
list.append((_("Package list update reset (repair)"), "feed_repair"))
if len(self.updates) > 0:
list.append((_("Update all available updates"), "update_available"))
if cur and config.plugins.svenh.local.value != "none":
if len(self.argument[cur])>2 and not self.argument[cur][6]:
#print(cur, self["config"].getCurrent()[0], self.argument[cur][6])
list.append((_("Download") + ": '" + self["config"].getCurrent()[0] + "' -> " + self.getLocalPath(), "download_deb"))
if cur and len(self.argument[cur])>2 and self.argument[cur][6]:
#print(cur, self["config"].getCurrent()[0], self.argument[cur][6])
list.append((_("Delete") + ": '" + self["config"].getCurrent()[0] + "' -> " + self.getLocalPath(), "delete_deb"))
list.append((_("Show Log")+": "+plugin_log, "showLastLog"))
self.session.openWithCallback(
self.menuCallback,
ChoiceBox,
title = _("Following tasks will be done after you press OK!").replace("!",":"),
windowTitle = getTitle(),
list = list,
)
def openSetup(self):
self.session.openWithCallback(self.setupCallback,SvenH_Setup)
def menuCallback(self, ret):
ret = ret and ret[1]
if ret:
if ret == "feed_update":
self.session.open(MessageBox, _("Trying to download a new packetlist. Please wait..."), MessageBox.TYPE_INFO, timeout=plugin_timeout)
self.aptUpdate()
elif ret == "feed_upgrade":
text = "all upcoming updates will be installed (also from all other feeds)."
text+= "\n\nDo you really want to update all upcoming updates ?"
self.session.openWithCallback(self.feedUpgradeCallback, MessageBox, text)
elif ret == "feed_repair":
self.feedRepair()
elif ret == "update_available":
feed_updates = []
local_updates = []
cmd = ""
for package in self.argument:
if len(package) > 3 and package[3] == UPDATENEEDED and package[6]:
local_updates.append(package[6])
elif len(package) > 3 and package[3] == UPDATENEEDED:
feed_updates.append(package[2])
all_feed_updates = " ".join(feed_updates)
all_local_updates = " ".join(local_updates)
self.deb = all_feed_updates + all_local_updates
cprint("update all: %s" % all_feed_updates)
title = _("available updates")
if all_feed_updates:
cmd = "apt-get -o=Dpkg::Use-Pty=0 --reinstall --only-upgrade install %s -f -y --assume-yes; apt-get -o=Dpkg::Use-Pty=0 install -f -y --assume-yes" % (all_feed_updates)
if all_local_updates:
if cmd:
cmd += "; "
cmd += "dpkg --force-all -i %s; apt-get -o=Dpkg::Use-Pty=0 install -f -y --assume-yes" % (all_local_updates)
self.session.openWithCallback(self.finishedConsole,Console,_(title),[cmd], None, False, plugin_log)
elif ret == "download_deb":
cur = self["config"].getCurrentIndex()
if cur and len(self.argument[cur])>2 and not self.argument[cur][6]:
text=_("Do you really want to continue?")
replacestr=" "+_("Downloading").lower()+" %s?" % self.argument[cur][2]
print(self.argument[cur])
question=text.replace("?",replacestr)
self.session.openWithCallback(self.downloadDebCallback, MessageBox, question, MessageBox.TYPE_YESNO)
elif ret == "delete_deb":
cur = self["config"].getCurrentIndex()
if cur and len(self.argument[cur])>2 and self.argument[cur][6] and os_path.exists(self.argument[cur][6]):
self.session.openWithCallback(self.deleteDebCallback, MessageBox, _("Do you really want to delete %s?") % self.argument[cur][6], MessageBox.TYPE_YESNO)
elif ret == "showLastLog":
self.showLastLog()
def feedUpgradeCallback(self, ret):
cprint(">>>> feedUpgradeCallback %s" % ret)
if ret:
self.session.open(MessageBox, _("Trying to download a new packetlist. Please wait...").replace("...","")+" for "+_("Software update"), MessageBox.TYPE_INFO, timeout=plugin_timeout)
self.aptUpgrade()
def setupCallback(self, ret):
cprint(">>>> setupCallback %s" % ret)
if ret:
self["buttonyellow"].setText(" ")
if config.plugins.svenh.feed.value:
addFeed(update=False)
self.aptUpdate()
else:
removeFeed()
self.md5_package = {}
self.updates = self.createSetup()
self.updateWindowTitle()
if config.plugins.svenh.local.value != "none":
self.filewatchDebStart()
else:
self.filewatchDebStop()
def downloadDebCallback(self, ret):
if ret:
cur = self["config"].getCurrentIndex()
if len(self.argument[cur])>2 and not self.argument[cur][6]:
self.download_directory = self.getLocalPath()
self.download_kit=self.argument[cur][2]
cmd = "cd %s; rm %s*.deb; apt-get -o=Dpkg::Use-Pty=0 download %s" % (self.download_directory,self.download_kit,self.download_kit)
self.download = eConsoleAppContainer()
self.download_conn = self.download.appClosed.connect(self.downloadDebFinished)
self.download.execute(cmd)
def downloadDebFinished(self, ret):
text=_("Download")+" "+self.download_directory+"/"+self.download_kit+" "+_("Execution finished!!").replace("!!","!")
self.session.open(MessageBox, text, MessageBox.TYPE_INFO, timeout=plugin_timeout)
def deleteDebCallback(self, ret):
if ret:
cur = self["config"].getCurrentIndex()
if len(self.argument[cur])>2 and self.argument[cur][6] and os_path.exists(self.argument[cur][6]):
os_remove(self.argument[cur][6])
cprint("delete local deb: %s" % self.argument[cur][6])
#reload createSetup with Filewatcher after delete
def feedRepair(self):
cprint("menu pressed")
if checkApt():
checkApt(True)
# repair stranded locks
if os_path.exists("/var/lib/apt/lists/lock"):
os_remove("/var/lib/apt/lists/lock")
if os_path.exists("/var/lib/apt/lists/lock"):
os_remove("/var/lib/apt/lists/lock")
if checkApt(): # should NOT be true anymore ...
self.session.open(MessageBox, _("Upgrading Dreambox... Please wait"), MessageBox.TYPE_ERROR, timeout=plugin_timeout)
else:
self.session.open(MessageBox, _("There was an error downloading the packetlist. Please try again."), MessageBox.TYPE_WARNING, timeout=plugin_timeout)
else:
# repair the rest
cmd = "dpkg --configure -a; apt-get -qq -o=Dpkg::Use-Pty=0 update; apt-get -qq -o=Dpkg::Use-Pty=0 install -f -y --assume-yes; apt-get autoremove -f -y --assume-yes; apt-get -qq -o=Dpkg::Use-Pty=0 clean"
title=_("Feed repair")
start_text = _("Feed repair is running. Please wait ...")
self.session.open(Console,_(title),[cmd], None, False, plugin_log, start_text)
def selectionChanged(self):
cprint(">>>> selectionChanged")
cur = self["config"].getCurrentIndex()
if self["config"].getCurrent()[1] == config.plugins.svenh.package_empty:
self["buttonblue"].setText(" ") #- dont set because on start ipkgupdate set to "...."
self["buttonyellow"].setText(" ")
else:
task=self.argument[cur][3]
if task==INSTALLABLE:
self["buttonyellow"].setText(_("Install"))
elif task==UPDATENEEDED:
self["buttonyellow"].setText(_("Update"))
elif task==DOWNGRADE:
self["buttonyellow"].setText(_("Downgrade"))
else: # UNINSTALL
self["buttonyellow"].setText(_("Uninstall"))
if self["buttonblue"].getText() == " ":
self["buttonblue"].setText(_("About")) #- dont set because on start ipkgupdate set to "...."
if not self["text"].getText().startswith(_("State")):
name = self.argument[cur][0] # plugin name
if config.plugins.svenh.show_info.value == "desc":
description = " ".join(self.argument[cur][1]).replace(" ", " ") # merge description lines
if description != name:
description = description.replace(name,"") # description without name
self["text"].setText(_("Description") + ": " + description) # show description in the info-line
else:
self["text"].setText(_("Name") + ": " + self.argument[cur][2]) # show packagename
def createSetup(self, first=False):
global statusfile_data
statusfile_data = ""
updates=[]
self.list = []
self.argument = []
self.list_update_all = []
self.argument_update_all = []
r = 0
if self.resolv is None:
error=_("Your dreambox isn't connected to the internet properly. Please check it and try again.")
err=error.split(".")
self.list.append(getConfigListEntry(err[0], config.plugins.svenh.package_empty))
if len(err) > 1:
self.list.append(getConfigListEntry(err[1], config.plugins.svenh.package_empty))
self["config"].list = self.list
self["config"].l.setList(self.list)
return []
if config.plugins.svenh.feed.value:
feedList = []
feedList.append(plugin_feedName)
for feedname in feedList:
packages_file = getPackages(feedname)
content=""
if os_path.exists(packages_file):
f=open(packages_file,"r")
content = f.read()
f.close()
#cprint(">>>> package: %s" % packages_file)
#cprint(">>>> createSetup len content: %d" % len(content))
if len(content) > 0 and config.plugins.svenh.listview.value!="false":
self.argument.append((str(r)))
r+=1
self.list.append(("%s %s (c) %s %s" % (gheader,_("Plugins"),feedname,gtrailer), ))
content=content.replace("\n ",", ").replace("\n ",", ")
upackages=content.strip().split("\n\n")
packages=sortPackages(upackages)
x=0
boxarch=getArch()
#sorting by status (updates first) or by AZ
self.list_update = []
self.list_new = []
self.list_none = []
self.argument_update = []
self.argument_new = []
self.argument_none = []
svenh_argument=None
for package in packages:
desc=package['Description'].split(",")
name=package['PackageName']
parch=package['Architecture']
if (parch=="all" or parch==boxarch):
kit=name
new=package['Version'].strip()
current=currentVersion(package['Package'])
#fix for CSP-Version from DP-Feed - for example 0.1.0-r8+git0+570434d592-r0.0
gitPos = current.find("+git")
#print(">>> name", name)
if name == "ChannelSelection Plus" and gitPos>0:
current = current[:gitPos]
#print(">>> currentversion", current)
deb=package['Package']
depends=None
try:
depends=package['Depends'].split(",")
except:
pass
if not depends is None:
for dep in depends:
if dep.find(feedPlugin_PackageName) != -1:
depends.remove(dep)
if len(depends) < 1:
depends=None
if config.plugins.svenh.version.value:
kit+=" v%s" % new
if config.plugins.svenh.size.value:
size=int(package['Size'])//1024
kit+=" - %dkB" % (size)
debkit=None
if "SvenH Feed-Plugin" in name:
try:
date=package['Date'].strip()
sp=date.split()
ymd="%s%s%02d" % (sp[3],abbr_to_num(sp[2]),int(sp[1]))
new=new+"-"+ymd
except:
pass
#cprint("current: %s new: %s" % (current,new))
if current == _("none"):
status=INSTALLABLE
elif Version(current) == Version(new):
status=INSTALLED
elif Version(current) > Version(new):
status=DOWNGRADE
else:
status=UPDATENEEDED
if "SvenH Feed-Plugin" in name:
svenh_argument = (name,desc,deb,status,new,depends,debkit,feedname)
if config.plugins.svenh.listview.value != "sort":
if current == _("none"):
self.list.append(getConfigListEntry(kit, config.plugins.svenh.package_install))
elif Version(current) == Version(new):
self.list.append(getConfigListEntry(kit, config.plugins.svenh.package_uninstall))
elif Version(current) > Version(new):
self.list.append(getConfigListEntry(kit, config.plugins.svenh.package_downgrade))
else:
self.list.append(getConfigListEntry(kit, config.plugins.svenh.package_update))
updates.append(deb)
self.list_update.append(getConfigListEntry(kit, config.plugins.svenh.package_update))
self.argument_update.append((name,desc,deb,status,new,depends,debkit,feedname))
# arguments for real plugins
self.argument.append((name,desc,deb,status,new,depends,debkit,feedname))
else:
if current == _("none"):
self.list_none.append(getConfigListEntry(kit, config.plugins.svenh.package_install))
self.argument_none.append((name,desc,deb,status,new,depends,debkit,feedname))
elif Version(current) == Version(new):
self.list_new.append(getConfigListEntry(kit, config.plugins.svenh.package_uninstall))
self.argument_new.append((name,desc,deb,status,new,depends,debkit,feedname))
elif Version(current) > Version(new):
self.list_new.append(getConfigListEntry(kit, config.plugins.svenh.package_downgrade))
self.argument_new.append((name,desc,deb,status,new,depends,debkit,feedname))
else:
self.list_update.append(getConfigListEntry(kit, config.plugins.svenh.package_update))
self.argument_update.append((name,desc,deb,status,new,depends,debkit,feedname))
updates.append(deb)
if config.plugins.svenh.listview.value == "sort":
self.list.extend(self.list_update)
self.argument.extend(self.argument_update)
self.list.extend(self.list_new)
self.argument.extend(self.argument_new)
self.list.extend(self.list_none)
self.argument.extend(self.argument_none)
if not svenh_argument is None:
#set feed plugin to first
idx = self.argument.index(svenh_argument)
entry = self.argument.pop(idx)
self.argument.insert(1,entry)
entry = self.list.pop(idx)
self.list.insert(1,entry)
if self.list_update: # fill update_all over all feeds
self.list_update_all.extend(self.list_update)
self.argument_update_all.extend(self.argument_update)
if config.plugins.svenh.local.value != "none":
directory = self.getLocalPath()
self.list.append(("%s %s %s %s" % (gheader,_("Plugins"), directory,gtrailer), ))
r+=1
self.argument.append((str(r)))
boxkit=getArch()+".deb"
self.list_update = []
self.list_new = []
self.list_none = []
self.list_down = []
self.argument_update = []
self.argument_new = []
self.argument_none = []
self.argument_down = []
feedname="local"
filelist = sorted(os_listdir(directory))
for file in filelist:
if file.endswith("all.deb") or file.endswith(boxkit):
# should be moved were needed ... too slow ...
#changelog,copyright,readme=parseDoc(directory,file)
#cprint("changelog: %s copyright: %s README: %s" % (changelog,copyright,readme))
name,desc,deb,status,new,depends,md5sums=parseDeb(directory,file)
kit=name
current=currentVersion(deb, feedDeb=False)
#fix for CSP-Version from DP-Feed - for example 0.1.0-r8+git0+570434d592-r0.0
gitPos = current.find("+git")
if name == "ChannelSelection Plus" and gitPos>0:
current = current[:gitPos]
#print(">>> currentversion", current)
if current == _("none"):
status=INSTALLABLE
elif Version(current) == Version(new):
status=INSTALLED
elif Version(current) > Version(new):
status=DOWNGRADE
else:
status=UPDATENEEDED
if not depends is None:
for dep in depends:
if dep.find(feedPlugin_PackageName) != -1:
depends.remove(dep)
if len(depends) < 1:
depends=None
if config.plugins.svenh.version.value:
kit+=" v%s" % new
if config.plugins.svenh.size.value:
stat=os_stat("%s/%s" % (directory,file))
kit+=" - %dkB" % (int(stat.st_size//1024))
debkit="%s/%s" % (directory,file)
if config.plugins.svenh.listview.value!="sort":
if current == _("none"):
self.list.append(getConfigListEntry(kit, config.plugins.svenh.package_install))
elif Version(current) == Version(new):
self.list.append(getConfigListEntry(kit, config.plugins.svenh.package_uninstall))
elif Version(current) > Version(new):
self.list.append(getConfigListEntry(kit, config.plugins.svenh.package_downgrade))
else:
self.list.append(getConfigListEntry(kit, config.plugins.svenh.package_update))
updates.append(deb)
self.list_update.append(getConfigListEntry(kit, config.plugins.svenh.package_update))
self.argument_update.append((name,desc,deb,status,new,depends,debkit,feedname))
updates.append(deb)
# arguments for real plugins
#cprint("name %s desc %s deb %s status %s new %s depends %s" % (name,desc,deb,status,new,depends))
self.argument.append((name,desc,deb,status,new,depends,debkit,feedname))
else:
if current == _("none"):
self.list_none.append(getConfigListEntry(kit, config.plugins.svenh.package_install))
self.argument_none.append((name,desc,deb,status,new,depends,debkit,feedname))
elif Version(current) == Version(new):
self.list_new.append(getConfigListEntry(kit, config.plugins.svenh.package_uninstall))
self.argument_new.append((name,desc,deb,status,new,depends,debkit,feedname))
elif Version(current) > Version(new):
self.list_down.append(getConfigListEntry(kit, config.plugins.svenh.package_downgrade))
self.argument_down.append((name,desc,deb,status,new,depends,debkit,feedname))
else:
self.list_update.append(getConfigListEntry(kit, config.plugins.svenh.package_update))
self.argument_update.append((name,desc,deb,status,new,depends,debkit,feedname))
updates.append(deb)
if config.plugins.svenh.listview.value == "sort":
self.list.extend(self.list_update)
self.argument.extend(self.argument_update)
self.list.extend(self.list_new)
self.argument.extend(self.argument_new)
self.list.extend(self.list_none)
self.argument.extend(self.argument_none)
self.list.extend(self.list_down)
self.argument.extend(self.argument_down)
if self.list_update: # fill update_all over all feeds and local
self.list_update_all.extend(self.list_update)
self.argument_update_all.extend(self.argument_update)
#updates = list( dict.fromkeys(updates) ) # delete duplicates from local
# show all updates on top of the list
if config.plugins.svenh.show_update_section.value and self.list_update_all:
self.list_update_all.extend(self.list)
self.argument_update_all.extend(self.argument)
self.list = self.list_update_all
self.argument = self.argument_update_all
self.list.insert(0,("%s %s %s %s" % (gheader,_("Plugins"), _("Updates"),gtrailer), ))
self.argument.insert(0,("0"))
if len(self.list) == 1: #avoid gs if list has only a section, but not packages
self.list.append(getConfigListEntry(" no package found", config.plugins.svenh.package_empty))
self.argument.append(("no package","no desc"))
if len(self.list) == 0: #if feed is disabled
self.list.append(getConfigListEntry(" not activated - go to setup on menu-key", config.plugins.svenh.package_empty))
self.argument.append(("not activated","not activated"))
self["config"].list = self.list
self["config"].l.setList(self.list)
if first:
self["config"].onSelectionChanged.append(self.selectionChanged)
print(updates)
return updates
def keyNumberGlobal(self, number):
pass #to prevent changedEntry on any KeyNumber pressed
def changedEntry(self):
cprint(">>>> changedEntry")
def setWindowTitle(self):
self.updateWindowTitle()
self["logo"].instance.setPixmapFromFile("%s/plugin.png" % plugindir)
self["gemfury"].instance.setPixmapFromFile("%s/gemfury.png" % plugindir)
self["menu"].instance.setPixmapFromFile(getPiconPath("menu"))
self["info"].instance.setPixmapFromFile(getPiconPath("info"))
def updateWindowTitle(self):
if len(self.updates) > 0:
self.setTitle(getTitle()+" v"+plugin_version+" (%d %s)" % (len(self.updates),_("Update")))
else:
self.setTitle(getTitle()+" v"+plugin_version)
def redPressed(self):
if self.restartNeeded:
cprint("restart handling")
self.restartHandling(False)
else:
cprint("direct close")
self.close(False)
def cancel(self,answer):
if answer:
for x in self["config"].list:
if len(x) > 1:
x[1].cancel()
if config.plugins.svenh.feed.value:
addFeed()
else:
removeFeed()
if self.restartNeeded:
cprint("restart handling")
self.restartHandling(False)
else:
cprint("direct close")
self.close(False)
else:
if not os_path.exists(plugin_feedlist) and config.plugins.svenh.feed.value:
addFeed()
def open_info(self):
cur = self["config"].getCurrentIndex()
if not cur or self["config"].getCurrent()[1] == config.plugins.svenh.package_empty:
return
if config.plugins.svenh.version.value:
title=_("About")+" "+self.argument[cur][0]+" V"+self.argument[cur][4]
else:
title=_("About")+" "+self.argument[cur][0]
header=self.argument[cur][0] # name
# merge description lines
footer=" ".join(self.argument[cur][1])
footer=footer.replace(header,"") # description without name
package=self.argument[cur][2]
package_status=self.argument[cur][3]
localdeb = self.argument[cur][6]
feedname = self.argument[cur][7]
cprint("INFO: %s %s %s %s %s %s" % (title,header,footer, package, package_status,localdeb))
title = _("Info") + " " + header
self.session.open(SvenH_Info, title, header, footer, package, package_status, localdeb, feedname)
def aptUpgrade(self):
# apt get update should be already done ...
cprint("apt-get upgrade")
upgrade_args = {'use_maintainer' : False, 'test_only': False}
self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE,upgrade_args)
self["text"].setText(_("State") + ": " + _("Update")+" "+_("In Progress")+" ......")
def aptUpdate(self):
cprint("apt-get update")
self["text"].setText(_("State") + ": " + _("Update")+" "+_("In Progress")+" ...")
self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
def ipkgCallback(self, event, param = None):
if event == self.ipkg.EVENT_DONE:
cprint("apt-get done")
self["text"].setText("")
self.selectionChanged() #change info-text after aptUpdate
#self.createSetup() # call from filewatcher
def updateFeed(self,quiet=False):
if config.plugins.svenh.feed.value:
if not quiet:
self.session.open(MessageBox, _("Trying to download a new packetlist. Please wait..."), MessageBox.TYPE_INFO, timeout=plugin_timeout)
cprint("updateFeed aptUpdate")
self.aptUpdate()
def okPressed(self):
cur = self["config"].getCurrentIndex()
current = self["config"].getCurrent()
if cur == 0 or self["config"].getCurrent()[1] == config.plugins.svenh.package_empty:
return
if len(self.argument[cur])<3:
return
if checkApt():
self.session.open(MessageBox, _("Upgrading Dreambox... Please wait"), MessageBox.TYPE_ERROR, timeout=plugin_timeout)
else:
self.name=self.argument[cur][0]
self.desc=self.argument[cur][1]
self.deb=self.argument[cur][2]
self.task=self.argument[cur][3]
self.new=self.argument[cur][4]
self.depends=self.argument[cur][5]
self.debkit=self.argument[cur][6]
if self.task==INSTALLABLE:
text=_("This plugin will be installed")+": %s ?" % self.name
if config.plugins.svenh.confirm.value=="true":
self.session.openWithCallback(self.debInstall,MessageBox,text,MessageBox.TYPE_YESNO)
else:
self.debInstall(True)
elif self.task==UPDATENEEDED:
text=_("Do you want to upgrade the package: %s") % self.name
if config.plugins.svenh.confirm.value=="true":
self.session.openWithCallback(self.debInstall,MessageBox,text,MessageBox.TYPE_YESNO)
else:
self.debInstall(True)
elif self.task==DOWNGRADE:
if "SvenH Feed-Plugin" in self.name:
if config.plugins.svenh.confirm.value!="false":
text=_("Downgrade")+" %s " % self.name +_("disabled")
self.session.open(MessageBox,text, MessageBox.TYPE_ERROR)
else:
tt=_("There might not be enough Space on the selected Partition.\nDo you really want to continue?")
sp=tt.split("\n")
if len(sp) > 1:
text=_("Downgrade")+" %s. " % self.name+sp[1]
else:
text=_("Downgrade")+" %s?)" % self.name
if config.plugins.svenh.confirm.value=="true":
self.session.openWithCallback(self.debInstall,MessageBox,text, MessageBox.TYPE_YESNO)
else:
self.debInstall(True)
else:
if "SvenH Feed-Plugin" in self.name:
if config.plugins.svenh.confirm.value!="false":
text=_("This plugin will be removed")+":\n - %s" % self.name
text+="\n\n\n" + _("All other installed plugins from the feed will not be removed.")
text+="\n\n" + _("Do you really want to remove this feed plugin?")
self.session.openWithCallback(self.debInstall,MessageBox,text,MessageBox.TYPE_YESNO)
else:
text=_("This plugin will be removed")+": %s" % self.name
if config.plugins.svenh.confirm.value=="true":
self.session.openWithCallback(self.debInstall,MessageBox,text,MessageBox.TYPE_YESNO)
else:
self.debInstall(True)
def skipInstall(self):
text=_("No, do nothing.").replace(".","!")
self.session.open(MessageBox,text, MessageBox.TYPE_WARNING)
def debInstall(self,answer):
if answer is None:
self.skipInstall()
elif answer is False:
self.skipInstall()
else:
if not self.debkit is None:
cprint("package: %s kit: %s version: %s" % (self.deb,self.debkit,self.new))
script=""
if self.task==INSTALLABLE:
title = _("This plugin will be installed")+": %s" % self.name
cmd = "dpkg --force-all -i %s; apt-get -o=Dpkg::Use-Pty=0 install -f -y --assume-yes%s" % (self.debkit,script)
elif self.task==UPDATENEEDED:
title = _("This plugin will be updated")+": %s" % self.name
cmd = "apt-mark unhold %s > /dev/null 2>&1; dpkg --force-all -i %s; apt-get -o=Dpkg::Use-Pty=0 install -f -y --assume-yes%s" % (self.deb, self.debkit,script)
elif self.task==DOWNGRADE:
title = _("This plugin will be downgrade")+": %s" % self.name
cmd = "apt-mark unhold %s > /dev/null 2>&1; dpkg --force-all -i %s; apt-get -o=Dpkg::Use-Pty=0 install -f -y --assume-yes%s" % (self.deb, self.debkit, script)
else: # UNINSTALL
title = _("This plugin will be removed")+": %s" % self.name
cmd = "apt-mark unhold %s > /dev/null 2>&1; dpkg --force-all -r %s; apt-get -o=Dpkg::Use-Pty=0 autoremove -f -y --assume-yes" % (self.deb, self.deb)
else:
cprint("package: %s version: %s" % (self.deb,self.new))
script=""
if self.task==INSTALLABLE:
title = _("This plugin will be installed")+": %s" % self.name
cmd = "apt-get -o=Dpkg::Use-Pty=0 install %s -f -y --assume-yes; apt-get install -o=Dpkg::Use-Pty=0 -f -y --assume-yes%s" % (self.deb,script)
elif self.task==UPDATENEEDED:
title = _("This plugin will be updated")+": %s" % self.name
cmd = "apt-get -o=Dpkg::Use-Pty=0 --reinstall --only-upgrade install %s -f -y --assume-yes; apt-get -o=Dpkg::Use-Pty=0 install -f -y --assume-yes%s" % (self.deb,script)
elif self.task==DOWNGRADE:
title = _("This plugin will be downgrade")+": %s" % self.name
cmd = "apt-get -o=Dpkg::Use-Pty=0 --only-upgrade install %s=%s -f -y --allow-downgrades; apt-get -o=Dpkg::Use-Pty=0 install -f -y --assume-yes%s" % (self.deb, self.new, script)
else: # UNINSTALL
title = _("This plugin will be removed")+": %s" % self.name
cmd = "apt-get -o=Dpkg::Use-Pty=0 remove %s -f -y --assume-yes; apt-get -o=Dpkg::Use-Pty=0 autoremove -f -y --assume-yes" % (self.deb)
self.session.openWithCallback(self.finishedConsole,Console,_(title),[cmd], None, False, plugin_log)
def finishedConsole(self):
if self.deb != feedPlugin_PackageName:
self.restartNeeded=True
elif self.deb == feedPlugin_PackageName and self.task==INSTALLED: #after uninstalling feed-plugin
removeFeed()
self.md5_package = {}
self.restartNeeded=True
self.updates=self.createSetup()
self.updateWindowTitle()
cprint("restart needed ... later")
#print(">>> installed deb: '%s', task: '%s'" % (self.deb, self.task))
def restartHandling(self,option=True):
self.option=option
if config.plugins.svenh.confirm.value=="info":
text=_("Restart required") + "\n\n" + _("Restart GUI")+"!"
self.session.openWithCallback(self.doExit,MessageBox,text, MessageBox.TYPE_INFO)
elif config.plugins.svenh.confirm.value=="true":
text=_("Restart required") + "\n\n" + _("Restart GUI")+"?"
self.session.openWithCallback(self.doRestart, MessageBox,text, MessageBox.TYPE_YESNO)
else: # false has currently no action - except closing ...
self.close(self.option)
def doRestart(self,answer):
if answer is None:
return
if answer is False:
self.close(self.option)
else:
self.session.open(TryQuitMainloop, 3)
self.close()
def doExit(self,answer):
if answer is None:
return
if answer is False:
return
else:
self.close(self.option)
#fix SSL error with getPage
from twisted.internet.ssl import ClientContextFactory
from twisted.internet._sslverify import ClientTLSOptions
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
class downloaderClientContextFactory(ClientContextFactory):
def __init__(self, url=None):
domain = urlparse(url).netloc
self.hostname = domain
def getContext(self, hostname=None, port=None):
ctx = ClientContextFactory.getContext(self)
if self.hostname and ClientTLSOptions is not None:
ClientTLSOptions(self.hostname, ctx)
return ctx
class fileDownloader:
def __init__(self, file):
cprint("fileDownloader::init file=%s" % (file))
self.urlbase=file
def getList(self, callback, errback):
cprint("fileDownloader:getList %s" % self.urlbase)
self.callback = callback
self.errback = errback
header = {"Cache-Control": "no-cache", "Pragma": "no-cache"}
onwContextFactory = downloaderClientContextFactory(self.urlbase) if "https" in self.urlbase else None
getPage(self.urlbase, contextFactory = onwContextFactory, headers=header).addCallback(self.file_finished).addErrback(self.file_failed)
def file_failed(self, failure_instance):
cprint("fileDownloads:file_failed %s" % self.urlbase)
self.errback(failure_instance.getErrorMessage())
def file_finished(self, file):
cprint("fileDownloader:file_finished %s" % self.urlbase)
self.callback(file)
class CheckPackages(Screen):
def __init__(self, session):
Screen.__init__(self, session)
cprint("STARTS watching Packages File")
# always watch for Package file changes...
self.md5_package = {}
packagesList = getPackagesList()
for packagefile in packagesList:
if os_path.exists(packagefile):
self.md5_package[packagefile] = hashlib.md5(open(packagefile,'rb').read()).hexdigest()
self.filewatcher = eFileWatch("/var/lib/apt/lists", False, eFileEvent.MOVE)
self.filewatcher_conn = self.filewatcher.fileChanged.connect(self.fileEvent)
self.filewatcher.startWatching()
def fileEvent(self, watch, event):
dir = watch.getDirectory()
filename = event.getFullPath()
packagesList=getPackagesList()
print(">>>> filename, packages", filename, packagesList)
if filename in packagesList:
if os_path.exists(filename):
md5_package = hashlib.md5(open(filename,'rb').read()).hexdigest()
if md5_package != self.md5_package.get(filename,0):
cprint("CHANGED %s, %s call metaDreamy, %s, %s" % (dir, filename,self.md5_package.get(filename,0), md5_package))
self.md5_package[filename] = md5_package
# check Packages file for changes ...
metaDreamy(config.plugins.svenh.feed.value)
class SvenH_Info(Screen,HelpableScreen):
if sz_w == 1920:
skin = """
<screen name="SvenH_Info" position="center,170" size="1200,890" >
<widget name="logo" position="20,10" size="150,60" />
<widget backgroundColor="#9f1313" font="Regular;26" halign="center" name="buttonred" position="180,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="180,60" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;26" halign="center" name="buttongreen" position="370,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="180,60" valign="center" />
<widget backgroundColor="#a08500" font="Regular;26" halign="center" name="buttonyellow" position="560,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="180,60" valign="center" />
<widget backgroundColor="#18188b" font="Regular;26" halign="center" name="buttonblue" position="750,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="180,60" valign="center" />
<widget name="infokey" position="935,10" size="60,30" alphatest="on" />
<widget name="menukey" position="935,40" size="60,30" alphatest="on" />
<widget name="gemfury" position="1002,12" size="177,56" alphatest="on" />
<eLabel backgroundColor="grey" position="20,90" size="1160,1" />
<eLabel backgroundColor="grey" position="20,740" size="1160,1" />
<widget name="about" foregroundColor="yellow" position="20,750" size="1160,50" halign="center" valign="center" font="Regular;36"/>
<eLabel backgroundColor="grey" position="20,810" size="1160,1" />
<widget name="info" position="20,820" size="1160,50" halign="center" valign="center" foregroundColor="yellow" font="Regular;28"/>
<widget name="text" position="20,120" size="1160,600" font="Regular;26"/>
</screen>"""
elif sz_w == 2560:
skin = """
<screen name="SvenH_Info" position="center,200" size="1640,1160" >
<widget name="logo" position="20,10" size="200,80" />
<widget backgroundColor="#9f1313" font="Regular;32" halign="center" name="buttonred" position="230,10" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="240,80" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;32" halign="center" name="buttongreen" position="490,10" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="240,80" valign="center" />
<widget backgroundColor="#a08500" font="Regular;32" halign="center" name="buttonyellow" position="750,10" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="240,80" valign="center" />
<widget backgroundColor="#18188b" font="Regular;32" halign="center" name="buttonblue" position="1010,10" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="240,80" valign="center" />
<widget name="infokey" position="1270,10" size="80,40" alphatest="on" />
<widget name="menukey" position="1270,50" size="80,40" alphatest="on" />
<widget name="gemfury" position="1380,12" size="228,72" alphatest="on" />
<eLabel backgroundColor="grey" position="20,100" size="1600,2" />
<eLabel backgroundColor="grey" position="20,940" size="1600,2" />
<widget name="about" position="20,960" size="1600,60" halign="center" valign="center" foregroundColor="yellow" font="Regular;48" />
<eLabel backgroundColor="grey" position="20,1040" size="1600,2" />
<widget name="info" position="20,1060" size="1600,60" halign="center" valign="center" foregroundColor="yellow" font="Regular;40" />
<widget name="text" position="30,130" size="1590,800" font="Regular;40" />
</screen>"""
else:
skin = """
<screen name="SvenH_Info" position="center,100" size="820,580" >
<widget name="logo" position="10,5" size="100,40" />
<widget backgroundColor="#9f1313" font="Regular;16" halign="center" name="buttonred" position="115,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="120,40" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;16" halign="center" name="buttongreen" position="245,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="120,40" valign="center" />
<widget backgroundColor="#a08500" font="Regular;16" halign="center" name="buttonyellow" position="375,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="120,40" valign="center" />
<widget backgroundColor="#18188b" font="Regular;16" halign="center" name="buttonblue" position="505,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="120,40" valign="center" />
<widget name="infokey" position="635,5" size="40,20" alphatest="on" />
<widget name="menukey" position="635,25" size="40,20" alphatest="on" />
<widget name="gemfury" position="690,6" size="114,36" alphatest="on" />
<eLabel backgroundColor="grey" position="10,50" size="800,1" />
<eLabel backgroundColor="grey" position="10,470" size="800,1" />
<widget name="about" position="10,480" size="800,30" halign="center" valign="center" foregroundColor="yellow" font="Regular;24"/>
<eLabel backgroundColor="grey" position="10,520" size="800,1" />
<widget name="info" position="10,530" size="800,30" halign="center" valign="center" foregroundColor="yellow" font="Regular;20"/>
<widget name="text" position="15,65" size="795,400" font="Regular;20"/>
</screen>"""
def __init__(self, session, title, header, footer, package, package_status, localdeb, feedname):
Screen.__init__(self, session)
self.title=title + " (" + feedname + ")"
self.header=header
self.footer=footer
self.package=package
self.package_status=package_status
self.localdeb=localdeb
self.feedname=feedname
self.aptresult=""
cprint("title %s header %s footer %s package %s package_status %s localdeb %s" % (self.title,self.header, self.footer, self.package, self.package_status, self.localdeb))
self.onShown.append(self.setWindowTitle)
self["buttonred"] = Label(_("Exit"))
self["buttongreen"] = Label(_("Changelog"))
self["buttonyellow"] = Label("Copyright")
self["buttonblue"] = Label("README")
self["menukey"] = Pixmap()
self["infokey"] = Pixmap()
self["logo"] = Pixmap()
self["about"] = Label(self.header)
self["info"] = Label(self.footer)
self["gemfury"] = Pixmap()
self["text"] = ScrollLabel()
HelpableScreen.__init__(self)
self["colorActionsInfo"] = HelpableActionMap(self, "ColorActions",
{
"red": (self.cancel,_("Exit")),
"green": (self.greenPressed,_("Changelog")),
"yellow": (self.yellowPressed,_("Copyright")),
"blue": (self.bluePressed,_("README")),
}, -2)
self["setupActionsInfo"] = HelpableActionMap(self, "SetupActions",
{
"cancel": (self.cancel,_("Exit")),
}, -2)
self["directionActionsInfo"] = HelpableActionMap(self, "DirectionActions",
{
"up": (self["text"].pageUp,_("Up")),
"down": (self["text"].pageDown,_("Down")),
"left": (self["text"].pageUp,_("Up")),
"right": (self["text"].pageDown,_("Down")),
}, -2)
self["channelSelectBaseActionsInfo"] = HelpableActionMap(self, "ChannelSelectBaseActions",
{
"nextBouquet": (self.firstPage,_("Begin")),
"prevBouquet": (self["text"].lastPage,_("End")),
}, -2)
self["channelSelectActionsInfo"] = HelpableActionMap(self, "ChannelSelectEPGActions",
{
"showEPGList": (self.infoPressed,_("show Checksum information")),
}, -2)
text_menu=_("select menu options")
self["menuActionsInfo"] = HelpableActionMap(self, "MenuActions",
{
"menu": (self.menuPressed,text_menu),
}, -2)
# for new RC use Audio key as Help key alternative
self["InfobarAudioSelectionActionsInfo"] = HelpableActionMap(self,"InfobarAudioSelectionActions",
{
"audioSelection": (self.audioPressed,_("show Help screen")),
}, -3)
def firstPage(self):
cprint(">>> firstPage")
self["text"].long_text.move(ePoint(0,0))
self["text"].updateScrollbar()
def audioPressed(self):
audio2Help()
def setWindowTitle(self):
self.setTitle(self.title)
self["logo"].instance.setPixmapFromFile("%s/plugin.png" % plugindir)
self["gemfury"].instance.setPixmapFromFile("%s/gemfury.png" % plugindir)
self["menukey"].instance.setPixmapFromFile(getPiconPath("menu"))
self["infokey"].instance.setPixmapFromFile(getPiconPath("info"))
if len(self.aptresult)==0:
self.greenPressed() #load changelog
def menuPressed(self):
cprint(">>> menuPressed")
self.aptresult="apt"
list = []
list.append(("show", "apt-cache show %s" % self.package))
list.append(("depends", "apt-cache depends %s" % self.package))
list.append(("rdepends", "apt-cache rdepends %s" % self.package))
list.append(("list", "apt list %s" % self.package))
list.append(("stats", "apt-cache stats"))
list.append(("policy", "apt-cache policy"))
self.session.openWithCallback(
self.menuCallback,
ChoiceBox,
title = _("Following tasks will be done after you press OK!").replace("!",":"),
windowTitle = getTitle(),
list = list,
)
def menuCallback(self, command):
if command is None:
return
else:
cmd=command[1]
self.aptresult="%s:\n\n" % cmd
cprint("apt cmd: %s" % cmd)
self.aptcontainer = eConsoleAppContainer()
self.aptcontainer.dataAvail_conn = self.aptcontainer.dataAvail.connect(self.aptDataAvailable)
self.aptcontainer.appClosed_conn = self.aptcontainer.appClosed.connect(self.aptCacheFinished)
self.aptcontainer.execute(cmd)
def aptDataAvailable(self,str):
cprint(">>>> %s" % str)
if str.find("WARNING:") is -1:
self.aptresult+=str
def aptCacheFinished(self,ret):
cprint(self.aptresult)
self["text"].setText(self.aptresult)
def infoPressed(self):
self.aptresult=""
cprint(">>> infoPressed")
md5sums = ""
if self.localdeb and self.package_status in (INSTALLABLE, INSTALLED):
name,desc,deb,status,new,depends,md5sums = parseDeb(os_path.dirname(self.localdeb),os_path.basename(self.localdeb))
if not md5sums:
local="/var/lib/dpkg/info/%s.md5sums" % self.package
if os_path.exists(local):
f=open(local,"r")
md5sums=f.read()
f.close()
if md5sums:
if self.package_status in (INSTALLED, UPDATENEEDED, DOWNGRADE):
#check for md5 only if local deb-status is installed
mds5entries = md5sums.strip("\n").split("\n")
md5ok_list = []
md5fail_list = []
for md5entry in mds5entries:
pos = md5entry.find(" ")
if pos:
md5hash = md5entry[:pos]
file = md5entry[pos:].strip().strip("*")
if not file.startswith("/"):
file="/"+file
if os_path.exists(file):
md5fromFile = hashlib.md5(open(file,'rb').read()).hexdigest()
else:
md5fromFile = ""
if md5fromFile == md5hash:
md5ok_list.append(md5hash + " " + file)
else:
md5fail_list.append(md5hash + " " + file)
text=""
if md5fail_list:
text+=_("md5sum check failure")+":\n\n" + "\n".join(md5fail_list)+"\n"
if md5ok_list:
if len(text) > 0:
text+="\n"
text +=_("md5sum check ok") + ":\n\n" + "\n".join(md5ok_list) + "\n"
self["text"].setText(text)
else:
self["text"].setText(_("md5sums from DEB-package:") +"\n"+ md5sums)
else:
self["text"].setText(_("md5sums: not found"))
def finishedDownload(self, file):
cprint(">>> finishedDownload")
first_search_string = '<pre><em>'
pos0 = file.find(first_search_string)
#cprint(">>> file %s" % file)
if pos0 > 0:
cprint(">>> find pre em")
pos1 = file.find("</em></pre>",pos0)
text = file[pos0 + len(first_search_string):pos1]
text = re_sub("^<!--%\+b:..%-->","",text)
text = re_sub("<!--%-b:..%-->$","",text)
text = text.replace("<","<").replace(">",">")
else:
cprint(">>> second try")
first_search_string = '<!--%\+b:..%--><!--%glmr%--><pre class="chroma"><code>'
second_search_string = '</code></pre><!--%glmr%--><!--%-b:..%-->'
pos0=-1
match = re_search(first_search_string, file)
if match: pos0 = match.start()
if pos0>0:
cprint(">>> find by second try")
pos1=0
match = re_search(second_search_string, file)
if match: pos1 = match.start()
text = file[pos0 + len(first_search_string)-1:pos1]
text = re_sub(r'<.*?>', '', text) # remove html tags
text = text.replace("<","<").replace(">",">").strip()
else:
cprint(">>> not found in text")
text = "text not found"
#cprint("text: %s" % text)
self["text"].setText(text)
def failedDownload(self, error):
cprint(">>> failedDownload error: %s" % error)
dir = "/usr/share/doc/%s" % (self.package)
name = self.fileName.lower()
#cprint("dir: %s lower: %s" % (dir,name))
found=False
if os_path.exists(dir) and not (self.localdeb and self.package_status in (INSTALLABLE, UPDATENEEDED)):
for file in os_listdir(dir):
filel=file.lower()
if filel.startswith(name):
found=True
gotit=dir+"/"+file
if file.endswith(".gz"):
f=gzip.open(gotit,"rb")
else:
f=open(gotit,"r")
text=f.read()
f.close()
self["text"].setText(text)
elif self.localdeb: # load info from local deb file
cprint("read file from local deb: %s" % self.localdeb)
changelog,copyright,readme=parseDoc(os_path.dirname(self.localdeb),os_path.basename(self.localdeb))
file=self.fileName.lower()
found=True
if file.startswith("readme") and readme:
self["text"].setText(readme)
elif file.startswith("changelog") and changelog:
self["text"].setText(changelog)
elif file.startswith("copyright") and copyright:
self["text"].setText(copyright)
else:
self["text"].setText(file + ": " + _("No details found."))
elif self.package_status in (INSTALLED,) and self.downloadCount == 0:
#if installed, but not found in /usr/share/doc/...package... then load from gemfury
self.downloadCount=1
self["text"].setText(_("Downloading")+" %s ..." % self.fileName)
url = "https://gemfury.com/%s/deb:%s/-/content/usr/share/doc/%s/%s" % (plugin_feedName, self.package, self.package, self.fileName)
cprint("downloading: %s" % url)
self.fileDownloader = fileDownloader(url)
self.fileDownloader.getList(self.finishedDownload, self.failedDownload)
return
if not found:
self["text"].setText(_("Download failed")+": %s\n\n%s" % (self.fileName, error))
def startDownload(self, fileName):
self.fileName = fileName
self.downloadCount=0
cprint("package status: %s" % self.package_status)
if self.package_status in (INSTALLABLE, UPDATENEEDED) and not self.localdeb:
self["text"].setText(_("Downloading")+" %s ..." % fileName)
url = "https://gemfury.com/%s/deb:%s/-/content/usr/share/doc/%s/%s" % (plugin_feedName, self.package, self.package, self.fileName)
cprint("downloading: %s" % url)
self.fileDownloader = fileDownloader(url)
self.fileDownloader.getList(self.finishedDownload, self.failedDownload)
else:
self.failedDownload(_("An empty filename is illegal."))
def greenPressed(self):
self.aptresult=""
cprint(">>> greenPressed")
self.startDownload("changelog")
def yellowPressed(self):
self.aptresult=""
cprint(">>> yellowPressed")
self.startDownload("copyright")
def bluePressed(self):
self.aptresult=""
cprint(">>> bluePressed")
self.startDownload("README")
def cancel(self):
self.close(False)
def metaDreamy(enable_meta=True):
try:
packagesList = getPackagesList(getAll=True)
for packagename in packagesList:
autor="Sven H"
cprint("metaDream packagename %s, %s" % (autor, packagename))
global statusfile_data
statusfile_data = ""
gp4_filter = ""
gp4_filename = "/etc/enigma2/AddonFilterlist_%s.json" % autor
if not os_path.exists(packagename):
cprint("no Packages file (yet)")
if not enable_meta:
removeStrandedMetas(autor)
continue
cprint("meta file creation: %s" % enable_meta)
f = open(packagename,"r")
content = f.read()
f.close()
if len(content) == 0:
continue
content=content.replace("\n ",",, ").replace("\n ",",, ") #replace ENTER in description
packages=content.strip().split("\n\n")
#checkPreview_value = checkPreview()
for package in packages:
#create meta-files
package_list = package.strip("\n").split("\n")
try:
package = dict([(x.split(":")[0].strip(),x.split(":")[1].strip()) for x in package_list])
except:
cprint("BAD package file: %s" % packagename)
return
if enable_meta:
desc=package['Description'].replace(",,","") #remove replaced ENTER
sp=desc.split(" ")
if len(sp)>1:
name="%s %s" % (sp[0],sp[1])
else:
name=sp[0]
if name != desc:
shortdesc = desc.replace(name,"")
else:
shortdesc = name
longdesc = shortdesc
meta_txt = '<default>\n'
meta_txt += '\t<prerequisites>\n'
meta_txt += '\t\t<tag type="%s" />\n' % autor
meta_txt += '\t</prerequisites>\n'
meta_txt += '\t<info>\n'
meta_txt += '\t\t<author>%s</author>\n' % autor
meta_txt += '\t\t<name>%s</name>\n' % name
meta_txt += '\t\t<packagename>%s</packagename>\n' % package['Package']
if config.plugins.svenh.size.value:
size=int(package['Size'])//1024
shortdescription="%s - %dkB" % (shortdesc,size)
longdescription="%s - %dkB" % (longdesc,size)
else:
shortdescription=shortdesc
longdescription=longdesc
if config.plugins.svenh.version.value:
current=currentVersion(package['Package'])
new=package['Version'].strip()
if new==current or current==_("none"):
meta_txt += '\t\t<shortdescription>%s %s</shortdescription>\n' % (shortdescription, new)
meta_txt += '\t\t<description>%s %s</description>\n' % (longdescription, new)
else:
meta_txt += '\t\t<shortdescription>%s %s %s %s</shortdescription>\n' % (shortdescription, current, _("Update"), package['Version'])
meta_txt += '\t\t<description>%s %s %s %s</description>\n' % (longdescription, current, _("Update"), package['Version'])
else:
meta_txt += '\t\t<shortdescription>%s</shortdescription>\n' % shortdescription
meta_txt += '\t\t<description>%s</description>\n' % longdescription
meta_txt += '\t</info>\n'
meta_txt += '\t<files type="package"> <!-- without version, without .ipk -->\n'
meta_txt += '\t\t<file type="package" name="%s" />\n' % package['Package']
meta_txt += '\t</files>\n'
meta_txt += '</default>\n'
meta_filename = "/usr/share/meta/plugin_%s_%s.xml" % (autor, package['Package'].split("-")[-1].lower())
if enable_meta:
writeMeta(meta_filename, meta_txt)
else:
removeMeta(meta_filename)
#set all packages as filter-text for AddonFilter_Sven H.json
if gp4_filter:
gp4_filter += "," + package['Package']
else:
gp4_filter = package['Package']
if enable_meta:
# write gp4 json
gp4Write(gp4_filename,gp4_filter,autor)
pass
else:
gp4Remove(gp4_filename,autor)
removeStrandedMetas(autor)
except:
cprint("error on write meta")
def removeStrandedMetas(autor):
# check for stranded metas of plugins from feed
for file in os_listdir("/usr/share/meta"):
f=open("/usr/share/meta/%s" % file)
mm=f.read()
f.close()
if mm.find(autor) != -1:
cprint("remove stranded meta file %s" % file)
os_remove("/usr/share/meta/%s" % file)
def checkApt(kill=False):
pids = [pid for pid in os_listdir('/proc') if pid.isdigit()]
apt=False
for pid in pids:
try:
cmd=open(os_path.join('/proc', pid, 'cmdline'), 'rb').read().split('\0')
if cmd[0].find("apt") != -1:
apt=True
if kill:
os_kill(int(pid), signal.SIGKILL)
except IOError: # proc has already terminated
continue
return apt
def checkHost(url):
host=url[url.find("//")+2:]
sp=[]
sp=host.split(":")
host=sp[0]
sp=host.split("/")
host=sp[0]
if "@" in host:
host = host.split("@")[1]
resolv=None
try:
resolv=gethostbyname(host)
except:
cprint("HOST ERROR %s" % host)
if resolv==host:
resolv=None
return host, resolv
def currentVersion(package, feedDeb=True):
global statusfile_data
if len(statusfile_data) == 0:
cprint("reading %s" % plugin_status_file)
statusfile_data=open(plugin_status_file,"r").read().split("\n")
needle="Package: %s" % package
needle=needle.strip()
version=_("none")
try:
if needle in statusfile_data:
index = statusfile_data.index(needle)
status_line = statusfile_data[index+1]
if status_line.startswith(("Status: deinstall ok","Status: install ok not-installed")):
return version
for line in statusfile_data[index+1:]:
if line.startswith("Version:"):
sp=line.split(":")
if len(sp) > 1:
version=sp[1].strip()
cprint("got Version %s for %s" % (version,package))
if feedDeb and package==feedPlugin_PackageName:
for line in statusfile_data[index+1:]:
# cprint(">>>>>>>>>>>>> %s" % line)
if line.startswith("Date:"):
sp=line.split(":")
if len(sp) > 1:
date=sp[1].strip()
sp=date.split()
ymd="%s%s%02d" % (sp[3],abbr_to_num(sp[2]),int(sp[1]))
version=version+"-"+ymd
return version
return version
return version
except:
import traceback, sys
traceback.print_exc()
return version
def writeMeta(meta_filename, meta_text):
if os_path.exists(meta_filename):
f = open(meta_filename, "r")
old_text=f.read()
f.close()
if old_text == meta_text:
#cprint("meta file %s unchanged" % meta_filename)
return
# new meta file or content changed ...
open(meta_filename, "w")
f = open(meta_filename, "w")
f.write(meta_text)
f.close()
cprint("meta file %s written" % meta_filename)
def removeMeta(meta_filename):
if os_path.exists(meta_filename):
os_remove(meta_filename)
cprint("meta file %s removed" % meta_filename)
def gp4Write(gp4_filename,gp4_filter,autor):
cprint("gp4Write: %s, %s " % (gp4_filename, gp4_filter))
#create AddonFilter_Sven H.json file for the AddonManager if the user file exists
gp4_userfilename = "/etc/enigma2/AddonFilterlistuser.json"
if os_path.exists(gp4_userfilename):
gp4_name = autor + " - " + _("Plugins")
gp4_hide = 0
gp4_sort = 1
gp4_desc = "%s - %s" % (autor,_("Plugin selection"))
gp4_json_txt = '{\n\t"entrys": [\n\t{"name":"%s", "hide":%s, "sort":%s, "desc":"%s", "filter":"%s"}\n\t]\n}\n' % (gp4_name, gp4_hide, gp4_sort, gp4_desc, gp4_filter)
#cprint("gp4: %s" % gp4_json_txt)
if os_path.exists(gp4_filename):
f = open(gp4_filename, "r")
old_json=f.read()
f.close()
if old_json != gp4_json_txt:
cprint("re-writing file: %s" % gp4_filename)
f= open(gp4_filename, "w")
f.write(gp4_json_txt)
f.close()
else:
cprint("creating file: %s" % gp4_filename)
f= open(gp4_filename, "w")
f.write(gp4_json_txt)
f.close()
lines = open(gp4_userfilename).readlines()
for line in lines:
if line.find(autor + " ") != -1:
#read value for hide/sort
gp4_komma = ""
if line.strip("\n").endswith(","):
gp4_komma = ","
line_attribs = line.split(",")
for attr in line_attribs:
attr = attr.split(":")
if '"hide"' in attr[0]:
gp4_hide = int(attr[1])
if '"sort"' in attr[0]:
gp4_sort = int(attr[1])
gp4_json_line = '\t{"name":"%s", "hide":%s, "sort":%s, "desc":"%s", "filter":"%s"}%s\n' % (gp4_name, gp4_hide, gp4_sort, gp4_desc,gp4_filter, gp4_komma)
if line != gp4_json_line:
# remove from AddonFilterlistuser.json to reload
# the new AddonFilterlist_Sven H.json in GP4 AddonManager
cprint("refresh %s line in %s" % (autor, gp4_userfilename))
lines[lines.index(line)] = gp4_json_line
gp4_json_txt = "".join(lines).replace(",\n\t]","\n\t]") #replace ',' on last entry
f = open(gp4_userfilename, "w")
f.write(gp4_json_txt)
f.close()
break
def gp4Remove(gp4_filename,autor):
cprint("gp4remove: %s" % gp4_filename)
if os_path.exists(gp4_filename):
os_remove(gp4_filename)
gp4_userfilename = "/etc/enigma2/AddonFilterlistuser.json"
if os_path.exists(gp4_userfilename):
lines = open(gp4_userfilename).readlines()
for line in lines:
if line.find(autor + " ") != -1:
cprint("remove %s line in %s" % (autor, gp4_userfilename))
lines.remove(line)
gp4_json_txt = "".join(lines).replace(",\n\t]","\n\t]") #replace if ',' after last entry
f = open(gp4_userfilename, "w")
f.write(gp4_json_txt)
f.close()
break
class SvenH_DirectoryBrowser(Screen):
if sz_w == 1920:
skin = """
<screen name="SvenH_DirectoryBrowser" position="center,170" size="920,740">
<ePixmap pixmap="Default-FHD/skin_default/buttons/red.svg" position="10,5" size="300,70" />
<ePixmap pixmap="Default-FHD/skin_default/buttons/green.svg" position="310,5" size="300,70" />
<widget backgroundColor="#9f1313" font="Regular;30" halign="center" position="10,5" render="Label" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="300,70" source="key_red" transparent="1" valign="center" zPosition="1" />
<widget backgroundColor="#1f771f" font="Regular;30" halign="center" position="310,5" render="Label" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="300,70" source="key_green" transparent="1" valign="center" zPosition="1" />
<eLabel backgroundColor="grey" position="10,80" size="900,1" />
<widget enableWrapAround="1" name="filelist" position="10,90" scrollbarMode="showOnDemand" size="900,630" />
</screen>"""
elif sz_w == 2560:
skin = """
<screen name="SvenH_DirectoryBrowser" position="center,240" size="1220,860" >
<ePixmap pixmap="skin_default/buttons/red.png" position="20,10" size="400,80" />
<ePixmap pixmap="skin_default/buttons/green.png" position="420,10" size="400,80" />
<widget source="key_red" render="Label" position="20,10" size="400,80" zPosition="1" font="Regular;40" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" />
<widget source="key_green" render="Label" position="420,10" size="400,80" zPosition="1" font="Regular;40" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" />
<eLabel position="20,100" size="1180,2" backgroundColor="grey" />
<widget name="filelist" position="20,120" size="1180,720" enableWrapAround="1" scrollbarMode="showOnDemand" />
</screen>"""
else:
skin = """
<screen name="SvenH_DirectoryBrowser" position="center,120" size="610,430">
<ePixmap pixmap="skin_default/buttons/red.png" position="10,5" size="200,40"/>
<ePixmap pixmap="skin_default/buttons/green.png" position="210,5" size="200,40"/>
<widget source="key_red" render="Label" position="10,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2"/>
<widget source="key_green" render="Label" position="210,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2"/>
<eLabel position="10,50" size="590,1" backgroundColor="grey"/>
<widget name="filelist" position="10,60" size="590,360" enableWrapAround="1" scrollbarMode="showOnDemand"/>
</screen>"""
def __init__(self, session, text = "", filename = "", currDir = None, bookmarks = None, userMode = False, windowTitle = _("Select Location"), minFree = None, autoAdd = False, editDir = False, inhibitDirs = [], inhibitMounts = []):
Screen.__init__(self, session)
if currDir and not os_path.exists(currDir):
currDir = "/"
if not currDir.endswith("/"):
currDir += "/"
self.filelist = FileList(currDir, showDirectories = True, showFiles = False, inhibitMounts = inhibitMounts, inhibitDirs = inhibitDirs)
self["filelist"] = self.filelist
self["filelist"].onSelectionChanged.append(self.selectionChanged)
self["FilelistActions"] = ActionMap(["SetupActions"],
{
"save": self.select,
"ok": self.ok,
"cancel": self.exit
})
self["key_red"] = StaticText(_("Cancel"))
self["key_green"] = StaticText(_("OK"))
self.windowTitle = windowTitle
self.onShown.append(self.setWindowTitle)
def setWindowTitle(self):
self.setTitle(self.windowTitle)
def ok(self):
if self["filelist"].canDescent(): # isDir
self["filelist"].descent()
def select(self):
directory = self["filelist"].getSelection()[0]
if directory != "/":
directory = directory.rstrip("/")
self.close(directory)
def selectionChanged(self):
pass
def exit(self):
self.close(None)
class SvenH_Setup(Screen, ConfigListScreen, HelpableScreen):
if sz_w == 1920:
skin = """
<screen name="SvenH_Setup" position="center,170" size="1200,890">
<widget name="logo" position="20,10" size="150,60" />
<widget backgroundColor="#9f1313" font="Regular;26" halign="center" name="buttonred" position="180,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="180,60" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;26" halign="center" name="buttongreen" position="370,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="180,60" valign="center" />
<widget backgroundColor="#a08500" font="Regular;26" halign="center" name="buttonyellow" position="560,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="180,60" valign="center" />
<widget backgroundColor="#18188b" font="Regular;26" halign="center" name="buttonblue" position="750,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="180,60" valign="center" />
<widget name="gemfury" position="1002,12" size="177,56" alphatest="on" />
<widget name="info" position="935,10" size="60,30" alphatest="on" />
<widget name="menu" position="935,40" size="60,30" alphatest="on" />
<eLabel backgroundColor="grey" position="20,90" size="1160,1" />
<widget name="config" enableWrapAround="1" position="30,110" scrollbarMode="showOnDemand" size="1140,670" />
<eLabel backgroundColor="grey" position="20,790" size="1160,1" />
<widget name="text" backgroundColor="background" position="40,800" size="1120,80" font="Regular;28" zPosition="1" transparent="1"/>
</screen>"""
elif sz_w == 2560:
skin = """
<screen name="SvenH_Setup" position="center,200" size="1640,1160" >
<widget name="logo" position="20,10" size="200,80" />
<widget backgroundColor="#9f1313" font="Regular;32" halign="center" name="buttonred" position="230,10" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="240,80" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;32" halign="center" name="buttongreen" position="490,10" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="240,80" valign="center" />
<widget backgroundColor="#a08500" font="Regular;32" halign="center" name="buttonyellow" position="750,10" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="240,80" valign="center" />
<widget backgroundColor="#18188b" font="Regular;32" halign="center" name="buttonblue" position="1010,10" foregroundColor="white" shadowColor="black" shadowOffset="-4,-4" size="240,80" valign="center" />
<widget name="gemfury" position="1380,12" size="228,72" alphatest="on" />
<widget name="info" position="1270,10" size="80,40" alphatest="on" />
<widget name="menu" position="1270,50" size="80,40" alphatest="on" />
<eLabel backgroundColor="grey" position="20,100" size="1600,2" />
<widget name="config" position="30,120" size="1580,840" enableWrapAround="1" scrollbarMode="showOnDemand" />
<eLabel backgroundColor="grey" position="20,980" size="1600,2" />
<widget name="text" backgroundColor="background" position="40,1000" size="1560,140" font="Regular;44" zPosition="1" transparent="1" />
</screen>"""
else:
skin = """
<screen name="SvenH_Setup" position="center,100" size="820,580">
<widget name="logo" position="10,5" size="100,40" />
<widget backgroundColor="#9f1313" font="Regular;16" halign="center" name="buttonred" position="115,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="120,40" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;16" halign="center" name="buttongreen" position="245,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="120,40" valign="center" />
<widget backgroundColor="#a08500" font="Regular;16" halign="center" name="buttonyellow" position="375,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="120,40" valign="center" />
<widget backgroundColor="#18188b" font="Regular;16" halign="center" name="buttonblue" position="505,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="120,40" valign="center" />
<widget name="gemfury" position="690,6" size="114,36" alphatest="on" />
<widget name="info" position="635,5" size="40,20" alphatest="on" />
<widget name="menu" position="635,25" size="40,20" alphatest="on" />
<eLabel backgroundColor="grey" position="10,50" size="800,1" />
<widget name="config" position="15,60" size="790,420" enableWrapAround="1" scrollbarMode="showOnDemand" />
<eLabel backgroundColor="grey" position="10,490" size="800,1" />
<widget name="text" backgroundColor="background" position="20,500" size="780,70" font="Regular;22" zPosition="1" transparent="1"/>
</screen>"""
def __init__(self, session, args = 0):
Screen.__init__(self, session)
self.list = []
# explizit check on every entry
self.onChangedEntry = []
self.onConfigEntryChanged = []
ConfigListScreen.__init__(self, self.list, session = self.session, on_change = self.changedEntry)
self["config"].onSelectionChanged.append(self.selectionChanged)
self.createSetup()
self["buttonred"] = Label(_("Exit"))
self["buttongreen"] = Label(_("Save"))
self["buttonyellow"] = Label(_("Reset"))
self["buttonblue"] = Label(_("About"))
self["text"] = Label()
self["logo"] = Pixmap()
self["menu"] = Pixmap()
self["info"] = Pixmap()
self["gemfury"] = Pixmap()
self["setupActions"] = ActionMap(["ColorActions","SetupActions","EPGSelectActions","MenuActions"],
{
"red": self.redPressed,
"green": self.save,
"yellow": self.yellowPressed,
"blue": self.about,
"save": self.save,
"cancel": self.redPressed,
"ok": self.okPressed,
"info": self.about,
"menu": self.redPressed,
}, -2)
self.onLayoutFinish.append(self.onLayoutFinished)
def onLayoutFinished(self):
self.setTitle(getTitle() + " v%s" % plugin_version + " - " + _("Setup") )
self["logo"].instance.setPixmapFromFile("%s/plugin.png" % plugindir)
self["gemfury"].instance.setPixmapFromFile("%s/gemfury.png" % plugindir)
self["menu"].instance.setPixmapFromFile(getPiconPath("menu"))
self["info"].instance.setPixmapFromFile(getPiconPath("info"))
def selectionChanged(self):
cur = self["config"].getCurrent()
if cur:
self["text"].text = cur[2]
def about(self):
self.session.open(MessageBox, _("Feed Plugin v%s by Sven H (2022)") % plugin_version, MessageBox.TYPE_INFO, timeout=plugin_timeout)
def save(self):
config.plugins.svenh.package_install.value=config.plugins.svenh.package_install.default
config.plugins.svenh.package_uninstall.value=config.plugins.svenh.package_uninstall.default
config.plugins.svenh.package_update.value=config.plugins.svenh.package_update.default
config.plugins.svenh.package_downgrade.value=config.plugins.svenh.package_downgrade.default
for x in self["config"].list:
if len(x) > 1:
x[1].save()
configfile.save
self.close(True)
def cancel(self,answer):
if answer:
for x in self["config"].list:
if len(x) > 1:
x[1].cancel()
cprint("direct close")
self.close(False)
def yellowPressed(self):
self.session.openWithCallback(self.callbackReset,MessageBox,_("Reset to defaults?"))
def callbackReset(self, ret):
if ret:
for x in self["config"].list:
if len(x) > 1:
x[1].value = x[1].default
self.createSetup()
def redPressed(self):
changed=self["config"].isChanged()
if changed and config.plugins.svenh.confirm.value!="false":
if config.plugins.svenh.confirm.value=="true":
text=_("Really close without saving settings?")
self.session.openWithCallback(self.cancel,MessageBox,text,MessageBox.TYPE_YESNO)
else: # only info message ...
text=_("Close without saving settings!")
self.session.openWithCallback(self.cancel,MessageBox,text,MessageBox.TYPE_WARNING)
elif changed:
self.cancel(True)
else:
self.close(False)
def changedEntry(self):
cprint(">>>> changedEntry")
cur = self["config"].getCurrent()[1]
self.createSetup()
def createSetup(self, first=False):
self.list = []
self.list.append(getConfigListEntry(_("activate feed"), config.plugins.svenh.feed,_("Activate or deactivate the feed-function of this plugin.\nIf deactivated no plugins from feeds will be listed.")))
self.list.append(getConfigListEntry(_("Install local plugins"), config.plugins.svenh.local,_("Activate or deactivate the package-listing from selectable local folder.\nYou can use predefined folders or a userdefined folder.")))
if config.plugins.svenh.local.value == "user":
self.list.append(getConfigListEntry("..." + _("User defined folder for local install"), config.plugins.svenh.local_user_path,_("You can select a local folder with 'OK'.")))
if config.plugins.svenh.feed.value or config.plugins.svenh.local.value != "none":
ask_text=_("yes: The plugin will ask you before starting package-actions.\nMessage: The plugin only shows a message on package-actions.")
self.list.append(getConfigListEntry(_("Ask user"), config.plugins.svenh.confirm,ask_text))
self.list.append(getConfigListEntry(_("show package version"), config.plugins.svenh.version,_("Show the current version number of the package in the package list.")))
self.list.append(getConfigListEntry(_("show package size"), config.plugins.svenh.size,_("Show the size of the package in the package list.")))
extra_text=_("Select the extra info is shown in the package list (default=description).")
self.list.append(getConfigListEntry(_("show extra info"), config.plugins.svenh.show_info,extra_text))
self.list.append(getConfigListEntry(_("show section with updates"), config.plugins.svenh.show_update_section,_("Show an additional section on the top of the package list for updatable packackes.")))
self.list.append(getConfigListEntry(_("sort the package list"), config.plugins.svenh.listview,_("Select the sorting mode of the package list.")))
self["config"].list = self.list
self["config"].l.setList(self.list)
def okPressed(self):
if self["config"].getCurrent()[1] == config.plugins.svenh.local_user_path:
self.openDirectoryBrowser(config.plugins.svenh.local_user_path.value)
return
def openDirectoryBrowser(self, path):
try:
self.session.openWithCallback(
self.openDirectoryBrowserCB,
SvenH_DirectoryBrowser,
windowTitle = _("Choose Directory:"),
currDir = str(path),
bookmarks = None,
autoAdd = False,
editDir = True,
inhibitDirs = ["/.cache", "/.local", "/autofs","/bin", "/boot", "/dev", "/etc", "/home", "/lib", "/proc", "/run", "/sbin", "/sys", "/usr", "/var", "/mnt", "/media/net", "/net"],
minFree = None )
except Exception, e:
cprint("openDirectoryBrowser get failed: %s" % str(e))
def openDirectoryBrowserCB(self, path):
if not path is None:
if path != config.plugins.svenh.local_user_path.value:
config.plugins.svenh.local_user_path.value = path