appmenus: script formatting

Wrap long lines, fix whitespaces
This commit is contained in:
Marek Marczykowski-Górecki 2015-05-02 20:13:28 +02:00
parent d43a421dee
commit 2a08357fa4
2 changed files with 150 additions and 88 deletions

View File

@ -28,9 +28,9 @@ import os.path
import shutil
import dbus
from qubes.qubes import QubesVm,QubesHVm
from qubes.qubes import QubesException,QubesHost,QubesVmLabels
from qubes.qubes import vm_files,system_path,dry_run
from qubes.qubes import QubesVm, QubesHVm
from qubes.qubes import QubesException, QubesHost, QubesVmLabels
from qubes.qubes import vm_files, system_path, dry_run
import qubes.imgconverter
@ -40,9 +40,12 @@ vm_files['appmenus_icons_subdir'] = 'apps.icons'
vm_files['appmenus_template_templates_subdir'] = 'apps-template.templates'
vm_files['appmenus_whitelist'] = 'whitelisted-appmenus.list'
system_path['appmenu_start_hvm_template'] = '/usr/share/qubes-appmenus/qubes-start.desktop'
system_path['appmenu_create_cmd'] = '/usr/libexec/qubes-appmenus/create-apps-for-appvm.sh'
system_path['appmenu_remove_cmd'] = '/usr/libexec/qubes-appmenus/remove-appvm-appmenus.sh'
system_path['appmenu_start_hvm_template'] = \
'/usr/share/qubes-appmenus/qubes-start.desktop'
system_path['appmenu_create_cmd'] = \
'/usr/libexec/qubes-appmenus/create-apps-for-appvm.sh'
system_path['appmenu_remove_cmd'] = \
'/usr/libexec/qubes-appmenus/remove-appvm-appmenus.sh'
def QubesVm_get_attrs_config(self, attrs):
@ -56,12 +59,14 @@ def QubesVm_get_attrs_config(self, attrs):
'os.path.join(self.dir_path, vm_files["appmenus_icons_subdir"])' }
return attrs
def QubesTemplateVm_get_attrs_config(self, attrs):
attrs['appmenus_templates_dir'] = { 'eval': 'os.path.join(self.dir_path, vm_files["appmenus_templates_subdir"])' }
attrs['appmenus_template_icons_dir'] = { 'eval': 'os.path.join(self.dir_path, vm_files["appmenus_template_icons_subdir"])' }
return attrs
def QubesVm_appmenus_create(self, verbose=False, source_template = None):
def QubesVm_appmenus_create(self, verbose=False, source_template=None):
if source_template is None:
source_template = self.template
@ -84,18 +89,20 @@ def QubesVm_appmenus_create(self, verbose=False, source_template = None):
self.name, vmtype, self.label.icon],
stdout=msgoutput, stderr=msgoutput)
elif self.appmenus_templates_dir is not None:
subprocess.check_call ([system_path["appmenu_create_cmd"],
self.appmenus_templates_dir, self.name,
vmtype, self.label.icon],
stdout=msgoutput, stderr=msgoutput)
subprocess.check_call([system_path["appmenu_create_cmd"],
self.appmenus_templates_dir, self.name,
vmtype, self.label.icon],
stdout=msgoutput, stderr=msgoutput)
else:
# Only add apps to menu
subprocess.check_call ([system_path["appmenu_create_cmd"],
"none", self.name, vmtype,
self.label.icon],
stdout=msgoutput, stderr=msgoutput)
subprocess.check_call([system_path["appmenu_create_cmd"],
"none", self.name, vmtype,
self.label.icon],
stdout=msgoutput, stderr=msgoutput)
except subprocess.CalledProcessError:
print >> sys.stderr, "Ooops, there was a problem creating appmenus for {0} VM!".format (self.name)
print >> sys.stderr, "Ooops, there was a problem creating appmenus " \
"for {0} VM!".format(self.name)
def QubesVm_appmenus_remove(self):
vmtype = None
@ -105,8 +112,9 @@ def QubesVm_appmenus_remove(self):
vmtype = 'vm-templates'
else:
vmtype = 'appvms'
subprocess.check_call ([system_path["appmenu_remove_cmd"], self.name,
vmtype], stderr=open(os.devnull, 'w'))
subprocess.check_call([system_path["appmenu_remove_cmd"], self.name,
vmtype], stderr=open(os.devnull, 'w'))
def QubesVm_appicons_create(self, srcdir=None):
if srcdir is None:
@ -136,51 +144,64 @@ def QubesVm_appicons_create(self, srcdir=None):
src_icon = os.path.join(srcdir, icon)
dst_icon = os.path.join(self.appmenus_icons_dir, icon)
if not os.path.exists(dst_icon) or \
os.path.getmtime(src_icon) > os.path.getmtime(dst_icon):
os.path.getmtime(src_icon) > os.path.getmtime(dst_icon):
qubes.imgconverter.tint(src_icon, dst_icon, self.label.color)
def QubesVm_appicons_remove(self):
if not os.path.exists(self.appmenus_icons_dir): return
if not os.path.exists(self.appmenus_icons_dir):
return
for icon in os.listdir(self.appmenus_icons_dir):
os.unlink(os.path.join(self.appmenus_icons_dir, icon))
def QubesVm_pre_rename(self, new_name):
self.appmenus_remove()
def QubesVm_post_rename(self, old_name):
old_dirpath = os.path.join(os.path.dirname(self.dir_path), old_name)
if self.appmenus_templates_dir is not None:
self.appmenus_templates_dir = self.appmenus_templates_dir.replace(old_dirpath, self.dir_path)
self.appmenus_templates_dir = self.appmenus_templates_dir.replace(
old_dirpath, self.dir_path)
self.appmenus_create()
def QubesVm_create_on_disk(self, verbose, source_template):
if isinstance(self, QubesHVm) and source_template is None:
if verbose:
print >> sys.stderr, "--> Creating appmenus directory: {0}".format(self.appmenus_templates_dir)
os.mkdir (self.appmenus_templates_dir)
shutil.copy (system_path["appmenu_start_hvm_template"], self.appmenus_templates_dir)
print >> sys.stderr, "--> Creating appmenus directory: {0}".format(
self.appmenus_templates_dir)
os.mkdir(self.appmenus_templates_dir)
shutil.copy(system_path["appmenu_start_hvm_template"],
self.appmenus_templates_dir)
source_whitelist_filename = 'vm-' + vm_files["appmenus_whitelist"]
if self.is_netvm():
source_whitelist_filename = 'netvm-' + vm_files["appmenus_whitelist"]
if source_template and os.path.exists(os.path.join(source_template.dir_path, source_whitelist_filename)):
if source_template and os.path.exists(
os.path.join(source_template.dir_path, source_whitelist_filename)):
if verbose:
print >> sys.stderr, "--> Creating default whitelisted apps list: {0}".\
print >> sys.stderr, "--> Creating default whitelisted apps list: {0}". \
format(self.dir_path + '/' + vm_files["whitelisted_appmenus"])
shutil.copy(os.path.join(source_template.dir_path, source_whitelist_filename),
os.path.join(self.dir_path, vm_files["whitelisted_appmenus"]))
shutil.copy(
os.path.join(source_template.dir_path, source_whitelist_filename),
os.path.join(self.dir_path, vm_files["whitelisted_appmenus"]))
if source_template and self.updateable:
if verbose:
print >> sys.stderr, "--> Copying the template's appmenus templates dir:\n{0} ==>\n{1}".\
format(source_template.appmenus_templates_dir, self.appmenus_templates_dir)
print >> sys.stderr, "--> Copying the template's appmenus templates dir:\n{0} ==>\n{1}". \
format(source_template.appmenus_templates_dir,
self.appmenus_templates_dir)
if os.path.isdir(source_template.appmenus_templates_dir):
shutil.copytree (source_template.appmenus_templates_dir, self.appmenus_templates_dir)
shutil.copytree(source_template.appmenus_templates_dir,
self.appmenus_templates_dir)
else:
os.mkdir(self.appmenus_templates_dir)
if os.path.isdir(source_template.appmenus_template_icons_dir):
shutil.copytree (source_template.appmenus_template_icons_dir, self.appmenus_template_icons_dir)
shutil.copytree(source_template.appmenus_template_icons_dir,
self.appmenus_template_icons_dir)
else:
os.mkdir(self.appmenus_template_icons_dir)
@ -188,23 +209,27 @@ def QubesVm_create_on_disk(self, verbose, source_template):
self.appicons_create()
self.appmenus_create(verbose=verbose)
def QubesVm_clone_disk_files(self, src_vm, verbose):
if src_vm.updateable and src_vm.appmenus_templates_dir is not None and self.appmenus_templates_dir is not None:
if src_vm.updateable and src_vm.appmenus_templates_dir is not None and \
self.appmenus_templates_dir is not None:
if verbose:
print >> sys.stderr, "--> Copying the template's appmenus templates dir:\n{0} ==>\n{1}".\
format(src_vm.appmenus_templates_dir, self.appmenus_templates_dir)
shutil.copytree (src_vm.appmenus_templates_dir, self.appmenus_templates_dir)
print >> sys.stderr, "--> Copying the template's appmenus templates dir:\n{0} ==>\n{1}". \
format(src_vm.appmenus_templates_dir,
self.appmenus_templates_dir)
shutil.copytree(src_vm.appmenus_templates_dir,
self.appmenus_templates_dir)
if src_vm.updateable and src_vm.appmenus_template_icons_dir is not None \
and self.appmenus_template_icons_dir is not None and \
os.path.isdir(src_vm.appmenus_template_icons_dir):
if verbose:
print >> sys.stderr, "--> Copying the template's appmenus " \
"template icons dir:\n{0} ==>\n{1}".\
format(src_vm.appmenus_template_icons_dir,
self.appmenus_template_icons_dir)
shutil.copytree (src_vm.appmenus_template_icons_dir,
self.appmenus_template_icons_dir)
"template icons dir:\n{0} ==>\n{1}". \
format(src_vm.appmenus_template_icons_dir,
self.appmenus_template_icons_dir)
shutil.copytree(src_vm.appmenus_template_icons_dir,
self.appmenus_template_icons_dir)
for whitelist in (
vm_files["appmenus_whitelist"],
@ -212,18 +237,20 @@ def QubesVm_clone_disk_files(self, src_vm, verbose):
'netvm-' + vm_files["appmenus_whitelist"]):
if os.path.exists(os.path.join(src_vm.dir_path, whitelist)):
if verbose:
print >> sys.stderr, "--> Copying whitelisted apps list: {0}".\
print >> sys.stderr, "--> Copying whitelisted apps list: {0}". \
format(whitelist)
shutil.copy(os.path.join(src_vm.dir_path, whitelist),
os.path.join(self.dir_path, whitelist))
os.path.join(self.dir_path, whitelist))
# Create appmenus
self.appicons_create()
self.appmenus_create(verbose=verbose)
def QubesVm_remove_from_disk(self):
self.appmenus_remove()
def QubesVm_label_setter(self, _):
self.appicons_create()
@ -231,14 +258,18 @@ def QubesVm_label_setter(self, _):
# see #751 for details
if os.environ.get("DESKTOP_SESSION", "") == "kde-plasma":
try:
os.unlink(os.path.expandvars("$HOME/.kde/cache-$HOSTNAME/icon-cache.kcache"))
os.unlink(os.path.expandvars(
"$HOME/.kde/cache-$HOSTNAME/icon-cache.kcache"))
except:
pass
try:
notify_object = dbus.SessionBus().get_object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
notify_object = dbus.SessionBus().get_object(
"org.freedesktop.Notifications",
"/org/freedesktop/Notifications")
notify_object.Notify(
"Qubes", 0, self.label.icon, "Qubes",
"You will need to log off and log in again for the VM icons to update in the KDE launcher menu",
"You will need to log off and log in again for the VM icons "
"to update in the KDE launcher menu",
[], [], 10000,
dbus_interface="org.freedesktop.Notifications")
except:
@ -247,6 +278,7 @@ def QubesVm_label_setter(self, _):
self.appmenus_remove()
self.appmenus_create()
def QubesVm_appmenus_recreate(self):
"""
Force recreation of all appmenus and icons. For example when VM label
@ -257,6 +289,7 @@ def QubesVm_appmenus_recreate(self):
self.appicons_create()
self.appmenus_create()
def QubesVm_appmenus_update(self):
"""
Similar to appmenus_recreate, but do not touch unchanged files
@ -266,6 +299,7 @@ def QubesVm_appmenus_update(self):
self.appicons_cleanup()
self.appmenus_create()
def QubesVm_set_attr(self, name, newvalue, oldvalue):
if name == 'internal':
if newvalue and not oldvalue:

View File

@ -29,15 +29,15 @@ import shutil
import pipes
from optparse import OptionParser
from qubes.qubes import QubesVmCollection,QubesException,system_path
from qubes.qubes import QubesVmCollection, QubesException, system_path
from qubes.qubes import QubesHVm
from qubes.qubes import vm_files
import qubes.imgconverter
# fields required to be present (and verified) in retrieved desktop file
required_fields = [ "Name", "Exec" ]
required_fields = ["Name", "Exec"]
#limits
# limits
appmenus_line_size = 1024
appmenus_line_count = 100000
@ -98,12 +98,14 @@ def sanitise_categories(untrusted_value):
return ';'.join(categories) + ';'
def fallback_hvm_appmenulist():
p = subprocess.Popen(["grep", "-rH", "=", "/usr/share/qubes-appmenus/hvm"],
stdout=subprocess.PIPE)
p = subprocess.Popen(["grep", "-rH", "=", "/usr/share/qubes-appmenus/hvm"],
stdout=subprocess.PIPE)
(stdout, stderr) = p.communicate()
return stdout.splitlines()
def get_appmenus(vm):
global appmenus_line_count
global appmenus_line_size
@ -137,12 +139,13 @@ def get_appmenus(vm):
row_no = 0
appmenus = {}
line_rx = re.compile(r"([a-zA-Z0-9.()_-]+.desktop):([a-zA-Z0-9-]+(?:\[[a-zA-Z@_]+\])?)=(.*)")
line_rx = re.compile(
r"([a-zA-Z0-9.()_-]+.desktop):([a-zA-Z0-9-]+(?:\[[a-zA-Z@_]+\])?)=(.*)")
ignore_rx = re.compile(r".*([a-zA-Z0-9._-]+.desktop):(#.*|\s+)$")
for untrusted_line in untrusted_appmenulist:
# Ignore blank lines and comments
if len(untrusted_line) == 0 or ignore_rx.match(untrusted_line):
continue
continue
# use search instead of match to skip file path
untrusted_m = line_rx.search(untrusted_line)
if untrusted_m:
@ -171,9 +174,11 @@ def get_appmenus(vm):
if not appmenus.has_key(filename):
appmenus[filename] = {}
appmenus[filename][key]=value
appmenus[filename][key] = value
else:
print >>sys.stderr, "Warning: ignoring key %r of %s" % (untrusted_key, filename)
print >> sys.stderr, \
"Warning: ignoring key %r of %s" % \
(untrusted_key, filename)
# else: ignore this key
return appmenus
@ -183,7 +188,9 @@ def create_template(path, values):
# check if all required fields are present
for key in required_fields:
if not values.has_key(key):
print >>sys.stderr, "Warning: not creating/updating '%s' because of missing '%s' key" % (path, key)
print >> sys.stderr, "Warning: not creating/updating '%s' " \
"because of missing '%s' key" % (
path, key)
return
desktop_entry = ""
@ -200,11 +207,11 @@ def create_template(path, values):
else:
desktop_entry += "Icon=%XDGICON%\n"
for key in ["Name", "GenericName" ]:
for key in ["Name", "GenericName"]:
if values.has_key(key):
desktop_entry += "{0}=%VMNAME%: {1}\n".format(key, values[key])
for key in [ "Comment", "Categories" ]:
for key in ["Comment", "Categories"]:
if values.has_key(key):
desktop_entry += "{0}={1}\n".format(key, values[key])
@ -215,30 +222,37 @@ def create_template(path, values):
desktop_file.write(desktop_entry)
desktop_file.close()
def main():
env_vmname = os.environ.get("QREXEC_REMOTE_DOMAIN")
usage = "usage: %prog [options] <vm-name>\n"\
"Updates desktop file templates for given StandaloneVM or TemplateVM"
usage = "usage: %prog [options] <vm-name>\n" \
"Update desktop file templates for given StandaloneVM or TemplateVM"
parser = OptionParser (usage)
parser.add_option ("-v", "--verbose", action="store_true", dest="verbose", default=False)
parser.add_option ("--force-root", action="store_true", dest="force_root", default=False,
help="Force to run, even with root privileges")
parser.add_option ("--force-rpc", action="store_true", dest="force_rpc", default=False,
help="Force to start a new RPC call, even if called from existing one")
parser = OptionParser(usage)
parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
default=False)
parser.add_option("--force-root", action="store_true", dest="force_root",
default=False,
help="Force to run, even with root privileges")
parser.add_option("--force-rpc", action="store_true", dest="force_rpc",
default=False,
help="Force to start a new RPC call, "
"even if called from existing one")
(options, args) = parser.parse_args ()
if (len (args) != 1) and env_vmname is None:
parser.error ("You must specify at least the VM name!")
(options, args) = parser.parse_args()
if (len(args) != 1) and env_vmname is None:
parser.error("You must specify at least the VM name!")
if env_vmname:
vmname=env_vmname
vmname = env_vmname
else:
vmname=args[0]
vmname = args[0]
if os.geteuid() == 0:
if not options.force_root:
print >> sys.stderr, "*** Running this tool as root is strongly discouraged, this will lead you in permissions problems."
print >> sys.stderr, "*** Running this tool as root is strongly " \
"discouraged, this will lead you into " \
"permissions problems."
print >> sys.stderr, "Retry as unprivileged user."
print >> sys.stderr, "... or use --force-root to continue anyway."
exit(1)
@ -251,15 +265,19 @@ def main():
vm = qvm_collection.get_vm_by_name(vmname)
if vm is None:
print >>sys.stderr, "ERROR: A VM with the name '{0}' does not exist in the system.".format(vmname)
print >> sys.stderr, "ERROR: A VM with the name '{0}' " \
"does not exist in the system.".format(
vmname)
exit(1)
if vm.template is not None:
print >>sys.stderr, "ERROR: To sync appmenus for template based VM, do it on template instead"
print >> sys.stderr, "ERROR: To sync appmenus for template based VM, " \
"do it on template instead"
exit(1)
if not vm.is_running():
print >>sys.stderr, "ERROR: Appmenus can be retrieved only from running VM - start it first"
print >> sys.stderr, "ERROR: Appmenus can be retrieved only from " \
"running VM - start it first"
exit(1)
new_appmenus = {}
@ -270,7 +288,7 @@ def main():
new_appmenus = get_appmenus(None)
if len(new_appmenus) == 0:
print >>sys.stderr, "ERROR: No appmenus received, terminating"
print >> sys.stderr, "ERROR: No appmenus received, terminating"
exit(1)
if not os.path.exists(vm.appmenus_templates_dir):
@ -281,10 +299,12 @@ def main():
# Create new/update existing templates
if options.verbose:
print >> sys.stderr, "--> Got {0} appmenus, storing to disk".format(str(len(new_appmenus)))
print >> sys.stderr, "--> Got {0} appmenus, storing to disk".format(
str(len(new_appmenus)))
for appmenu_file in new_appmenus.keys():
if options.verbose:
if os.path.exists(os.path.join(vm.appmenus_templates_dir, appmenu_file)):
if os.path.exists(
os.path.join(vm.appmenus_templates_dir, appmenu_file)):
print >> sys.stderr, "---> Updating {0}".format(appmenu_file)
else:
print >> sys.stderr, "---> Creating {0}".format(appmenu_file)
@ -294,11 +314,14 @@ def main():
# del new_appmenus[appmenu_file]['Icon']
icondest = os.path.join(vm.appmenus_template_icons_dir,
os.path.splitext(appmenu_file)[0] + '.png')
os.path.splitext(appmenu_file)[0] + '.png')
try:
icon = qubes.imgconverter.Image.get_xdg_icon_from_vm(vm,
new_appmenus[appmenu_file]['Icon'])
icon = qubes.imgconverter.Image. \
get_xdg_icon_from_vm(vm,
new_appmenus[
appmenu_file][
'Icon'])
if os.path.exists(icondest):
old_icon = qubes.imgconverter.Image.load_from_file(icondest)
else:
@ -306,15 +329,17 @@ def main():
if old_icon is None or icon != old_icon:
icon.save(icondest)
except Exception, e:
print >> sys.stderr, '----> Failed to get icon for {0}: {1!s}'.format(appmenu_file, e)
print >> sys.stderr, '----> Failed to get icon for {0}: {1!s}'.\
format(appmenu_file, e)
if os.path.exists(icondest):
print >> sys.stderr, '-----> Found old icon, using it instead'
print >> sys.stderr, '-----> Found old icon, ' \
'using it instead'
else:
del new_appmenus[appmenu_file]['Icon']
create_template(os.path.join(vm.appmenus_templates_dir, appmenu_file),
new_appmenus[appmenu_file])
new_appmenus[appmenu_file])
# Delete appmenus of removed applications
if options.verbose:
@ -330,8 +355,10 @@ def main():
if isinstance(vm, QubesHVm):
if not os.path.exists(os.path.join(vm.appmenus_templates_dir,
os.path.basename(system_path['appmenu_start_hvm_template']))):
shutil.copy(system_path['appmenu_start_hvm_template'], vm.appmenus_templates_dir)
os.path.basename(system_path[
'appmenu_start_hvm_template']))):
shutil.copy(system_path['appmenu_start_hvm_template'],
vm.appmenus_templates_dir)
vm.appmenus_recreate()
if hasattr(vm, 'appvms'):
@ -340,10 +367,11 @@ def main():
try:
child_vm.appmenus_update()
except Exception, e:
print >> sys.stderr, "---> Failed to recreate appmenus for " \
print >> sys.stderr, "---> Failed to recreate appmenus for " \
"'{0}': {1}".format(child_vm.name, str(e))
if 'KDE_SESSION_UID' in os.environ:
subprocess.call(['kbuildsycoca4'])
os.unsetenv('SKIP_CACHE_REBUILD')
main()