Repository URL to install this package:
|
Version:
5.0-r2 ▾
|
enigma2-plugin-systemplugins-gutemine
/
usr
/
lib
/
enigma2
/
python
/
Plugins
/
SystemPlugins
/
gutemine
/
gutemine.py
|
|---|
from __future__ import generators
from __future__ import division
from __future__ import absolute_import
from __future__ import with_statement
from __future__ import print_function
from twisted.internet._sslverify import ClientTLSOptions
from twisted.internet.ssl import ClientContextFactory
import gzip
import signal
from datetime import datetime
from distutils.version import LooseVersion as Version
import zlib
import tarfile
#
# gutemine3 Software Feed Update Plugin
#
from Components.ActionMap import ActionMap, HelpableActionMap
from Components.Label import Label
from Components.config import (
config,
configfile,
ConfigSubsection,
ConfigText,
ConfigBoolean,
ConfigInteger,
ConfigSelectionNumber,
ConfigNothing,
ConfigSelection,
getConfigListEntry,
ConfigSlider,
ConfigSubList,
ConfigDirectory,
)
from Components.ConfigList import ConfigListScreen
from Components.Pixmap import Pixmap
from Components.Ipkg import IpkgComponent
from Components.ScrollLabel import ScrollLabel
from Tools.LoadPixmap import LoadPixmap
from Screens.Standby import TryQuitMainloop
from Plugins.Plugin import PluginDescriptor
import Plugins.Plugin
from Screens.Screen import Screen
from Screens.MessageBox import MessageBox
from Screens.ChoiceBox import ChoiceBox
from Screens.HelpMenu import HelpableScreen
from Screens import Standby
from Screens.InfoBar import InfoBar
from Components.Lcd import leaveStandby
from Components.FileList import FileList
from Components.Sources.StaticText import StaticText
from Components.PluginComponent import PluginComponent, plugins
from enigma import (
quitMainloop,
getDesktop,
eActionMap,
eTimer,
eFileWatch,
eFileEvent,
eConsoleAppContainer,
ePoint,
eServiceReference,
eDVBVolumecontrol,
fbClass,
)
from twisted.web import client
from os import (
path as os_path,
stat as os_stat,
rename as os_rename,
remove as os_remove,
listdir as os_listdir,
rmdir as os_rmdir,
mkdir as os_mkdir,
kill as os_kill,
symlink as os_symlink,
system as os_system,
)
from re import sub as re_sub, search as re_search
import sys
from socket import gethostbyname
from twisted.web import resource, http
from Plugins.Extensions.WebInterface.WebChilds.Toplevel import (
addExternalChild,
externalChildren,
)
import Plugins.SystemPlugins.gutemine.unix_ar as unix_ar
import gm
gutemine_version = gm.version()
gutemine_status = "/var/lib/dpkg/status"
gutemine_readme = "/usr/lib/enigma2/python/Plugins/SystemPlugins/gutemineReadme/README"
gutemine_plugindir = "/usr/lib/enigma2/python/Plugins/SystemPlugins/gutemine"
gutemine_log = "/tmp/gutemine.log"
gutemine_feedlist = "/etc/apt/sources.list.d/gutemine.list"
gutemine_feedconf = "/etc/apt/apt.conf.d/gutemine-feed-configs-deb.conf"
gutemine_desc = "gutemine" + " " + _("Software update")
if os_path.exists("/usr/lib/enigma2/python/Plugins/SystemPlugins/HdmiCec"):
from Plugins.SystemPlugins.HdmiCec.plugin import Cec, cec
else:
if os_path.exists("/usr/lib/enigma2/python/Plugins/SystemPlugins/CEC"):
from Plugins.SystemPlugins.CEC.Cec import cec
#
# 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]
gutemine_timeout = 5
# gutemine_dummy=9
INSTALLABLE = 0
INSTALLED = 1
UPDATENEEDED = 2
UNINSTALL = 3
DOWNGRADE = 4
def setConfigSelection(configName, choices, default):
if not hasattr(config.plugins.gutemine, configName):
# print("=== set new configSelection")
setattr(
config.plugins.gutemine,
configName,
ConfigSelection(default=default, choices=choices),
)
else:
configEntry = config.plugins.gutemine.__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, "gutemine"):
config.plugins.gutemine = ConfigSubsection()
if not hasattr(config.plugins.gutemine, "feed"):
config.plugins.gutemine.feed = ConfigBoolean(
default=True, descriptions=yes_no_descriptions
)
if not hasattr(config.plugins.gutemine, "hide"):
config.plugins.gutemine.hide = ConfigBoolean(
default=False, descriptions=yes_no_descriptions
)
if not hasattr(config.plugins.gutemine, "version"):
config.plugins.gutemine.version = ConfigBoolean(
default=True, descriptions=yes_no_descriptions
)
if not hasattr(config.plugins.gutemine, "size"):
config.plugins.gutemine.size = ConfigBoolean(
default=False, descriptions=yes_no_descriptions
)
if not hasattr(config.plugins.gutemine, "local_user_path"):
config.plugins.gutemine.local_user_path = ConfigDirectory(default="/")
if not hasattr(config.plugins.gutemine, "backupdate"):
config.plugins.gutemine.backupdate = ConfigBoolean(
default=True, descriptions=yes_no_descriptions
)
if not hasattr(config.plugins.gutemine, "backuptime"):
config.plugins.gutemine.backuptime = ConfigBoolean(
default=False, descriptions=yes_no_descriptions
)
if not hasattr(config.plugins.gutemine, "favourites"):
config.plugins.gutemine.favourites = ConfigText(
"enigma2-plugin-systemplugins-gutemine", fixed_size=False
)
if not hasattr(config.plugins.gutemine, "show_update_section"):
config.plugins.gutemine.show_update_section = ConfigBoolean(
default=True, descriptions=yes_no_descriptions
)
view_options = []
view_options.append(("false", _("no")))
view_options.append(("true", _("Sort. A-Z")))
view_options.append(("sort", _("Sort. A-Z").replace(_("A-Z"), _("Install"))))
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")
leave_options = []
leave_options.append(("none", _("None")))
leave_options.append(("restart", _("Restart GUI")))
leave_options.append(("reboot", _("Reboot") + " " + _("Dreambox")))
setConfigSelection(configName="leave_action", choices=leave_options, default="none")
timeout_options = []
timeout_options.append(("0", _("yes")))
timeout_options.append(("10", "10 " + _("seconds")))
timeout_options.append(("30", "30 " + _("seconds")))
setConfigSelection(configName="timeout", default="0", choices=timeout_options)
# dummy configs ...
if not hasattr(config.plugins.gutemine, "package_install"):
gutemine_options_install = []
gutemine_options_install.append(
("install1", _("Installation") + " " + _("available"))
)
gutemine_options_install.append(
("install2", _("Installation") + " " + _("available"))
)
config.plugins.gutemine.package_install = ConfigSelection(
default="install1", choices=gutemine_options_install
)
if not hasattr(config.plugins.gutemine, "package_uninstall"):
gutemine_options_uninstall = []
gutemine_options_uninstall.append(
("uninstall1", _("Installation finished.").replace(".", ""))
)
gutemine_options_uninstall.append(
("uninstall2", _("Installation finished.").replace(".", ""))
)
config.plugins.gutemine.package_uninstall = ConfigSelection(
default="uninstall1", choices=gutemine_options_uninstall
)
if not hasattr(config.plugins.gutemine, "package_update"):
gutemine_options_update = []
gutemine_options_update.append(("update1", _("Update") + " " + _("available")))
gutemine_options_update.append(("update2", _("Update") + " " + _("available")))
config.plugins.gutemine.package_update = ConfigSelection(
default="update1", choices=gutemine_options_update
)
if not hasattr(config.plugins.gutemine, "package_downgrade"):
gutemine_options_downgrade = []
gutemine_options_downgrade.append(("downgrade1", _("Downgrade")))
gutemine_options_downgrade.append(("downgrade2", _("Downgrade")))
config.plugins.gutemine.package_downgrade = ConfigSelection(
default="downgrade1", choices=gutemine_options_downgrade
)
if not hasattr(config.plugins.gutemine, "package_empty"):
gutemine_options_empty = []
gutemine_options_empty.append(("empty1", _(" ")))
gutemine_options_empty.append(("empty2", _(" ")))
config.plugins.gutemine.package_empty = ConfigSelection(
default="empty1", choices=gutemine_options_empty
)
return
CYANC = "\033[36m"
ENDC = "\033[m"
def cprint(text):
print(CYANC + "[gutemine] " + text + ENDC)
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 ...
statusfile_data = ""
def getPluginDir():
gutemine_plugindir = "/usr/lib/enigma2/python/Plugins/SystemPlugins/gutemine"
return gutemine_plugindir
def getTitle():
gutemine_feed = "gutemine3"
return gutemine_feed
def getFeed():
gutemine_deb = "gm3"
return gutemine_deb
def getFeedUrl():
gutemine_deb = getFeed()
gutemine_feedurl = "deb [trusted=yes] https://repo.fury.io/%s/ ./\n" % (
gutemine_deb
)
cprint("getFeedUrl: %s" % gutemine_feedurl)
return gutemine_feedurl
def getFeedConfig():
feed_config = 'Acquire::https::repo.fury.io::Verify-Peer "false";\nAcquire::https::repo.fury.io::Verify-Host "false";\n'
return feed_config
def getPackages():
gutemine_deb = getFeed()
gutemine_packages = "/var/lib/apt/lists/repo.fury.io_%s_._Packages" % (gutemine_deb)
# cprint("gutemine_packages: %s" % gutemine_packages)
return gutemine_packages
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
import sys
traceback.print_exc()
return ""
sz_w = getDesktop(0).size().width()
gheader = " " * 6
gtrailer = ""
def addFeed(update=True):
cprint("ADDING FEED")
gutemine_feedurl = getFeedUrl()
gutemine_feedconfig = getFeedConfig()
gutemine_packages = getPackages()
if not os_path.exists(gutemine_feedlist):
f = open(gutemine_feedlist, "w")
f.write(gutemine_feedurl)
f.close()
else:
f = open(gutemine_feedlist, "r")
feed = f.read()
f.close()
if feed != gutemine_feedurl:
f = open(gutemine_feedlist, "w")
f.write(gutemine_feedurl)
f.close()
if not os_path.exists(gutemine_feedconf):
f = open(gutemine_feedconf, "w")
f.write(gutemine_feedconfig)
f.close()
if os_path.exists(gutemine_packages):
metaDreamy(True)
if update:
aptUpdate()
def removeFeed():
cprint("REMOVING FEED")
# gutemine_packages=getPackages()
if os_path.exists(gutemine_feedlist):
os_remove(gutemine_feedlist)
if os_path.exists(gutemine_feedconf):
os_remove(gutemine_feedconf)
metaDreamy(False)
packagesList = getPackagesList()
for package in packagesList:
if os_path.exists(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:"):
print(line)
sp = line.split(":")
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").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()
data_tar.close()
c = open("/tmp/data.tar.xz", "w")
c.write(data)
c.close()
gm.xz("/tmp/data.tar.xz")
data_tar = open("/tmp/data.tar")
elif debian.find("data.tar.xz") != -1:
cprint("data.tar.xz")
data_tar = ar_file.open("data.tar.xz")
data = data_tar.read()
data_tar.close()
c = open("/tmp/data.tar.xz", "w")
c.write(data)
c.close()
gm.xz("/tmp/data.tar.xz")
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 = "_" + gm.arch() + ".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()
control_tar.close()
c = open("/tmp/control.tar.xz", "w")
c.write(control)
c.close()
gm.xz("/tmp/control.tar.xz")
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()
control_tar.close()
c = open("/tmp/control.tar.xz", "w")
c.write(control)
c.close()
gm.xz("/tmp/control.tar.xz")
control_tar = open("/tmp/control.tar")
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)
gutemine_skin = config.skin.primary_skin.value.replace("/skin.xml", "")
class gutemineInformation(Screen):
if sz_w == 2560:
skin = """
<screen position="160,1000" size="480,80" title="gutemine Information Menu" flags="wfNoBorder" backgroundColor="#ffffffff" zPosition="9">
<widget name="lights" position="0,0" size="480,80"/>
</screen>"""
elif sz_w == 1920:
skin = """
<screen position="120,800" size="480,80" title="gutemine Information Menu" flags="wfNoBorder" backgroundColor="#ffffffff" zPosition="9">
<widget name="lights" position="0,0" size="480,80"/>
</screen>"""
else:
skin = """
<screen position="80,500" size="480,80" title="gutemine Information Menu" flags="wfNoBorder" backgroundColor="#ffffffff" zPosition="9">
<widget name="lights" position="0,0" size="480,80"/>
</screen>"""
def __init__(self, session):
self.skin = gutemineInformation.skin
self.setup_title = _("gutemine3") + " " + _("Information")
Screen.__init__(self, session)
self["lights"] = Pixmap()
# explizit check on every entry
self.onChangedEntry = []
self.onConfigEntryChanged = []
self.session = session
self["actions"] = ActionMap(
["SetupActions"],
{"cancel": self.goBack, "back": self.goBack, "ok": self.goBack},
-1,
)
self.onLayoutFinish.append(self.byLayoutEnd)
def goBack(self):
self.close()
def byLayoutEnd(self):
gm.fury()
self["lights"].instance.setPixmapFromFile("/tmp/lights.svg")
# let's have our own Console with logging ...
class Console(Screen):
# TODO move this to skin.xml
if sz_w == 2560:
skin = """
<screen position="200,200" size="1100,800" title="Command execution..." >
<widget name="text" position="0,0" size="1100,800" font="Console;28" />
</screen>"""
elif sz_w == 1920:
skin = """
<screen position="150,150" size="800,600" title="Command execution..." >
<widget name="text" position="0,0" size="800,600" font="Console;20" />
</screen>"""
else:
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,
):
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.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)
# dont start before gui is finished
self.onLayoutFinish.append(self.startRun)
def updateTitle(self):
self.setTitle(self.newtitle)
def startRun(self):
self["text"].setText(_("Execution Progress:") + "\n\n")
if not self.logfile == 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 = ""
# start of container application failed...
if self.container.execute(self.cmdlist[self.run]):
self.runFinished(-1) # so we must call runFinished manual
def runFinished(self, retval):
self.run += 1
if self.run != len(self.cmdlist):
# start of container application failed...
if self.container.execute(self.cmdlist[self.run]):
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 == None:
self.finishedCallback()
if not retval and self.closeOnSuccess:
self.cancel()
def cancel(self):
if self.run == len(self.cmdlist):
if not self.logfile == 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 == 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 == None:
self.output.write(str)
class gutemineMain(Screen, ConfigListScreen, HelpableScreen):
if sz_w == 2560:
skin = """
<screen name="gutemineMain" position="center,200" size="1640,1160" title="gutemine" >
<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="-3,-3" size="240,80" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;32" halign="center" name="buttongreen" position="490,10" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" size="240,80" valign="center" />
<widget backgroundColor="#a08500" font="Regular;32" halign="center" name="buttonyellow" position="750,10" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" size="240,80" valign="center" />
<widget backgroundColor="#18188b" font="Regular;32" halign="center" name="buttonblue" position="1010,10" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" 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="gutemine" position="1000,1002" size="230,148" zPosition="1" />
<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>"""
elif sz_w == 1920:
skin = """
<screen name="gutemineMain" position="center,170" size="1200,890" title="gutemine" >
<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="gutemine" position="630,731" size="230,159" zPosition="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>"""
else:
skin = """
<screen name="gutemineMain" position="center,100" size="820,580" title="gutemine" >
<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="gutemine" position="500,501" size="115,79" zPosition="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)
gutemine_feedurl = getFeedUrl()
sp = gutemine_feedurl.split()
url = sp[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(_("Extensions"))
self["buttonyellow"] = Label(_("Update"))
self["buttonblue"] = Label(_("About"))
self["text"] = Label()
# self["text"].hide()
self["gutemine"] = Pixmap()
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, _("Option Selector")),
"yellow": (self.okPressed, _("Package action")),
"blue": (self.bluePressed, _("About")),
},
-2,
)
text0 = (
_("gutemine") + " " + _("Plugin") + " " + _("enabled") + "/" + _("disabled")
)
text2 = _("New version:").replace(":", "") + " " + _("Software update")
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")),
"0": (self.hideFeedPlugin, text0),
},
-2,
)
self["channelSelectActions"] = HelpableActionMap(
self,
"ChannelSelectEPGActions",
{
"showEPGList": (self.infoPressed, _("Information") + "/" + _("About")),
},
-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, _("Help")),
},
-3,
)
# watch for filechanges
self.filewatchStart()
self.filewatchDebStart()
if config.plugins.gutemine.feed.value:
addFeed(False) # if feed changed ...
# print("========= init updateFeed")
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] = gm.md5(packagefile)
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(gutemine_status):
self.md5_status = gm.md5(gutemine_status)
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 == gutemine_status:
if os_path.exists(gutemine_status):
md5_status = gm.md5(gutemine_status)
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 = gm.md5(filename)
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.gutemine.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 = gm.arch() + ".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.gutemine.local.value == "user":
deb_directory = "%s" % config.plugins.gutemine.local_user_path.value
else:
deb_directory = "/%s" % config.plugins.gutemine.local.value
return deb_directory
def infoPressed(self):
self.open_about_info("info")
def bluePressed(self):
self.open_about_info("about")
def showLastLog(self):
if os_path.exists(gutemine_log):
cmd = "cat %s" % gutemine_log
self.session.open(Console, gutemine_log, [cmd])
else:
self.session.open(
MessageBox, _("none") + " " + gutemine_log, MessageBox.TYPE_ERROR
)
def change_PluginDescriptorEntry(self, pd=None):
if pd == None:
return
show_MenuEntry = not config.plugins.gutemine.hide.value
# print("=== menu", pd.name, pd.where, show_MenuEntry)
pdList = [(p) for p in plugins.getPlugins(where=pd.where[:]) if p is pd]
if show_MenuEntry:
if pd not in pdList:
if pd.icon == None:
# update icon if PluginDescriptor was not set on e2-start
pd.updateIcon(gutemine_plugindir)
plugins.addPlugin(pd)
else:
for pd in pdList:
plugins.removePlugin(pd)
def hideFeedPlugin(self):
if config.plugins.gutemine.hide.value:
config.plugins.gutemine.hide.value = False
text = _("gutemine") + " " + _("Plugin") + " " + _("enabled")
else:
config.plugins.gutemine.hide.value = True
if os_path.exists(
"/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager"
):
text = (
_("gutemine")
+ " "
+ _("Plugin")
+ " "
+ _("disabled")
+ "\n\n"
+ _("gutemine")
+ " "
+ _("Software management")
+ " "
+ _("available")
)
else:
text = (
_("gutemine")
+ " "
+ _("Plugin")
+ " "
+ _("disabled")
+ "\n\n"
+ _("gutemine")
+ " "
+ _("Setup")
+ " "
+ _("Menu")
+ " "
+ _("available")
)
try:
from .plugin import PluginMenuDescriptor
from .plugin import ExtensionsMenuDescriptor
except:
self.session.open(
MessageBox,
"The new function to live disable/enable menu entries is only avaible after the next GUI-Restart",
MessageBox.TYPE_WARNING,
)
return
config.plugins.gutemine.hide.save()
self.session.open(MessageBox, text, MessageBox.TYPE_WARNING)
# add/remove Entries from PluginBrowser and ExtensionsMenu without GUI-restart
self.change_PluginDescriptorEntry(PluginMenuDescriptor)
self.change_PluginDescriptorEntry(ExtensionsMenuDescriptor)
def changeFeedCallback(self, answer):
cprint(">>>>>>> changeFeedCallback, %s %s" % (answer, self.new_feed))
if answer:
removeFeed()
self.md5_package = {}
addFeed(update=False)
self.aptUpdate()
self.session.open(
MessageBox,
_("Trying to download a new packetlist. Please wait..."),
MessageBox.TYPE_INFO,
timeout=gutemine_timeout,
)
def greenPressed(self):
cur = self["config"].getCurrentIndex()
list = []
list.append(
(_("Package list update") + " " + _("Update") + " (update)", "feed_update")
)
list.append(
(
_("Package list update") + " " + _("Complete") + " (upgrade)",
"feed_upgrade",
)
)
list.append(
(_("Package list update") + " " + _("Reset") + " (repair)", "feed_repair")
)
list.append(
(_("Package list update") + " " + _("Abort") + " (abort)", "feed_abort")
)
if len(self.updates) > 0:
list.append(
(
_("Update") + ": " + _("all") + " " + _("available"),
"update_available",
)
)
list.append(
(_("Save") + " " + _("Favourites") + ": " + _("Plugins"), "save_fav")
)
list.append(
(_("Install") + " " + _("Favourites") + ": " + _("Plugins"), "load_fav")
)
if os_path.exists("/etc/resolv.conf"):
f = open("/etc/resolv.conf", "r")
self.apt_host = f.read()
f.close()
if self.apt_host.find("8.8.8.8") == -1:
list.append(
(
_("Add") + " Google " + _("Name") + " " + _("Server IP"),
"add_dns",
)
)
else:
list.append(
(
_("Remove") + " Google " + _("Name") + " " + _("Server IP"),
"remove_dns",
)
)
if cur and config.plugins.gutemine.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(
(
self["config"].getCurrent()[0]
+ " "
+ _("delete file")
+ " "
+ self.getLocalPath(),
"delete_deb",
)
)
list.append((_("Show Log") + ": " + gutemine_log, "showLastLog"))
userscripts_path = "/usr/script"
if os_path.exists(userscripts_path):
for script in os_listdir(userscripts_path):
if script.endswith(".sh") and not script.startswith("."):
list.append(
(
_("Select")
+ ": "
+ script.replace(".sh", "").replace(userscripts_path, ""),
"%s/%s" % (userscripts_path, script),
)
)
data_userscripts_path = "/data/script"
if os_path.exists(data_userscripts_path):
for script in os_listdir(data_userscripts_path):
if script.endswith(".sh") and not script.startswith("."):
list.append(
(
script.replace(".sh", "").replace(data_userscripts_path, ""),
"%s/%s" % (data_userscripts_path, script),
)
)
self.session.openWithCallback(
self.menuCallback,
ChoiceBox,
title=_("Following tasks will be done after you press OK!").replace(
"!", ":"
),
windowTitle=getTitle(),
list=list,
)
def getScriptOptions(self):
userscripts_options = []
userscripts_options.append(("none", _("none")))
userscripts_options.append(("start", _("start")))
userscripts_options.append(("stop", _("stop")))
userscripts_options.append(("restart", _("restart")))
userscripts_options.append(("info", _("info")))
userscripts_options.append(("enable", _("enable autostart")))
userscripts_options.append(("disable", _("disable autostart")))
return userscripts_options
def executeScript(self, answer):
if answer == None:
self.skipInstall()
elif answer:
title = self.scriptname + " " + self.option
cmd = "%s %s" % (self.scriptname, self.option)
cprint("command %s" % cmd)
self.session.open(Console, _(title), [cmd], None, False, gutemine_log)
else:
self.skipInstall()
def openSetup(self):
self.session.openWithCallback(self.setupCallback, gutemineSetup)
def menuCallback(self, ret):
ret = ret and ret[1]
if ret:
if ret == "setup":
self.openSetup()
elif ret == "feed_update":
self.session.open(
MessageBox,
_("Trying to download a new packetlist. Please wait..."),
MessageBox.TYPE_INFO,
timeout=gutemine_timeout,
)
self.aptUpdate()
elif ret == "feed_upgrade":
self.session.open(
MessageBox,
_("Trying to download a new packetlist. Please wait...").replace(
"...", ""
)
+ " & "
+ _("Software update"),
MessageBox.TYPE_INFO,
timeout=gutemine_timeout,
)
self.aptUpgrade()
elif ret == "feed_repair":
self.feedRepair(False)
elif ret == "feed_abort": # force apt kill command
self.feedRepair(True)
elif ret == "add_dns":
f = open("/etc/resolv.conf", "w")
f.write("nameserver 8.8.8.8\n")
f.write("nameserver 8.8.4.4\n")
f.write("nameserver 2001:4860:4860::8888\n")
f.write("nameserver 2001:4860:4860::8844\n")
f.close()
if os_path.exists("/sys/class/net/eth0/address"):
f = open("/sys/class/net/eth0/address", "r")
ea = f.read()
f.close()
cprint(ea)
cmf = "/var/lib/connman/ethernet_%s_cable/settings" % ea.replace(
":", ""
).rstrip("\n")
cprint(cmf)
if os_path.exists(cmf):
cm = ""
f = open(cmf, "r")
line = f.readline()
while line:
if line.startswith("Nameservers="):
line = "Nameservers=8.8.8.8;8.8.4.4;2001:4860:4860::8888;2001:4860:4860::8844;\n"
cm += line
line = f.readline()
f.close()
if cm.find("8.8.8.8") == -1:
line = "Nameservers=8.8.8.8;8.8.4.4;2001:4860:4860::8888;2001:4860:4860::8844;\n"
cm += line
cprint(cm)
f = open(cmf, "w")
f.write(cm)
f.close()
text = (
_("Add")
+ " Google "
+ _("Name")
+ " "
+ _("Server IP")
+ " "
+ _("done")
)
self.session.open(
MessageBox, text, MessageBox.TYPE_INFO, timeout=gutemine_timeout
)
elif ret == "remove_dns":
f = open("/etc/resolv.conf", "w")
f.write("# Generated by Connection Manager\n")
f.write("nameserver 127.0.0.1\n")
f.write("nameserver ::1\n")
f.close()
if os_path.exists("/sys/class/net/eth0/address"):
f = open("/sys/class/net/eth0/address", "r")
ea = f.read()
f.close()
cprint(ea)
cmf = "/var/lib/connman/ethernet_%s_cable/settings" % ea.replace(
":", ""
).rstrip("\n")
cprint(cmf)
if os_path.exists(cmf):
cm = ""
f = open(cmf, "r")
line = f.readline()
while line:
if not line.startswith("Nameservers="):
cm += line
line = f.readline()
f.close()
cprint(cm)
f = open(cmf, "w")
f.write(cm)
f.close()
text = (
_("Remove")
+ " Google "
+ _("Name")
+ " "
+ _("Server IP")
+ " "
+ _("done")
)
self.session.open(
MessageBox, text, MessageBox.TYPE_INFO, timeout=gutemine_timeout
)
elif ret == "save_fav":
self.session.open(
MessageBox,
_("Save") + " " + _("Favourites") + " " + _("done"),
MessageBox.TYPE_INFO,
timeout=gutemine_timeout,
)
self.saveFavourites()
elif ret == "load_fav":
feed_updates = []
local_updates = []
cmd = ""
package_status = INSTALLABLE
all_install_list = config.plugins.gutemine.favourites.value.split(" ")
# print("=== all_install_list", all_install_list)
feed_package_list = [
package[2]
for package in self.argument
if len(package) > 3
and package[3] == package_status
and not package[6]
and package[2] in all_install_list
]
local_package_list = [
package[6]
for package in self.argument
if len(package) > 3
and package[3] == package_status
and package[6]
and package[2] in all_install_list
and package[2] not in feed_package_list
]
# print("=== feedpackagelist", feed_package_list)
# print("=== localpackagelist", local_package_list)
all_feed_install = " ".join(feed_package_list)
all_local_install = " ".join(local_package_list)
self.deb = all_feed_install + all_local_install
if all_feed_install:
cmd = (
"apt-get -o=Dpkg::Use-Pty=0 install %s -f -y --assume-yes --install-recommends; apt-get install -o=Dpkg::Use-Pty=0 -f -y --assume-yes"
% (all_feed_install)
)
if all_local_install:
if cmd:
cmd += "; "
cmd += (
"dpkg --force-all -i %s; apt-get -o=Dpkg::Use-Pty=0 install -f -y --assume-yes --install-recommends"
% (all_local_install)
)
# print("=== install fav cmd", cmd)
title = _("Install") + " " + _("Favourites")
if cmd:
self.session.openWithCallback(
self.finishedConsole,
Console,
_(title),
[cmd],
None,
False,
gutemine_log,
)
else:
self.session.open(
MessageBox,
_("None")
+ " "
+ _("Package list update")
+ " ("
+ _("empty")
+ ")",
MessageBox.TYPE_INFO,
title=title,
timeout=gutemine_timeout,
)
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 = _("Software update") + ": %s" % _("available")
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,
gutemine_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()
else: # user scripts
self.scriptname = ret
cprint(self.scriptname)
if self.scriptname.startswith("/usr/script/installer-"):
self.executeConfirm(("none", _("none")))
else:
self.session.openWithCallback(
self.executeConfirm,
ChoiceBox,
_("Please select an option below.").replace(".", ""),
self.getScriptOptions(),
)
def setupCallback(self, ret):
cprint(">>>> setupCallback %s" % ret)
if ret:
# self["buttongreen"].setText(_(" "))
self["buttonyellow"].setText(_(" "))
# self["buttonblue"].setText(_(" "))
if config.plugins.gutemine.feed.value:
addFeed(update=False)
self.aptUpdate()
else:
removeFeed()
self.updates = self.createSetup()
self.updateWindowTitle()
if config.plugins.gutemine.local.value != "none":
self.filewatchDebStart()
else:
self.filewatchDebStop()
def executeConfirm(self, scriptoption):
if scriptoption == None:
text = _("No, do nothing.").replace(".", "!")
self.session.open(MessageBox, text, MessageBox.TYPE_ERROR)
else:
if scriptoption[0] == "none":
self.option = ""
else:
self.option = scriptoption[1]
if config.plugins.gutemine.confirm.value == "true":
text = (
_("Execution Progress:") + " " + self.scriptname + " " + self.option
)
self.session.openWithCallback(
self.executeScript, MessageBox, text, MessageBox.TYPE_YESNO
)
else:
self.executeScript(True)
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=gutemine_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, forced=True):
cprint(">>> feedRepair")
if checkApt() or forced:
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=gutemine_timeout,
)
else:
self.session.open(
MessageBox,
_(
"There was an error downloading the packetlist. Please try again."
),
MessageBox.TYPE_WARNING,
timeout=gutemine_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"
text = _("Timer overlap in timers.xml detected!\nPlease recheck it!")
sp = text.split("\n")
title = sp[1].replace("!", "...")
self.session.open(Console, _(title), [cmd], None, False, gutemine_log)
def selectionChanged(self):
cprint(">>>> selectionChanged")
curidx = self["config"].getCurrentIndex()
cur = self["config"].getCurrent()
if len(cur) < 2 or cur[1] == config.plugins.gutemine.package_empty:
# - dont set because on start ipkgupdate set to "...."
self["buttonblue"].setText(_(" "))
self["buttonyellow"].setText(_(" "))
else:
task = self.argument[curidx][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() == _(" "):
# - dont set because on start ipkgupdate set to "...."
self["buttonblue"].setText(_("About"))
if not self["text"].getText().startswith(_("State")):
name = self.argument[curidx][0] # plugin name
if config.plugins.gutemine.show_info.value == "desc":
description = " ".join(self.argument[curidx][1]).replace(
" ", " "
) # merge description lines
if description != name:
description = description.replace(
name, ""
) # description without name
# show description in the info-line
self["text"].setText(_("Description") + ": " + description)
else:
# show packagename
self["text"].setText(_("Name") + ": " + self.argument[curidx][2])
def createSetup(self, first=False):
global statusfile_data
statusfile_data = ""
gutemine_packages = getPackages()
updates = []
self.list = []
self.argument = []
self.list_update_all = []
self.argument_update_all = []
r = 0
if self.resolv == 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.gutemine.package_empty)
)
if len(err) > 1:
self.list.append(
getConfigListEntry(err[1], config.plugins.gutemine.package_empty)
)
self["config"].list = self.list
self["config"].l.setList(self.list)
return []
if config.plugins.gutemine.feed.value:
feedList = []
feedList.append("gm3")
for feedname in feedList:
gutemine_packages = getPackages()
content = ""
if os_path.exists(gutemine_packages):
f = open(gutemine_packages, "r")
content = f.read()
f.close()
# cprint(">>>> package: %s" % gutemine_packages)
# cprint(">>>> createSetup len content: %d" % len(content))
if (
len(content) > 0
and config.plugins.gutemine.listview.value != "false"
):
self.argument.append((str(r)))
r += 1
self.list.append(
(
"%s %s (c) %s %s"
% (gheader, _("Plugins"), "gutemine3", gtrailer),
)
)
content = content.replace("\n ", ", ").replace("\n ", ", ")
upackages = content.strip().split("\n\n")
packages = sortPackages(upackages)
x = 0
boxarch = gm.arch()
# 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 = []
gutemine_argument = None
for package in packages:
desc = package["Description"].split(",")
name = package["PackageName"]
parch = package["Architecture"]
showAT = True
if name == "Alan Turing" and "Flash" != gm.booted():
showAT = False
showBA = True
if name == "Barry Allen" and "Flash" != gm.booted():
showBA = False
showAP = True
if name == "Auto Pin" and os_path.exists("/usr/lib/enigma2/python/Plugins/Extensions/Pineas"):
showAP = False
if (parch == "all" or parch == boxarch) and showAT and showBA and showAP:
kit = name
new = package["Version"].strip()
sp=[]
sp=new.split(":")
new = sp[-1].strip()
current = currentVersion(package["Package"])
deb = package["Package"]
depends = None
try:
depends = package["Depends"].split(",")
except:
pass
if not depends == None:
for dep in depends:
if (
dep.find(
"enigma2-plugin-systemplugins-gutemine"
)
!= -1
):
depends.remove(dep)
if len(depends) < 1:
depends = None
if config.plugins.gutemine.version.value:
kit += " v%s" % new
if config.plugins.gutemine.size.value:
size = int(package["Size"]) // 1024
kit += " - %dkB" % (size)
debkit = None
cprint("compare for %s Version current: %s new: %s" % (kit, 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 "gutemine Feed" in name:
gutemine_argument = (
name,
desc,
deb,
status,
new,
depends,
debkit,
feedname,
)
if config.plugins.gutemine.listview.value != "sort":
if current == _("none"):
self.list.append(
getConfigListEntry(
kit, config.plugins.gutemine.package_install
)
)
elif Version(current) == Version(new):
self.list.append(
getConfigListEntry(
kit,
config.plugins.gutemine.package_uninstall,
)
)
elif Version(current) > Version(new):
self.list.append(
getConfigListEntry(
kit,
config.plugins.gutemine.package_downgrade,
)
)
else:
self.list.append(
getConfigListEntry(
kit, config.plugins.gutemine.package_update
)
)
updates.append(deb)
self.list_update.append(
getConfigListEntry(
kit, config.plugins.gutemine.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.gutemine.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.gutemine.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.gutemine.package_downgrade,
)
)
self.argument_new.append(
(
name,
desc,
deb,
status,
new,
depends,
debkit,
feedname,
)
)
else:
self.list_update.append(
getConfigListEntry(
kit, config.plugins.gutemine.package_update
)
)
self.argument_update.append(
(
name,
desc,
deb,
status,
new,
depends,
debkit,
feedname,
)
)
updates.append(deb)
if config.plugins.gutemine.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 gutemine_argument == None:
# set gutemine to first
idx = self.argument.index(gutemine_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.gutemine.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 = gm.arch() + ".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)
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 == None:
for dep in depends:
if dep.find("enigma2-plugin-systemplugins-gutemine") != -1:
depends.remove(dep)
if len(depends) < 1:
depends = None
if config.plugins.gutemine.version.value:
kit += " v%s" % new
if config.plugins.gutemine.size.value:
stat = os_stat("%s/%s" % (directory, file))
kit += " - %dkB" % (int(stat.st_size // 1024))
debkit = "%s/%s" % (directory, file)
if config.plugins.gutemine.listview.value != "sort":
if current == _("none"):
self.list.append(
getConfigListEntry(
kit, config.plugins.gutemine.package_install
)
)
elif Version(current) == Version(new):
self.list.append(
getConfigListEntry(
kit, config.plugins.gutemine.package_uninstall
)
)
elif Version(current) > Version(new):
self.list.append(
getConfigListEntry(
kit, config.plugins.gutemine.package_downgrade
)
)
else:
self.list.append(
getConfigListEntry(
kit, config.plugins.gutemine.package_update
)
)
updates.append(deb)
self.list_update.append(
getConfigListEntry(
kit, config.plugins.gutemine.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.gutemine.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.gutemine.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.gutemine.package_downgrade
)
)
self.argument_down.append(
(
name,
desc,
deb,
status,
new,
depends,
debkit,
feedname,
)
)
else:
self.list_update.append(
getConfigListEntry(
kit, config.plugins.gutemine.package_update
)
)
self.argument_update.append(
(
name,
desc,
deb,
status,
new,
depends,
debkit,
feedname,
)
)
updates.append(deb)
if config.plugins.gutemine.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.gutemine.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.gutemine.package_empty
)
)
self.argument.append(("no package", "no desc"))
if len(self.list) == 0: # if feed is disabled
self.list.append(
getConfigListEntry(
" %s - %s"
% (
_("Inactive"),
_("Press the Menu button for additional options."),
),
config.plugins.gutemine.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()
if gm.fury():
self["logo"].instance.setPixmapFromFile("%s/fury.png" % gutemine_plugindir)
else:
self["logo"].instance.setPixmapFromFile(
"%s/gutemine.png" % gutemine_plugindir
)
self["gemfury"].instance.setPixmapFromFile("%s/dark.png" % gutemine_plugindir)
self["menu"].instance.setPixmapFromFile(gm.getpicon("menu"))
self["info"].instance.setPixmapFromFile(gm.getpicon("info"))
def updateWindowTitle(self):
if len(self.updates) > 0:
self.setTitle(
getTitle()
+ " "
+ gutemine_version
+ " @ "
+ gm.boxtype()
+ " (%d %s)" % (len(self.updates), _("Update"))
)
else:
self.setTitle(getTitle() + " " + gutemine_version + " @ " + gm.boxtype())
def saveFavourites(self):
installed = []
for package in self.argument:
if len(package) > 3 and package[3] > 0 and package[2] not in installed:
installed.append(package[2])
installed_packages = " ".join(installed)
cprint(installed_packages)
config.plugins.gutemine.favourites.value = installed_packages
config.plugins.gutemine.favourites.save()
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.gutemine.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(gutemine_feedlist)
and config.plugins.gutemine.feed.value
):
addFeed()
def open_about_info(self, screenName="about"):
cur = self["config"].getCurrentIndex()
if (
not cur
or self["config"].getCurrent()[1] == config.plugins.gutemine.package_empty
):
return
if config.plugins.gutemine.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]
deb = self.argument[cur][2].split("-") # end of kit name
if not self.argument[cur][5] == None:
depends = "\n".join(self.argument[cur][5]).replace(" ", "")
else:
depends = None
status = " "
preview = "%s/out.png" % gutemine_plugindir
cprint(
"ABOUT: %s %s %s %s %s %s %s %s %s"
% (
title,
header,
footer,
status,
preview,
depends,
package,
package_status,
localdeb,
)
)
if screenName == "about":
self.session.open(
gutemineAbout,
title,
header,
footer,
status,
preview,
depends,
package,
package_status,
localdeb,
feedname,
)
elif screenName == "info":
title = _("Info") + " " + header
self.session.open(
gutemineInfo,
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)
print("=========== update about ... =============")
self["text"].setText(
_("State") + ": " + _("Update") + " " + _("In Progress") + " ......"
)
def aptUpdate(self):
cprint("apt-get update")
print("========== aptUpdate set Text")
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")
print("========== ipkgCallback set text =====")
self["text"].setText("")
self.selectionChanged() # change info-text after aptUpdate
checkAll()
def updateFeed(self, quiet=False):
if config.plugins.gutemine.feed.value:
if not quiet:
self.session.open(
MessageBox,
_("Trying to download a new packetlist. Please wait..."),
MessageBox.TYPE_INFO,
timeout=gutemine_timeout,
)
print("======== 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.gutemine.package_empty
):
return
if len(self.argument[cur]) < 3:
return
if checkApt():
self.session.open(
MessageBox,
_("Upgrading Dreambox... Please wait"),
MessageBox.TYPE_ERROR,
timeout=gutemine_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.").replace(".", "")
+ ": %s ?" % self.name
)
if config.plugins.gutemine.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:\n").rstrip("\n")
+ " %s" % self.name
)
if config.plugins.gutemine.confirm.value == "true":
self.session.openWithCallback(
self.debInstall, MessageBox, text, MessageBox.TYPE_YESNO
)
else:
self.debInstall(True)
elif self.task == DOWNGRADE:
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.gutemine.confirm.value == "true":
self.session.openWithCallback(
self.debInstall, MessageBox, text, MessageBox.TYPE_YESNO
)
else:
self.debInstall(True)
else:
if "gutemine Feed" in self.name:
if config.plugins.gutemine.confirm.value != "false":
text = _("Uninstall") + " %s " % self.name + _("disabled")
self.session.open(MessageBox, text, MessageBox.TYPE_ERROR)
else:
text = (
_("This plugin will be removed.").replace(".", "")
+ ": %s" % self.name
)
if config.plugins.gutemine.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 == None:
self.skipInstall()
elif not answer:
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.deb.startswith("enigma2-plugin-installer-"):
script = (
self.deb.replace("enigma2-plugin-", "; /usr/script/") + ".sh"
)
cprint(script)
if self.task == INSTALLABLE:
title = (
_("This plugin will be installed.").replace(".", "")
+ ": %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 = _("Software update") + ": %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 = _("Software 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.").replace(".", "")
+ ": %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.deb.startswith("enigma2-plugin-installer-"):
script = (
self.deb.replace("enigma2-plugin-", "; /usr/script/") + ".sh"
)
cprint(script)
if self.task == INSTALLABLE:
title = (
_("This plugin will be installed.").replace(".", "")
+ ": %s" % self.name
)
cmd = (
"apt-get -o=Dpkg::Use-Pty=0 install %s -f -y --assume-yes --install-recommends; apt-get install -o=Dpkg::Use-Pty=0 -f -y --assume-yes%s"
% (self.deb, script)
)
elif self.task == UPDATENEEDED:
title = _("Software update") + ": %s" % self.name
cmd = (
"apt-get -o=Dpkg::Use-Pty=0 --reinstall --only-upgrade install %s -f -y --assume-yes --install-recommends; apt-get -o=Dpkg::Use-Pty=0 install -f -y --assume-yes%s"
% (self.deb, script)
)
elif self.task == DOWNGRADE:
title = _("Software downgrade") + ": %s" % self.name
cmd = (
"apt-get -o=Dpkg::Use-Pty=0 --only-upgrade install %s=%s -f -y --allow-downgrades --install-recommends; 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.").replace(".", "")
+ ": %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,
gutemine_log,
)
def finishedConsole(self):
self.updates = self.createSetup()
self.updateWindowTitle()
cprint("restart needed ... later")
# print("==== installed deb '%s'" % self.deb)
if self.deb != "enigma2-plugin-systemplugins-gutemine":
self.restartNeeded = True
def restartHandling(self, option=True):
self.option = option
if config.plugins.gutemine.leave_action.value == "none":
self.close(True)
return
if config.plugins.gutemine.confirm.value == "info":
text = _("Restart GUI") + "!"
self.session.openWithCallback(
self.doExit, MessageBox, text, MessageBox.TYPE_INFO
)
elif config.plugins.gutemine.confirm.value == "true":
if config.plugins.gutemine.leave_action.value == "restart":
text = _("Restart GUI") + "?"
elif config.plugins.gutemine.leave_action.value == "reboot":
text = _("Reboot") + " " + _("Dreambox") + "?"
else: # future use
text = _("unknown")
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 == None:
return
if answer:
if config.plugins.gutemine.leave_action.value == "restart":
quitMainloop(3)
elif config.plugins.gutemine.leave_action.value == "reboot":
self.session.open(TryQuitMainloop, 2)
else: # future use
pass
else:
self.close(self.option)
def doExit(self, answer):
if answer == None:
return
if answer:
self.close(self.option)
# fix SSL error with getPage
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 != 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
gutemineFactory = (
downloaderClientContextFactory(self.urlbase)
if "https" in self.urlbase
else None
)
client.getPage(self.urlbase, contextFactory=gutemineFactory).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 gutemineCheckPackages(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] = gm.md5(packagefile)
self.gutemine = eFileWatch("/var/lib/apt/lists", False, eFileEvent.MOVE)
self.gutemine_conn = self.gutemine.fileChanged.connect(self.gutemineEvent)
self.gutemine.startWatching()
def gutemineEvent(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 = gm.md5(filename)
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.gutemine.feed.value)
class gutemineAbout(Screen, HelpableScreen):
if sz_w == 2560:
skin = """
<screen name="gutemineAbout" position="center,200" size="1640,1160" title="About gutemine" >
<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="-3,-3" size="240,80" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;32" halign="center" name="buttongreen" position="490,10" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" size="240,80" valign="center" />
<widget backgroundColor="#a08500" font="Regular;32" halign="center" name="buttonyellow" position="750,10" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" size="240,80" valign="center" />
<widget backgroundColor="#18188b" font="Regular;32" halign="center" name="buttonblue" position="1010,10" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" size="240,80" valign="center" />
<widget name="gemfury" position="1380,12" size="228,72" alphatest="on" />
<widget name="infokey" position="1270,10" size="80,40" alphatest="on" />
<widget name="menukey" position="1270,25" size="80,40" alphatest="on" />
<widget name="status" position="1250,110" size="360,80" halign="center" valign="center" foregroundColor="yellow" font="Regular;32"/>
<eLabel backgroundColor="grey" position="20,100" size="1600,2" />
<widget name="preview" position="440,140" size="768,768" />
<eLabel backgroundColor="grey" position="20,940" size="1600,2" />
<widget name="lights" position="20,960" size="360,60" alphatest="on" zPosition="1"/>
<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"/>
</screen>"""
elif sz_w == 1920:
skin = """
<screen name="gutemineAbout" position="center,170" size="1200,890" title="About gutemine" >
<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="infokey" position="935,10" size="60,30" alphatest="on" />
<widget name="menukey" position="935,40" size="60,30" alphatest="on" />
<widget name="status" position="925,100" size="250,70" halign="center" valign="center" foregroundColor="yellow" font="Regular;24"/>
<eLabel backgroundColor="grey" position="20,90" size="1160,1" />
<widget name="preview" position="315,130" size="576,576" />
<eLabel backgroundColor="grey" position="20,740" size="1160,1" />
<widget name="lights" position="20,755" size="240,40" alphatest="on" zPosition="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"/>
</screen>"""
else:
skin = """
<screen name="gutemineAbout" position="center,100" size="820,580" title="About gutemine" >
<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="infokey" position="635,5" size="40,20" alphatest="on" />
<widget name="menukey" position="635,25" size="40,20" alphatest="on" />
<widget name="status" position="625,55" size="180,40" halign="center" valign="center" foregroundColor="yellow" font="Regular;16"/>
<eLabel backgroundColor="grey" position="10,50" size="800,1" />
<widget name="preview" position="220,70" size="384,384" />
<eLabel backgroundColor="grey" position="10,470" size="800,1" />
<widget name="lights" position="10,480" size="180,30" alphatest="on" zPosition="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"/>
</screen>"""
def __init__(
self,
session,
title,
header,
footer,
status,
preview,
depends,
package,
package_status,
localdeb,
feedname,
):
Screen.__init__(self, session)
self.title = title
self.header = header
self.footer = footer
self.status = status
self.preview = preview
self.depends = depends
self.package = package
self.package_status = package_status
self.localdeb = localdeb
self.feedname = feedname
self["buttonred"] = Label(_("Exit"))
self["buttongreen"] = Label(_(" "))
self["buttonyellow"] = Label(_("Download"))
self["buttonblue"] = Label(_("Help"))
self["logo"] = Pixmap()
self["lights"] = Pixmap()
self["about"] = Label(self.header)
self["info"] = Label(self.footer)
self["status"] = Label(self.status)
self["preview"] = Pixmap()
self["gemfury"] = Pixmap()
self["menukey"] = Pixmap()
self["infokey"] = Pixmap()
self.onShown.append(self.setWindowTitle)
HelpableScreen.__init__(self)
self["colorActionsAbout"] = HelpableActionMap(
self,
"ColorActions",
{
"red": (self.cancel, _("Exit")),
"green": (self.greenPressed, _(" ")),
"yellow": (self.yellowPressed, _("Download")),
"blue": (self.bluePressed, _("Help")),
},
-2,
)
self["setupActionsAbout"] = HelpableActionMap(
self,
"SetupActions",
{
"save": (self.cancel, _("Exit")),
"cancel": (self.cancel, _("Exit")),
},
-2,
)
self["channelSelectActionsAbout"] = HelpableActionMap(
self,
"ChannelSelectEPGActions",
{
"showEPGList": (self.infoPressed, _("Information") + "/" + _("About")),
},
-2,
)
text_menu = _("Thumbnails") + " " + _("Show in plugin browser")
self["menuActionsAbout"] = HelpableActionMap(
self,
"MenuActions",
{
"menu": (self.menuPressed, text_menu),
},
-2,
)
# for new RC use Audio key as Help key alternative
self["InfobarAudioSelectionActionsAbout"] = HelpableActionMap(
self,
"InfobarAudioSelectionActions",
{
"audioSelection": (self.audioPressed, _("Help")),
},
-3,
)
def setWindowTitle(self):
self.setTitle(self.title)
self["preview"].instance.setPixmapFromFile(self.preview)
self["menukey"].instance.setPixmapFromFile(gm.getpicon("menu"))
self["infokey"].instance.setPixmapFromFile(gm.getpicon("info"))
self["gemfury"].instance.setPixmapFromFile("%s/dark.png" % gutemine_plugindir)
if gm.fury():
self["logo"].instance.setPixmapFromFile("%s/fury.png" % gutemine_plugindir)
else:
self["logo"].instance.setPixmapFromFile(
"%s/gutemine.png" % gutemine_plugindir
)
self["lights"].instance.setPixmapFromFile("/tmp/lights.svg")
def audioPressed(self):
audio2Help()
def infoPressed(self):
cprint(">>> infoPressed")
title = _("Info") + " " + self.header
self.session.open(
gutemineInfo,
title,
self.header,
self.footer,
self.package,
self.package_status,
self.localdeb,
self.feedname,
)
def menuPressed(self):
cprint(">>> menuPressed")
local = "/var/lib/dpkg/info/%s.md5sums" % self.package
sp = self.package.split("-")
png = sp[-1] + ".png\n"
cprint("%s %s" % (local, png))
plugin_png = None
if os_path.exists(local):
f = open(local, "r")
line = f.readline()
while line:
if line.endswith(png):
cprint(line)
sp = line.split()
print(sp)
if len(sp) > 1:
path = sp[1]
if not path.startswith("/"):
path = "/" + path
plugin_png = path.strip("*")
line = f.readline()
f.close()
if not plugin_png == None:
self["preview"].instance.setPixmapFromFile(plugin_png)
def bluePressed(self):
cprint(">>> bluePressed")
supporturl = _("A required tool (%s) was not found.") % "gutemine"
self["info"].setText(supporturl)
def yellowPressed(self):
cprint(">>> yellowPressed %s" % self.package)
downloadurl = "https://repo.fury.io/gm3/"
self["info"].setText(_("Download") + ": " + downloadurl)
def cancel(self):
self.close(False)
def greenPressed(self):
cprint(">>> greenPressed")
self["info"].setText(self.footer)
class gutemineInfo(Screen, HelpableScreen):
if sz_w == 2560:
skin = """
<screen name="gutemineInfo" position="center,200" size="1640,1160" title="About gutemine" >
<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="-3,-3" size="240,80" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;32" halign="center" name="buttongreen" position="490,10" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" size="240,80" valign="center" />
<widget backgroundColor="#a08500" font="Regular;32" halign="center" name="buttonyellow" position="750,10" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" size="240,80" valign="center" />
<widget backgroundColor="#18188b" font="Regular;32" halign="center" name="buttonblue" position="1010,10" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" 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,10600" size="1600,60" halign="center" valign="center" foregroundColor="yellow" font="Regular;40"/>
<widget name="text" position="30,130" size="1590,800" font="Regular;80"/>
</screen>"""
elif sz_w == 1920:
skin = """
<screen name="gutemineInfo" position="center,170" size="1200,890" title="About gutemine" >
<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>"""
else:
skin = """
<screen name="gutemineInfo" position="center,100" size="820,580" title="About gutemine" >
<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,
_("Information") + " " + _("Checksum"),
),
},
-2,
)
text_menu = _("Action:") + " " + _("gutemine") + " " + _("Plugin")
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, _("Help")),
},
-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/gutemine.png" % gutemine_plugindir)
self["menukey"].instance.setPixmapFromFile(gm.getpicon("menu"))
self["infokey"].instance.setPixmapFromFile(gm.getpicon("info"))
self["gemfury"].instance.setPixmapFromFile("%s/dark.png" % gutemine_plugindir)
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 == 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:") == -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 = gm.md5(file)
else:
md5fromFile = ""
if md5fromFile == md5hash:
md5ok_list.append(md5hash + " " + file)
else:
md5fail_list.append(md5hash + " " + file)
text = ""
if md5fail_list:
text += (
_("md5sum")
+ " "
+ _("Check")
+ " "
+ _("Failure").upper()
+ ":\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(">",">")
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
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."))
if not found:
self["text"].setText(
_("Download")
+ " "
+ _("Failed").lower()
+ ": %s\n\n%s" % (self.fileName, error)
)
def startDownload(self, fileName):
self.fileName = fileName
cprint("package status: %s" % self.package_status)
if self.package_status in (INSTALLABLE, UPDATENEEDED) and not self.localdeb:
self["text"].setText(_("Downloading") + " %s ..." % fileName)
feedName = getFeed()
url = "https://gemfury.com/%s/deb:%s/-/content/usr/share/doc/%s/%s" % (
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):
packagesList = getPackagesList(getAll=True)
# gutemine_packages=getPackages()
for packagename in packagesList:
autor = "gutemine"
print("======== packagename===", 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 - Thanks Dreamy")
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")
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
# split description ...
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.gutemine.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.gutemine.version.value:
current = currentVersion(package["Package"])
new = package["Version"].strip()
if new.find(":") != -1:
sp=new.split(":")
new=sp[1]
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.xml"
% 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_gutemine.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)
def removeStrandedMetas(autor):
# check for stranded metas of gutemine plugins
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("stranded meta file %s removed" % 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 checkAll():
cprint("checkAll")
gutemine_packages = getPackages()
# cprint("packages: %s" % gutemine_packages)
if not os_path.exists(gutemine_packages):
return
packagefile = open(gutemine_packages, "r").read().split("\n")
statusfile = open(gutemine_status, "r").read()
cmd = "apt-mark unhold "
for line in packagefile:
if line.startswith("Package:"):
sp = line.split(":")
if len(sp) > 1:
package = sp[1].strip()
if statusfile.find(package) != -1:
cmd = cmd + " " + package
gutemine_container = eConsoleAppContainer()
gutemine_container.execute(cmd)
return cmd
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" % gutemine_status)
statusfile_data = open(gutemine_status, "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"):
return version
for line in statusfile_data[index + 1 :]:
if line.startswith("Version:"):
sp = line.split(":")
if len(sp) == 2:
version = sp[1].strip()
if len(sp) == 3:
version = sp[2].strip()
cprint("got Version %s for %s" % (version, package))
return version
return version
except:
import traceback
import 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_gutemine.json file for the AddonManager if the user file exists
gp4_userfilename = "/etc/enigma2/AddonFilterlistuser.json"
if os_path.exists(gp4_userfilename):
gp4_name = "%s %s" % (autor, _("Plugins"))
gp4_hide = 0
gp4_sort = 1
gp4_desc = "%s %s %s" % (autor, _("Plugins"), _("select"))
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 gutemine from AddonFilterlistuser.json to reload
# the new AddonFilterlist_gutemine.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 ',' on last entry
f = open(gp4_userfilename, "w")
f.write(gp4_json_txt)
f.close()
break
class gutemineDirectoryBrowser(Screen):
if sz_w == 2560:
skin = """
<screen name="gutemineDirectoryBrowser" 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="-3,-3"/>
<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="-3,-3"/>
<eLabel position="20,100" size="1180,2" backgroundColor="grey"/>
<widget name="filelist" position="20,120" size="1180,720" enableWrapAround="1" scrollbarMode="showOnDemand"/>
</screen>"""
elif sz_w == 1920:
skin = """
<screen name="gutemineDirectoryBrowser" 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>"""
else:
skin = """
<screen name="gutemineDirectoryBrowser" 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 gutemineWebInterface(resource.Resource):
def render_GET(self, req):
command = req.args.get("gutemine", None)
req.setResponseCode(http.OK)
req.setHeader("Content-type", "text/html")
req.setHeader("charset", "UTF-8")
picon_line = 0
updates = 0
list = []
boxarch = gm.arch()
# sorting by status (updates first) or by AZ
list_update = []
list_new = []
list_none = []
list_down = []
gutemine_deb = getFeed()
if command == None:
content = ""
gutemine_packages = getPackages()
if os_path.exists(gutemine_packages):
f = open(gutemine_packages, "r")
content = f.read()
f.close()
# cprint(">>>> gutemine Webinterface len content: %d" % len(content))
if len(content) > 0:
content = content.replace("\n ", ", ").replace("\n ", ", ")
upackages = content.strip().split("\n\n")
packages = sortPackages(upackages)
x = 0
for package in packages:
desc = package["Description"].split(",")
name = package["PackageName"]
parch = package["Architecture"]
filename = package["Filename"]
if parch == "all" or parch == boxarch:
kit = name
if config.plugins.gutemine.size.value:
size = int(package["Size"]) // 1024
kit += " - %dkB" % (size)
new = package["Version"].strip()
sp=[]
sp=new.split(":")
new=sp[-1]
if config.plugins.gutemine.version.value:
kit += " %s" % new
current = currentVersion(package["Package"])
sp = filename.split("/")
debkit = sp[2]
# hidden download url
download = (
"https://manage.fury.io/2/indexes/deb/%s/download/%s"
% (
gutemine_deb,
debkit.replace("_", "-").replace(".deb", ""),
)
)
if config.plugins.gutemine.listview.value != "sort":
# cprint("debkit: %s current: %s new: %s" % (debkit, current,new))
if current == _("none"):
list.append(
(
kit,
debkit,
download,
_("Installation") + " " + _("available"),
)
)
elif Version(current) == Version(new):
list.append(
(
kit,
debkit,
download,
_("Installation finished.").replace(".", ""),
)
)
elif Version(current) > Version(new):
list.append((kit, debkit, download, _("Downgrade")))
else:
list.append(
(
kit,
debkit,
download,
_("Update") + " " + _("available"),
)
)
updates += 1
else:
if current == _("none"):
list_none.append(
(
kit,
debkit,
download,
_("Installation") + " " + _("available"),
)
)
elif Version(current) == Version(new):
list_new.append(
(
kit,
debkit,
download,
_("Installation finished.").replace(".", ""),
)
)
elif Version(current) > Version(new):
list_down.append(
(kit, debkit, download, _("Downgrade"))
)
else:
list_update.append(
(
kit,
debkit,
download,
_("Update") + " " + _("available"),
)
)
updates += 1
if config.plugins.gutemine.listview.value == "sort":
list.extend(list_update)
list.extend(list_new)
list.extend(list_none)
list.extend(list_down)
if updates > 0:
webtitle = (
getTitle()
+ " "
+ gutemine_version
+ " (%d %s)" % (updates, _("Update"))
)
else:
webtitle = getTitle() + " " + gutemine_version
if not os_path.exists(
"/usr/lib/enigma2/python/Plugins/Extensions/WebInterface/web-data/img/gemfury.ico"
):
os_symlink(
"%s/gemfury.ico" % gutemine_plugindir,
"/usr/lib/enigma2/python/Plugins/Extensions/WebInterface/web-data/img/gemfury.ico",
)
ghtml = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"'
ghtml += '"http://www.w3.org/TR/html4/loose.dtd">'
ghtml += "<head><title>%s</title>" % webtitle
ghtml += '<link rel="shortcut icon" type="/web-data/image/x-icon" href="/web-data/img/gemfury.ico">'
ghtml += (
'<meta content="text/html; charset=UTF-8" http-equiv="content-type">'
)
ghtml += '</head><body bgcolor="white">'
ghtml += '<font face="Tahoma, Arial, Helvetica" color="black">'
ghtml += '<font size="3" color="black">'
if len(list) > 0:
for kit in list:
ghtml += '<hr>%s <a href="%s">%s</a> %s<br>' % (
kit[0],
kit[2],
kit[1],
kit[3],
)
else:
ghtml += "%s: %s" % (getTitle(), _("Disabled"))
return ghtml
gutemine_added = False
for child in externalChildren:
if child[0] == "gutemine":
gutemine_added = True
if not gutemine_added:
addExternalChild(("gutemine", gutemineWebInterface(), getTitle(), "1", True))
class gutemineSetup(Screen, ConfigListScreen, HelpableScreen):
if sz_w == 2560:
skin = """
<screen name="gutemineSetup" position="center,200" size="1640,1160" title="gutemine" >
<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="-3,-3" size="240,80" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;32" halign="center" name="buttongreen" position="490,10" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" size="240,80" valign="center" />
<widget backgroundColor="#a08500" font="Regular;32" halign="center" name="buttonyellow" position="750,10" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" size="240,80" valign="center" />
<widget backgroundColor="#18188b" font="Regular;32" halign="center" name="buttonblue" position="1010,10" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" 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="gutemine" position="1000,1002" size="230,158" zPosition="1" />
<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>"""
elif sz_w == 1920:
skin = """
<screen name="gutemineSetup" position="center,170" size="1200,890" title="gutemine" >
<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="gutemine" position="630,731" size="230,159" zPosition="1" />
<widget enableWrapAround="1" name="config" 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>"""
else:
skin = """
<screen name="gutemineSetup" position="center,100" size="820,580" title="gutemine" >
<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="gutemine" position="500,501" size="115,79" zPosition="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.savedConfig()
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["gutemine"] = Pixmap()
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() + " - " + _("Setup"))
self["logo"].instance.setPixmapFromFile("%s/gutemine.png" % gutemine_plugindir)
self["gemfury"].instance.setPixmapFromFile("%s/dark.png" % gutemine_plugindir)
self["menu"].instance.setPixmapFromFile(gm.getpicon("menu"))
self["info"].instance.setPixmapFromFile(gm.getpicon("info"))
def selectionChanged(self):
cur = self["config"].getCurrent()
if cur:
self["text"].text = cur[2]
def about(self):
self.session.open(
MessageBox,
_("Plugin") + " %s (c) gutemine" % gutemine_version,
MessageBox.TYPE_INFO,
timeout=gutemine_timeout,
)
def save(self):
config.plugins.gutemine.package_install.value = (
config.plugins.gutemine.package_install.default
)
config.plugins.gutemine.package_uninstall.value = (
config.plugins.gutemine.package_uninstall.default
)
config.plugins.gutemine.package_update.value = (
config.plugins.gutemine.package_update.default
)
config.plugins.gutemine.package_downgrade.value = (
config.plugins.gutemine.package_downgrade.default
)
if os_path.exists("/etc/apt/apt.conf"):
f = open("/etc/apt/apt.conf", "r")
aptconf = f.read()
f.close()
timeout = int(config.plugins.gutemine.timeout.value)
if timeout == 0:
if aptconf.find("Timeout") != -1:
aptconf = 'APT::Architecture "%s";\n' % gm.arch()
else:
aptconf = (
'APT::Architecture "%s";\nAcquire::http::Timeout "%s";\nAcquire::https::Timeout "%s";\nAcquire::ftp::Timeout "%s";\n'
% (gm.arch(),timeout, timeout, timeout)
)
f = open("/etc/apt/apt.conf", "w")
f.write(aptconf)
f.close()
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.gutemine.confirm.value != "false":
if config.plugins.gutemine.confirm.value == "true":
text = _("Really close without saving settings?")
self.session.openWithCallback(
self.cancel, MessageBox, text, MessageBox.TYPE_YESNO
)
else: # only info message ...
text = _("Really close without saving settings?").replace("?", "!")
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(("%s %s %s" % (gheader,_("User defined")+" "+_("Settings"),gtrailer), ))
self.list.append(
getConfigListEntry(
_("Load feed on startup:").replace(":", ""),
config.plugins.gutemine.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 extension"),
config.plugins.gutemine.local,
"Activate or deactivate the package-listing from selectable local folder.\nYou can use predefined folders or a userdefined folder.",
)
)
if config.plugins.gutemine.local.value == "user":
self.list.append(
getConfigListEntry(
"..." + _("User defined") + " " + _("Install local extension"),
config.plugins.gutemine.local_user_path,
"You can select a local folder with 'OK'.",
)
)
self.list.append(
getConfigListEntry(
_("Exit") + " " + _("Action"),
config.plugins.gutemine.leave_action,
"Leave Feed Plugin Action.",
)
)
if (
config.plugins.gutemine.feed.value
or config.plugins.gutemine.local.value != "none"
):
ask_text = (
_("yes")
+ ": "
+ _("The plugin will ask you before starting plugin-actions.")
+ "\n"
+ _("Message")
+ ": "
+ _("The plugin only shows a message on plugin-actions.")
)
self.list.append(
getConfigListEntry(
_("Ask user"), config.plugins.gutemine.confirm, ask_text
)
)
self.list.append(
getConfigListEntry(
_("Current version:").replace(":", ""),
config.plugins.gutemine.version,
"Show the current version number of the package in the package list.",
)
)
self.list.append(
getConfigListEntry(
_("Size"),
config.plugins.gutemine.size,
"Show the size of the package in the package list.",
)
)
extra_text = (
_("Select the extra info shown in the package list")
+ " ("
+ _("Default")
+ "="
+ _("Description")
+ ")"
)
self.list.append(
getConfigListEntry(
_("Extra Info"), config.plugins.gutemine.show_info, extra_text
)
)
self.list.append(
getConfigListEntry(
_("View list of available ") + _("Updates"),
config.plugins.gutemine.show_update_section,
"Show an additional section on the top of the package list for updatable packackes.",
)
)
self.list.append(
getConfigListEntry(
_("View list of available ") + _("Plugins"),
config.plugins.gutemine.listview,
"Select the sorting mode of the package list, or to list no packages.",
)
)
timeout_text = _("Software update") + " " + _("no timeout")
self.list.append(
getConfigListEntry(
timeout_text,
config.plugins.gutemine.timeout,
"Select timeout of the Feed(s).",
)
)
self["config"].list = self.list
self["config"].l.setList(self.list)
def okPressed(self):
if self["config"].getCurrent()[1] == config.plugins.gutemine.local_user_path:
self.openDirectoryBrowser(config.plugins.gutemine.local_user_path.value)
return
def openDirectoryBrowser(self, path):
try:
self.session.openWithCallback(
self.openDirectoryBrowserCB,
gutemineDirectoryBrowser,
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:
cprint("openDirectoryBrowser failed")
def openDirectoryBrowserCB(self, path):
if not path == None:
if path != config.plugins.gutemine.local_user_path.value:
config.plugins.gutemine.local_user_path.value = path