文件操作 - utils.py
返回文件管理
返回主菜单
删除本文件
文件: /usr/lib/python2.7/site-packages/gtweak/utils.py
编辑文件内容
# -*- coding: utf-8 -*- # Copyright (c) 2011 John Stowers # SPDX-License-Identifier: GPL-3.0+ # License-Filename: LICENSES/GPL-3.0 import os.path import logging import tempfile import shutil import subprocess import glob import itertools import gtweak from gtweak.gsettings import GSettingsSetting import gi gi.require_version("Notify", "0.7") from gi.repository import GObject from gi.repository import GLib from gi.repository import Gio from gi.repository import Notify def singleton(cls): """ Singleton decorator that works with GObject derived types. The 'recommended' python one - http://wiki.python.org/moin/PythonDecoratorLibrary#Singleton does not (interacts badly with GObjectMeta """ instances = {} def getinstance(): if cls not in instances: instances[cls] = cls() return instances[cls] return getinstance def make_combo_list_with_default(opts, default, title=True, default_text=None): """ Turns a list of values into a list of value,name (where name is the display name a user will see in a combo box). If a value is opt is equal to that supplied in default the display name for that value is modified to "value <i>(default)</i>" @opts: a list of value @returns: a list of 2-tuples (value, name) """ themes = [] for t in opts: if t.lower() == "default" and t != default: #some themes etc are actually called default. Ick. Dont show them if they #are not the actual default value continue if title and len(t): name = t[0].upper() + t[1:] else: name = t if t == default: #indicates the default theme, e.g Adwaita (default) name = default_text or _("%s <i>(default)</i>") % name themes.append((t, name)) return themes def walk_directories(dirs, filter_func): valid = [] try: for thdir in dirs: if os.path.isdir(thdir): for t in os.listdir(thdir): if filter_func(os.path.join(thdir, t)): valid.append(t) except: logging.critical("Error parsing directories", exc_info=True) return valid def extract_zip_file(z, members_path, dest): """ returns (true_if_extracted_ok, true_if_updated) """ tmp = tempfile.mkdtemp() tmpdest = os.path.join(tmp, members_path) ok = True updated = False try: if os.path.exists(dest): shutil.rmtree(dest) updated = True z.extractall(tmp) shutil.copytree(tmpdest, dest) except OSError: ok = False logging.warning("Error extracting zip", exc_info=True) if ok: logging.info("Extracted zip to %s, copied to %s" % (tmpdest, dest)) return ok, updated def execute_subprocess(cmd_then_args, block=True): p = subprocess.Popen( cmd_then_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True, universal_newlines=True) if block: stdout, stderr = p.communicate() return stdout, stderr, p.returncode def get_resource_dirs(resource): """Returns a list of all known resource dirs for a given resource. :param str resource: Name of the resource (e.g. "themes") :return: A list of resource dirs """ dirs = [os.path.join(dir, resource) for dir in itertools.chain(GLib.get_system_data_dirs(), (gtweak.DATA_DIR, GLib.get_user_data_dir()))] dirs += [os.path.join(os.path.expanduser("~"), ".{}".format(resource))] return [dir for dir in dirs if os.path.isdir(dir)] @singleton class AutostartManager: @staticmethod def get_desktop_files(): return [a.get_filename() for a in Gio.app_info_get_all()] @staticmethod def get_user_autostart_files(): return glob.glob( os.path.join( GLib.get_user_config_dir(), "autostart", "*.desktop")) @staticmethod def get_system_autostart_files(): f = [] for d in GLib.get_system_config_dirs(): f.extend( glob.glob(os.path.join(d, "autostart", "*.desktop")) ) return f class AutostartFile: def __init__(self, appinfo, autostart_desktop_filename="", exec_cmd="", extra_exec_args=""): if appinfo: self._desktop_file = appinfo.get_filename() self._autostart_desktop_filename = autostart_desktop_filename or os.path.basename(self._desktop_file) self._create_file = False elif autostart_desktop_filename: self._desktop_file = None self._autostart_desktop_filename = autostart_desktop_filename self._create_file = True else: raise Exception("Need either an appinfo or a file name") self._exec_cmd = exec_cmd if extra_exec_args: self._extra_exec_args = " %s\n" % extra_exec_args else: self._extra_exec_args = "\n" user_autostart_dir = os.path.join(GLib.get_user_config_dir(), "autostart") if not os.path.isdir(user_autostart_dir): try: os.makedirs(user_autostart_dir) except: logging.critical("Could not create autostart dir: %s" % user_autostart_dir) self._user_autostart_file = os.path.join(user_autostart_dir, self._autostart_desktop_filename) if self._desktop_file: logging.debug("Found desktop file: %s" % self._desktop_file) logging.debug("User autostart desktop file: %s" % self._user_autostart_file) def _create_user_autostart_file(self): f = open(self._user_autostart_file, "w") f.write("[Desktop Entry]\nType=Application\nName=%s\nExec=%s\n" % (self._autostart_desktop_filename[0:-len('.desktop')], self._exec_cmd + self._extra_exec_args)) f.close() def is_start_at_login_enabled(self): if os.path.exists(self._user_autostart_file): #prefer user directories first #if it contains X-GNOME-Autostart-enabled=false then it has #has been disabled by the user in the session applet, otherwise #it is enabled return open(self._user_autostart_file).read().find("X-GNOME-Autostart-enabled=false") == -1 else: #check the system directories for f in AutostartManager().get_system_autostart_files(): if os.path.basename(f) == self._autostart_desktop_filename: return True return False def update_start_at_login(self, update): if os.path.exists(self._user_autostart_file): logging.info("Removing user autostart file %s" % self._user_autostart_file) os.remove(self._user_autostart_file) if update: if (not self._desktop_file) or (not os.path.exists(self._desktop_file)): if self._create_file: self._create_user_autostart_file() else: logging.critical("Could not find desktop file: %s" % self._desktop_file) return logging.info("Adding autostart %s" % self._user_autostart_file) #copy the original file to the new file, but add the extra exec args old = open(self._desktop_file, "r") new = open(self._user_autostart_file, "w") for l in old.readlines(): if l.startswith("Exec="): if self._exec_cmd: new.write("Exec=%s\n" % self._exec_cmd) else: new.write(l[0:-1]) new.write(self._extra_exec_args) else: new.write(l) old.close() new.close() class SchemaList: __list = None def __init__(self): if SchemaList.__list == None: SchemaList.__list = [] def get(self): return SchemaList.__list def insert(self, key_name, schema_name): v = [key_name, schema_name] SchemaList.__list.append(v) def reset(self): for i in SchemaList.__list: s = Gio.Settings(i[1]) s.reset(i[0]) @singleton class DisableExtension(GObject.GObject): __gsignals__ = { "disable-extension": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE,()), } def __init__(self): GObject.GObject.__init__(self) def disable(self): self.emit("disable-extension") @singleton class XSettingsOverrides: VARIANT_TYPES = { 'Gtk/ShellShowsAppMenu': GLib.Variant.new_int32, 'Gtk/EnablePrimaryPaste': GLib.Variant.new_int32, 'Gdk/WindowScalingFactor': GLib.Variant.new_int32, } def __init__(self): self._settings = Gio.Settings(schema='org.gnome.settings-daemon.plugins.xsettings') self._variant = self._settings.get_value("overrides") def _dup_variant_as_dict(self): items = {} for k in self._variant.keys(): try: #variant override doesnt support .items() v = self._variant[k] items[k] = self.VARIANT_TYPES[k](v) except KeyError: pass return items def _dup_variant(self): return GLib.Variant('a{sv}', self._dup_variant_as_dict()) def _set_override(self, name, v): items = self._dup_variant_as_dict() items[name] = self.VARIANT_TYPES[name](v) n = GLib.Variant('a{sv}', items) self._settings.set_value('overrides', n) self._variant = self._settings.get_value("overrides") def _get_override(self, name, default): try: return self._variant[name] except KeyError: return default #while I could store meta type information in the VARIANT_TYPES #dict, its easiest to do default value handling and missing value #checks in dedicated functions def set_shell_shows_app_menu(self, v): self._set_override('Gtk/ShellShowsAppMenu', int(v)) def get_shell_shows_app_menu(self): return self._get_override('Gtk/ShellShowsAppMenu', True) def set_enable_primary_paste(self, v): self._set_override('Gtk/EnablePrimaryPaste', int(v)) def get_enable_primary_paste(self): return self._get_override('Gtk/EnablePrimaryPaste', True) def set_window_scaling_factor(self, v): self._set_override('Gdk/WindowScalingFactor', int(v)) def get_window_scaling_factor(self): return self._get_override('Gdk/WindowScalingFactor', 1) class Notification: def __init__(self, summary, body): if Notify.is_initted() or Notify.init(_("GNOME Tweaks")): self.notification = Notify.Notification.new( summary, body, 'gnome-tweaks' ) self.notification.set_hint( "desktop-entry", GLib.Variant('s', 'org.gnome.tweaks')) self.notification.show() else: raise Exception("Not Supported") @singleton class LogoutNotification: def __init__(self): if Notify.is_initted() or Notify.init(_("GNOME Tweaks")): self.notification = Notify.Notification.new( _("Configuration changes require restart"), _("Your session needs to be restarted for settings to take effect"), 'gnome-tweaks') self.notification.add_action( "restart", _("Restart Session"), self._logout, None, None) self.notification.set_hint( "desktop-entry", GLib.Variant('s', 'org.gnome.tweaks')) self.notification.show() else: raise Exception("Not Supported") def _logout(self, btn, action, user_data, unknown): d = Gio.bus_get_sync(Gio.BusType.SESSION, None) proxy = Gio.DBusProxy.new_sync( d,Gio.DBusProxyFlags.NONE, None, 'org.gnome.SessionManager', '/org/gnome/SessionManager', 'org.gnome.SessionManager', None) proxy.Logout('(u)', 0)
修改文件时间
将文件时间修改为当前时间的前一年
删除文件