def newStarter(self, path, newstart): myitem = DesktopEntry(path) myitem.set("Name", newstart.Name) myitem.set("Exec", newstart.Exec) myitem.set("Comment", newstart.Comment) myitem.set("Type", "Application") myitem.set("Version", "1.0") myitem.set("X-GNOME-Autostart-enabled", newstart.Autostart) # Scrive il file .desktop myitem.write()
def set_autostart(self, enable): if not os.path.exists(self.autostart_desktop): if os.path.exists(self.sys_autostart_desktop): os.system("mkdir -p %s" % os.path.dirname(self.autostart_desktop)) os.system("cp %s %s" % (self.sys_autostart_desktop, self.autostart_desktop)) else: return False desktop_entry = DesktopEntry(self.autostart_desktop) if desktop_entry.getHidden() == enable: hidden_word = "false" if enable else "true" desktop_entry.set("Hidden", hidden_word) desktop_entry.write()
def enabled_toggled(self, cell, path, model): iter = model.get_iter((int(path),)) active = model.get_value(iter, COLUMN_ACTIVE) path = model.get_value(iter, COLUMN_PATH) if self.is_defaultitem(path): shutil.copy(path, self.userdir) path = os.path.join(self.userdir, os.path.basename(path)) desktopentry = DesktopEntry(path) desktopentry.set("X-GNOME-Autostart-enabled", "false") desktopentry.write() model.set(iter, COLUMN_PATH, path) else: if active: desktopentry = DesktopEntry(path) desktopentry.set("X-GNOME-Autostart-enabled", "false") desktopentry.write() else: if self.is_in_systemdir(path): os.remove(path) path = os.path.join(self.get_systemdir(path), os.path.basename(path)) model.set(iter, COLUMN_PATH, path) else: desktopentry = DesktopEntry(path) desktopentry.set("X-GNOME-Autostart-enabled", "true") desktopentry.set("Hidden", "false") desktopentry.write() active = not active model.set(iter, COLUMN_ACTIVE, active)
def _create_autostarter(self): autostart_file = self._get_autostart_file_path() autostart_dir = os.path.dirname(autostart_file) if not os.path.isdir(autostart_dir): #create autostart dir try: os.mkdir(autostart_dir) except DirectoryCreationError as e: print("Creation of autostart dir failed, please make it yourself: {}".format(autostart_dir)) raise e if not os.path.isfile(autostart_file): # create autostart entry starter_item = DesktopEntry(autostart_file) starter_item.set('Name', 'f.lux indicator applet') # Use the user's shell to start 'fluxgui', in case # 'fluxgui' is not installed on a standard system path. We # use 'sh' to start the users '/etc/passwd' shell via # '$SHELL', so that this will still work if the user # changes their shell after the # 'autostart/fluxgui.desktop' file is created. # # See PR #89 for an alternative approach: # # https://github.com/xflux-gui/fluxgui/pull/89 # # The escaping of the 'Exec' field is described in # # https://developer.gnome.org/desktop-entry-spec/#exec-variables. starter_item.set('Exec', r'sh -c "\\"\\$SHELL\\" -c fluxgui"') starter_item.set('Icon', 'fluxgui') starter_item.set('X-GNOME-Autostart-enabled', 'true') starter_item.write() self.autostart = True
def on_remove_item(self, widget, treeview): model, iter = treeview.get_selection().get_selected() if iter: path = model.get_value(iter, COLUMN_PATH) if path[1:4] == "etc": shutil.copy(path, treeview.userdir) desktopentry = DesktopEntry(os.path.join(treeview.userdir, os.path.basename(path))) else: desktopentry = DesktopEntry(path) desktopentry.set("Hidden", "true") desktopentry.set("X-GNOME-Autostart-enabled", "false") desktopentry.write() treeview.update_items(all = self.show_all_button.get_active(), comment = self.show_comment_button.get_active())
def _update_autostart_flag(self): if self._desktop == 'unknown': # No se puede autostartear :( return desktop_compartir = DesktopEntry( os.path.join(BaseDirectory.save_config_path('autostart'), 'compartir.desktop') ) if self._desktop == 'mate': desktop_compartir.set( 'X-MATE-Autostart-enabled', 'true' if self.compartir.autostart else 'false' ) desktop_compartir.write()
def test_write_file(self): de = DesktopEntry() de.parse(self.test_file) de.removeKey("Name") de.addGroup("Hallo") de.set("key", "value", "Hallo") new_file = os.path.join(self.tmpdir, "test.desktop") de.write(new_file, trusted=True) with io.open(new_file, encoding='utf-8') as f: contents = f.read() assert "[Hallo]" in contents, contents assert re.search("key\s*=\s*value", contents), contents # This is missing the Name key, and has an unknown Hallo group, so it # shouldn't validate. new_entry = DesktopEntry(new_file) self.assertRaises(ValidationError, new_entry.validate)
def on_edit_item(self, widget, treeview): model, iter = treeview.get_selection().get_selected() if iter: path = model.get_value(iter, COLUMN_PATH) if path[1:4] == "etc": shutil.copy(path, treeview.userdir) path = os.path.join(treeview.userdir, os.path.basename(path)) dialog = AutoStartDialog(DesktopEntry(path), widget.get_toplevel()) if dialog.run() == gtk.RESPONSE_OK: name = dialog.pm_name.get_text() cmd = dialog.pm_cmd.get_text() if not name: ErrorDialog(_("The name of the startup program cannot be empty")).launch() elif not cmd: ErrorDialog(_("Text was empty (or contained only whitespace)")).launch() else: desktopentry = DesktopEntry(path) desktopentry.set("Name", name, locale = True) desktopentry.set("Exec", cmd) desktopentry.set("Comment", dialog.pm_comment.get_text(), locale = True) desktopentry.write() treeview.update_items(all = self.show_all_button.get_active(), comment = self.show_comment_button.get_active()) dialog.destroy() return dialog.destroy()
def create_autostarter(self): """Adds an entry to the autostart directory to start fluxgui on startup.""" autostart_file = self._get_autostart_file_path() autostart_dir = os.path.dirname(autostart_file) if not os.path.isdir(autostart_dir): # Create autostart directory. try: os.mkdir(autostart_dir) except OSError: print ('creation of autostart dir failed, please make it ' 'yourself: %s') % autostart_dir self.exit() if not os.path.isfile(autostart_file): #create autostart entry starter_item = DesktopEntry(autostart_file) starter_item.set('Name', 'f.lux indicator applet') starter_item.set('Exec', 'fluxgui') starter_item.set('Icon', 'fluxgui') starter_item.set('X-GNOME-Autostart-enabled', 'true') starter_item.write()
class shortcut: def __init__(self, dest, path, arguments, name=None, ttype=TargetType.FILESYSTEM): ''' :param dest: Path to resulting file on file system :param path: Path where the link should point to :param arguments: Arguemnts to eecutable file :param name: Name of the application :param type: Link type - FILESYSTEM or URL ''' self.dest = dest self.path = path self.arguments = arguments self.name = name self.changed = '' self.is_in_user_context = self.set_usercontext() self.type = ttype def __str__(self): result = self.to_json() return result def set_changed(self, change_date): ''' Set object change date ''' self.changed = change_date def set_clsid(self, clsid): self.clsid = clsid def set_guid(self, uid): self.guid = uid def set_type(self, ttype): ''' Set type of the hyperlink - FILESYSTEM or URL :ttype: - object of class TargetType ''' self.type = ttype def set_usercontext(self, usercontext=False): ''' Perform action in user context or not ''' ctx = False if usercontext in [1, '1', True]: ctx = True self.is_in_user_context = ctx def is_usercontext(self): return self.is_in_user_context def to_json(self): ''' Return shortcut's JSON for further serialization. ''' content = dict() content['dest'] = self.dest content['path'] = self.path content['name'] = self.name content['arguments'] = self.arguments content['clsid'] = self.clsid content['guid'] = self.guid content['changed'] = self.changed content['is_in_user_context'] = self.is_in_user_context content['type'] = ttype2str(self.type) result = self.desktop() result.content.update(content) return json.dumps(result.content) def desktop(self): ''' Returns desktop file object which may be written to disk. ''' self.desktop_file = DesktopEntry() self.desktop_file.addGroup('Desktop Entry') if self.type == TargetType.URL: self.desktop_file.set('Type', 'Link') else: self.desktop_file.set('Type', 'Application') self.desktop_file.set('Version', '1.0') self.desktop_file.set('Name', self.name) if self.type == TargetType.URL: self.desktop_file.set('URL', self.path) else: self.desktop_file.set('Terminal', 'false') self.desktop_file.set('Exec', '{} {}'.format(self.path, self.arguments)) return self.desktop_file def write_desktop(self, dest): ''' Write .desktop file to disk using path 'dest'. Please note that .desktop files must have executable bit set in order to work in GUI. ''' self.desktop().write(dest) sc = Path(dest) sc.chmod(sc.stat().st_mode | stat.S_IEXEC)
class Autostart(gobject.GObject): __gsignals__ = { 'changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_BOOLEAN,)), } def __init__(self): gobject.GObject.__init__(self) self.config = Config.Config(tgcm.country_support) # Determine the path for XDG autostart dirs self.autofile_name = 'tgcm-%s.desktop' % tgcm.country_support self.user_autodir = None for foo in BaseDirectory.load_config_paths('autostart'): if foo.startswith(os.path.expanduser('~')): self.user_autodir = foo else: self.system_autodir = foo self.__create_desktop_entry_if_necessary() # Listen to file changes myfile = gio.File(self.user_autofile) self.desktopentry_monitor = myfile.monitor_file() self.desktopentry_monitor.connect('changed', self.on_desktopentry_changed) def __create_desktop_entry_if_necessary(self): # Create user autostart dir if it does not exists if self.user_autodir is None: self.user_autodir = BaseDirectory.save_config_path('autostart') # It it does not exists an autostart file for TGCM in userdir, # create a copy from the global one self.user_autofile = os.path.join(self.user_autodir, self.autofile_name) if not os.path.exists(self.user_autofile): autofile_path = os.path.join(self.system_autodir, self.autofile_name) shutil.copy(autofile_path, self.user_autofile) # Honor 'launch-startup' policy in regional-info.xml file self.desktopentry = DesktopEntry(self.user_autofile) is_autostart = self.config.check_policy('launch-startup') self.set_enabled(is_autostart) else: self.desktopentry = DesktopEntry(self.user_autofile) def is_enabled(self): self.__create_desktop_entry_if_necessary() # Check if the DesktopEntry object has an autostart attribute if self.desktopentry.hasKey('X-GNOME-Autostart-enabled'): is_autostart = self.desktopentry.get('X-GNOME-Autostart-enabled', \ type='boolean') else: is_autostart = True if self.desktopentry.hasKey('Hidden'): is_shown = not self.desktopentry.get('Hidden', type='boolean') else: is_shown = True return is_shown and is_autostart def set_enabled(self, value): self.__create_desktop_entry_if_necessary() value = str(value).lower() self.desktopentry.set('X-GNOME-Autostart-enabled', value) self.desktopentry.removeKey('Hidden') self.desktopentry.write() def on_desktopentry_changed(self, monitor, myfile, other_file, event): if event == gio.FILE_MONITOR_EVENT_DELETED: self.__create_desktop_entry_if_necessary() is_enabled = self.is_enabled() self.emit('changed', is_enabled)
def on_add_new_custom_dialog_response(self, dialog, response_id): """ Fired when the user triggered a response on the add_new_custom_dialog. """ # Clunky way to see if we have edit mode, but it works on_edit = dialog.get_widget_for_response(Gtk.ResponseType.NO).props.visible if not on_edit and response_id == Gtk.ResponseType.OK: # Obtain a working filename directory = os.path.expanduser("~/.config/autostart") if not os.path.exists(directory): os.makedirs(directory) filename = os.path.join( directory, self.objects.custom_name.get_text().lower().replace(" ","-") + ".custom%s.desktop" % (random.randint(0,1000),) ) if os.path.exists(filename): return on_add_new_custom_dialog_response(dialog, response_id) desktop_basename = os.path.basename(filename) entry = DesktopEntry(filename) entry.set("Version", 1.0) entry.set("Name", self.objects.custom_name.get_text()) entry.set("Exec", self.objects.custom_command.get_text()) entry.set("X-Vera-Autostart-Phase", "Other") entry.write() row = ApplicationRow(desktop_basename, entry) # Connect the changed signal row.connect("changed", self.on_row_changed) # Connect the requests_edit signal row.connect("requests_edit", self.on_row_requests_edit) # Prepend the row self.objects.list.prepend(row) self.desktop_list.append(desktop_basename) elif on_edit and response_id == Gtk.ResponseType.OK: # Edit self.current_edit_informations["desktop"].set("Name", self.objects.custom_name.get_text(), locale=True) self.current_edit_informations["desktop"].set("Exec", self.objects.custom_command.get_text()) self.current_edit_informations["desktop"].write() self.current_edit_informations["row"].name.set_text(self.objects.custom_name.get_text()) elif on_edit and response_id == Gtk.ResponseType.NO: # Remove # Cleanup the entry from the ignore list by ensuring that # it's enabled in its last moments... self.on_row_changed( self.current_edit_informations["row"], os.path.basename(self.current_edit_informations["desktop"].filename), True ) # Finally, remove os.remove(self.current_edit_informations["desktop"].filename) self.current_edit_informations["row"].destroy() # Hide dialog.hide() # Cleanup self.objects.custom_name.set_text("") self.objects.custom_command.set_text("") self.current_edit_informations = {}
class shortcut: def __init__(self, dest, path, arguments, name=None, action=None, ttype=TargetType.FILESYSTEM): ''' :param dest: Path to resulting file on file system :param path: Path where the link should point to :param arguments: Arguemnts to eecutable file :param name: Name of the application :param type: Link type - FILESYSTEM or URL ''' self.dest = dest self.path = path self.expanded_path = None self.arguments = arguments self.name = name self.action = action self.changed = '' self.icon = None self.is_in_user_context = self.set_usercontext() self.type = ttype def __str__(self): result = self.to_json() return result def set_changed(self, change_date): ''' Set object change date ''' self.changed = change_date def set_clsid(self, clsid): self.clsid = clsid def set_guid(self, uid): self.guid = uid def set_icon(self, icon_name): self.icon = icon_name def set_type(self, ttype): ''' Set type of the hyperlink - FILESYSTEM or URL :ttype: - object of class TargetType ''' self.type = ttype def set_usercontext(self, usercontext=False): ''' Perform action in user context or not ''' ctx = False if usercontext in [1, '1', True]: ctx = True self.is_in_user_context = ctx def set_expanded_path(self, path): ''' Adjust shortcut path with expanding windows variables ''' self.expanded_path = path def is_usercontext(self): return self.is_in_user_context def to_json(self): ''' Return shortcut's JSON for further serialization. ''' content = dict() content['dest'] = self.dest content['path'] = self.path content['name'] = self.name content['arguments'] = self.arguments content['clsid'] = self.clsid content['guid'] = self.guid content['changed'] = self.changed content['action'] = self.action content['is_in_user_context'] = self.is_in_user_context content['type'] = ttype2str(self.type) if self.icon: content['icon'] = self.icon result = self.desktop() result.content.update(content) return json.dumps(result.content) def desktop(self, dest=None): ''' Returns desktop file object which may be written to disk. ''' if dest: self.desktop_file = DesktopEntry(dest) else: self.desktop_file = DesktopEntry() self.desktop_file.addGroup('Desktop Entry') self.desktop_file.set('Version', '1.0') self._update_desktop() return self.desktop_file def _update_desktop(self): ''' Update desktop file object from internal data. ''' if self.type == TargetType.URL: self.desktop_file.set('Type', 'Link') else: self.desktop_file.set('Type', 'Application') self.desktop_file.set('Name', self.name) desktop_path = self.path if self.expanded_path: desktop_path = self.expanded_path if self.type == TargetType.URL: self.desktop_file.set('URL', desktop_path) else: self.desktop_file.set('Terminal', 'false') self.desktop_file.set('Exec', '{} {}'.format(desktop_path, self.arguments)) if self.icon: self.desktop_file.set('Icon', self.icon) def _write_desktop(self, dest, create_only=False, read_firstly=False): ''' Write .desktop file to disk using path 'dest'. Please note that .desktop files must have executable bit set in order to work in GUI. ''' sc = Path(dest) if sc.exists() and create_only: return if sc.exists() and read_firstly: self.desktop(dest).write(dest) else: self.desktop().write(dest) sc.chmod(sc.stat().st_mode | stat.S_IEXEC) def _remove_desktop(self, dest): ''' Remove .desktop file fromo disk using path 'dest'. ''' sc = Path(dest) if sc.exists(): sc.unlink() def apply_desktop(self, dest): ''' Apply .desktop file by action. ''' if self.action == 'U': self._write_desktop(dest, read_firstly=True) elif self.action == 'D': self._remove_desktop(dest) elif self.action == 'R': self._remove_desktop(dest) self._write_desktop(dest) elif self.action == 'C': self._write_desktop(dest, create_only=True)
def _create_desktop_file_from_command(self, command): basename = os.path.basename(command) path = os.path.expanduser('~/.local/share/applications/%s.desktop' % basename) desktop = DesktopEntry() desktop.addGroup('Desktop Entry') desktop.set('Type', 'Application') desktop.set('Version', '1.0') desktop.set('Terminal', 'false') desktop.set('Exec', command) desktop.set('Name', basename) desktop.set('X-Ubuntu-Tweak', 'true') desktop.write(path) return '%s.desktop' % basename
def on_add_item(self, widget, treeview): dialog = AutoStartDialog(parent = widget.get_toplevel()) if dialog.run() == gtk.RESPONSE_OK: name = dialog.pm_name.get_text() cmd = dialog.pm_cmd.get_text() if not name: ErrorDialog(_("The name of the startup program cannot be empty")).launch() elif not cmd: ErrorDialog(_("Text was empty (or contained only whitespace)")).launch() else: path = os.path.join(treeview.userdir, os.path.basename(cmd) + ".desktop") desktopentry = DesktopEntry(path) desktopentry.set("Name", dialog.pm_name.get_text()) desktopentry.set("Exec", dialog.pm_cmd.get_text()) desktopentry.set("Comment", dialog.pm_comment.get_text()) desktopentry.set("Type", "Application") desktopentry.set("Version", "1.0") desktopentry.set("X-GNOME-Autostart-enabled", "true") desktopentry.write() treeview.update_items(all = self.show_all_button.get_active(), comment = self.show_comment_button.get_active()) dialog.destroy() return dialog.destroy()
os.path.join(source_dir, translation)) catalog = TranslationCatalog("./po/vera-control-center") # Search for desktop files desktop_files = [] for directory, dirnames, filenames in os.walk("."): for file_ in filenames: if file_.endswith(".desktop"): entry = DesktopEntry(os.path.join(directory, file_)) for key in ("Name", "Comment", "Keywords"): try: source = entry.get(key) except: continue for lang, obj in TranslationCatalog.languages.items(): found = obj.find(source) if found and found.msgstr != "": # xdg's IniFile supports the locale= keyword, # but it supports only a boolean value. The locale # is hardcoded to the one of the current system. # We workaround this by specifying the right key # right now. entry.set("%s[%s]" % (key, lang), found.msgstr) entry.write()
def install_freedesktop_menuitem(game: Game): icon = os.path.join(game.install_dir, "support/icon.png") play = os.path.join(game.install_dir, "start.sh") # create a new desktop entry entry_name = re.sub('[^A-Za-z0-9_]+', '', game.name.replace(" ", "_")) fpath = os.path.join( Path.home(), ".local/share/applications/gog_com-" + entry_name + ".desktop") entry = DesktopEntry(fpath) entry.set("Encoding", "UTF-8") entry.set("Value", "1.0") entry.set("Type", "Application") entry.set("Name", game.name) entry.set("GenericName", game.name) entry.set("Comment", game.name) entry.set("Icon", icon) entry.set("Exec", "\"" + play + "\" \"\"") entry.set("Categories", "Game;") entry.set("Path", game.install_dir) entry.write(fpath, True)
def create_desktop_file(profile: Profile) -> None: desktop = DesktopEntry(str(application_dir / f"{profile.name}.desktop")) desktop.set("Name", f"{profile.name} (qutebrowser profile)") # TODO allow passing in an icon value desktop.set("Icon", "qutebrowser") desktop.set("Exec", " ".join(profile.cmdline()) + " %u") desktop.set("Categories", ["Network"]) desktop.set("Terminal", False) desktop.set("StartupNotify", True) desktop.write()
class shortcut: def __init__(self, dest, path, arguments, name=None): self.dest = dest self.path = path self.arguments = arguments self.name = name self.changed = '' self.is_in_user_context = self.set_usercontext() def __str__(self): result = self.to_json() return result def set_changed(self, change_date): ''' Set object change date ''' self.changed = change_date def set_clsid(self, clsid): self.clsid = clsid def set_guid(self, uid): self.guid = uid def set_usercontext(self, usercontext=False): ''' Perform action in user context or not ''' ctx = False if usercontext in [1, '1', True]: ctx = True self.is_in_user_context = ctx def is_usercontext(self): return self.is_in_user_context def to_json(self): ''' Return shortcut's JSON for further serialization. ''' content = dict() content['dest'] = self.dest content['path'] = self.path content['name'] = self.name content['arguments'] = self.arguments content['clsid'] = self.clsid content['guid'] = self.guid content['changed'] = self.changed content['is_in_user_context'] = self.is_in_user_context result = self.desktop() result.content.update(content) return json.dumps(result.content) def desktop(self): ''' Returns desktop file object which may be written to disk. ''' self.desktop_file = DesktopEntry() self.desktop_file.addGroup('Desktop Entry') self.desktop_file.set('Type', 'Application') self.desktop_file.set('Version', '1.0') self.desktop_file.set('Terminal', 'false') self.desktop_file.set('Exec', '{} {}'.format(self.path, self.arguments)) self.desktop_file.set('Name', self.name) return self.desktop_file def write_desktop(self, dest): ''' Write .desktop file to disk using path 'dest' ''' self.desktop().write(dest)
def on_add_new_custom_dialog_response(self, dialog, response_id): """ Fired when the user triggered a response on the add_new_custom_dialog. """ # Clunky way to see if we have edit mode, but it works on_edit = dialog.get_widget_for_response( Gtk.ResponseType.NO).props.visible if not on_edit and response_id == Gtk.ResponseType.OK: # Obtain a working filename directory = os.path.expanduser("~/.config/autostart") if not os.path.exists(directory): os.makedirs(directory) filename = os.path.join( directory, self.objects.custom_name.get_text().lower().replace(" ", "-") + ".custom%s.desktop" % (random.randint(0, 1000), )) if os.path.exists(filename): return on_add_new_custom_dialog_response(dialog, response_id) desktop_basename = os.path.basename(filename) entry = DesktopEntry(filename) entry.set("Version", 1.0) entry.set("Name", self.objects.custom_name.get_text()) entry.set("Exec", self.objects.custom_command.get_text()) entry.set("X-Vera-Autostart-Phase", "Other") entry.write() row = ApplicationRow(desktop_basename, entry) # Connect the changed signal row.connect("changed", self.on_row_changed) # Connect the requests_edit signal row.connect("requests_edit", self.on_row_requests_edit) # Prepend the row self.objects.list.prepend(row) self.desktop_list.append(desktop_basename) elif on_edit and response_id == Gtk.ResponseType.OK: # Edit self.current_edit_informations["desktop"].set( "Name", self.objects.custom_name.get_text(), locale=True) self.current_edit_informations["desktop"].set( "Exec", self.objects.custom_command.get_text()) self.current_edit_informations["desktop"].write() self.current_edit_informations["row"].name.set_text( self.objects.custom_name.get_text()) elif on_edit and response_id == Gtk.ResponseType.NO: # Remove # Cleanup the entry from the ignore list by ensuring that # it's enabled in its last moments... self.on_row_changed( self.current_edit_informations["row"], os.path.basename( self.current_edit_informations["desktop"].filename), True) # Finally, remove os.remove(self.current_edit_informations["desktop"].filename) self.current_edit_informations["row"].destroy() # Hide dialog.hide() # Cleanup self.objects.custom_name.set_text("") self.objects.custom_command.set_text("") self.current_edit_informations = {}
language = translation.replace(".po","") self.languages[language] = polib.pofile(os.path.join(source_dir, translation)) catalog = TranslationCatalog("./po/vera-control-center-module-updates") # Search for desktop files desktop_files = [] for directory, dirnames, filenames in os.walk("."): for file_ in filenames: if file_.endswith(".desktop"): entry = DesktopEntry(os.path.join(directory, file_)) for key in ("Name", "Comment", "Keywords"): try: source = entry.get(key) except: continue for lang, obj in TranslationCatalog.languages.items(): found = obj.find(source) if found and found.msgstr != "": # xdg's IniFile supports the locale= keyword, # but it supports only a boolean value. The locale # is hardcoded to the one of the current system. # We workaround this by specifying the right key # right now. entry.set("%s[%s]" % (key, lang), found.msgstr) entry.write()
def install_freedesktop_desktopitem(game: Game): icon = os.path.join(game.install_dir, "support/icon.png") play = os.path.join(game.install_dir, "start.sh") # create a new desktop entry entry_name = re.sub('[^A-Za-z0-9_]+', '', game.name.replace(" ", "_")) # find out desktop location cp = subprocess.run(["xdg-user-dir", "DESKTOP"], capture_output=True) desktop_dir = cp.stdout.decode().strip() + "/" fpath = os.path.join(desktop_dir, "gog_com-" + entry_name + ".desktop") entry = DesktopEntry(fpath) entry.set("Encoding", "UTF-8") entry.set("Value", "1.0") entry.set("Type", "Application") entry.set("Name", game.name) entry.set("GenericName", game.name) entry.set("Comment", game.name) entry.set("Icon", icon) entry.set("Exec", play) entry.set("Categories", "Game;") entry.set("Path", game.install_dir) entry.write(fpath, True)
class Autostart(gobject.GObject): __gsignals__ = { 'changed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_BOOLEAN, )), } def __init__(self): gobject.GObject.__init__(self) self.config = Config.Config(tgcm.country_support) # Determine the path for XDG autostart dirs self.autofile_name = 'tgcm-%s.desktop' % tgcm.country_support self.user_autodir = None for foo in BaseDirectory.load_config_paths('autostart'): if foo.startswith(os.path.expanduser('~')): self.user_autodir = foo else: self.system_autodir = foo self.__create_desktop_entry_if_necessary() # Listen to file changes myfile = gio.File(self.user_autofile) self.desktopentry_monitor = myfile.monitor_file() self.desktopentry_monitor.connect('changed', self.on_desktopentry_changed) def __create_desktop_entry_if_necessary(self): # Create user autostart dir if it does not exists if self.user_autodir is None: self.user_autodir = BaseDirectory.save_config_path('autostart') # It it does not exists an autostart file for TGCM in userdir, # create a copy from the global one self.user_autofile = os.path.join(self.user_autodir, self.autofile_name) if not os.path.exists(self.user_autofile): autofile_path = os.path.join(self.system_autodir, self.autofile_name) shutil.copy(autofile_path, self.user_autofile) # Honor 'launch-startup' policy in regional-info.xml file self.desktopentry = DesktopEntry(self.user_autofile) is_autostart = self.config.check_policy('launch-startup') self.set_enabled(is_autostart) else: self.desktopentry = DesktopEntry(self.user_autofile) def is_enabled(self): self.__create_desktop_entry_if_necessary() # Check if the DesktopEntry object has an autostart attribute if self.desktopentry.hasKey('X-GNOME-Autostart-enabled'): is_autostart = self.desktopentry.get('X-GNOME-Autostart-enabled', \ type='boolean') else: is_autostart = True if self.desktopentry.hasKey('Hidden'): is_shown = not self.desktopentry.get('Hidden', type='boolean') else: is_shown = True return is_shown and is_autostart def set_enabled(self, value): self.__create_desktop_entry_if_necessary() value = str(value).lower() self.desktopentry.set('X-GNOME-Autostart-enabled', value) self.desktopentry.removeKey('Hidden') self.desktopentry.write() def on_desktopentry_changed(self, monitor, myfile, other_file, event): if event == gio.FILE_MONITOR_EVENT_DELETED: self.__create_desktop_entry_if_necessary() is_enabled = self.is_enabled() self.emit('changed', is_enabled)
class Mapping(object): """ An object representation of a wiican mapping. A wiican mapping must be located in a single directory containing a file with the wminput code, a file containing the metadata (name, description, author, version) and an optional icon file. """ # Mandatory filename for the metadata file info_filename = "info.desktop" # Mandatory filename for the wminput config file mapping_filename = "mapping.wminput" def __init__(self, path=None): """ Builds a mapping object. Parameters: path - scans the path for building a mapping object if the needed files where found. If None it builds an empty mapping. If some of the needed files wasn't found it tries to build a mapping with the found info. The Mapping.info_filename and Mapping.mapping_filename class attributes marks the requiered filenames for the metadata file and wminput config file respectively. The Mapping.mapping_filename file must contain wminput config file code The Mapping.info_filename follows XDG DesktopEntry syntax. The Mapping.info_filename contains the source of the optional associated icon. If no icon found or no icon directive it falls back to default icon. There are three posibilities for icon setting: - An absolute path where the icon it's stored - Icon filename if it's stored in the same dir as Mapping.info_filename - Theme-icon-name for auto-getting the icon from the icon theme """ self.__path = path # Getting freedesktop definition file self.__info = DesktopEntry() if path and os.path.exists(os.path.join(path, Mapping.info_filename)): self.__info.parse(os.path.join(path, Mapping.info_filename)) else: self.__info.new(self.info_filename) self.__info.set("Type", "Wiican Mapping") # Getting wminput mapping file if path and os.path.exists(os.path.join(path, Mapping.mapping_filename)): mapping_fp = open(os.path.join(path, Mapping.mapping_filename), "r") self.__mapping = mapping_fp.read() mapping_fp.close() else: self.__mapping = "" # Getting icon file path icon_name = self.__info.getIcon() if path and icon_name in os.listdir(path): # Icon included self.set_icon(os.path.join(path, icon_name)) elif getIconPath(icon_name): # Theme icon self.set_icon(getIconPath(icon_name)) else: # Default icon self.set_icon(ICON_DEFAULT) def get_path(self): """Returns the absolute path where the wiican mapping it's saved. It returns None if the mapping it's not saved yet""" return self.__path def get_name(self): """Gets the name of the mapping""" return self.__info.getName() def set_name(self, name): """Sets the name for the mapping""" self.__info.set("Name", name) self.__info.set("Name", name, locale=True) def get_comment(self): """Gets the descriptional comment""" return self.__info.getComment() def set_comment(self, comment): """Sets the descriptional comment for the mapping""" self.__info.set("Comment", comment) self.__info.set("Comment", comment, locale=True) def get_icon(self): """ Gets the associated icon. If no icon found or no icon directive it falls back to default icon. """ icon_name = self.__info.getIcon() # Icon included if self.__path and icon_name in os.listdir(self.__path): return os.path.join(self.__path, icon_name) # Theme icon elif getIconPath(icon_name): return getIconPath(icon_name) # Default icon else: return ICON_DEFAULT def set_icon(self, icon_path): """ Sets the icon for the mapping. There are three posibilities for icon setting: - An absolute path where the icon it's stored - Icon filename if it's stored in the same dir as Mapping.info_filename - Theme-icon-name for auto-getting the icon from the icon theme """ self.__info.set("Icon", icon_path) def get_authors(self): """Gets the mapping author/s""" return self.__info.get("X-Authors") def set_authors(self, authors): """Sets the author/s for the mapping""" self.__info.set("X-Authors", authors) def get_version(self): """Gets the version of the mapping""" return self.__info.get("X-Version") def set_version(self, version): """Sets the version of the mapping""" self.__info.set("X-Version", version) def get_mapping(self): """Gets the wminput config code""" return self.__mapping def set_mapping(self, mapping): """Sets the wminput config code""" self.__mapping = mapping def write(self, dest_path=None): """ Saves the mapping object by writing the files in the mapping directory. The metadata it's saved in Mapping.info_filename file. The wminput config code it's saved in Mapping.mapping_filename file. The associated icon it's copied to the mapping directory. """ if not dest_path: if not self.__path: raise MappingError, _("No path provided for writing mapping") dest_path = self.__path elif not os.path.exists(dest_path): os.mkdir(dest_path) icon_path = self.get_icon() icon_filename = os.path.basename(icon_path) if not icon_path == os.path.join(dest_path, icon_filename): shutil.copy(icon_path, dest_path) self.set_icon(icon_filename) self.__info.write(os.path.join(dest_path, Mapping.info_filename)) mapping_fp = open(os.path.join(dest_path, Mapping.mapping_filename), "w") mapping_fp.write(self.__mapping) mapping_fp.close() # Clean not useful files for item in [ x for x in os.listdir(dest_path) if not x in [Mapping.info_filename, Mapping.mapping_filename, icon_filename] ]: os.unlink(os.path.join(dest_path, item)) self.__path = dest_path def __repr__(self): return "Mapping <" + self.__info.get("Name", locale=False) + " " + str(self.__info.getVersion()) + ">"
def get_or_create_desktop_file(): desktop = lookup_desktop_file('uroute.desktop') if desktop is None: path = os.path.join( xdg.BaseDirectory.xdg_data_home, 'applications', 'uroute.desktop', ) desktop = DesktopEntry(path) desktop.set('Version', '1.0') desktop.set('Name', 'Uroute') desktop.set('Comment', 'URL router.') desktop.set('Exec', 'uroute %U') desktop.set('StartupNotify', 'true') desktop.set('Terminal', 'false') desktop.set('Categories', 'Network;WebBrowser;') desktop.set( 'MimeType', ';'.join(( 'text/html', 'text/xml', 'application/xhtml_xml', 'application/xhtml+xml', 'image/webp', 'video/webp', 'x-scheme-handler/http', 'x-scheme-handler/https', 'x-scheme-handler/ftp', '' # End with a ; ))) desktop.write(trusted=True) log.debug('Created Uroute desktop entry at %s', path) return desktop