Update vendored pyxdg to 0.28

This commit is contained in:
Brian Sheldon 2022-11-28 06:15:51 -05:00
commit e60286ee3d
7 changed files with 95 additions and 66 deletions

View file

@ -43,6 +43,9 @@ xdg_config_dirs = [xdg_config_home] + \
xdg_cache_home = os.environ.get('XDG_CACHE_HOME') or \ xdg_cache_home = os.environ.get('XDG_CACHE_HOME') or \
os.path.join(_home, '.cache') os.path.join(_home, '.cache')
xdg_state_home = os.environ.get('XDG_STATE_HOME') or \
os.path.join(_home, '.local', 'state')
xdg_data_dirs = [x for x in xdg_data_dirs if x] xdg_data_dirs = [x for x in xdg_data_dirs if x]
xdg_config_dirs = [x for x in xdg_config_dirs if x] xdg_config_dirs = [x for x in xdg_config_dirs if x]
@ -81,6 +84,17 @@ def save_cache_path(*resource):
os.makedirs(path) os.makedirs(path)
return path return path
def save_state_path(*resource):
"""Ensure ``$XDG_STATE_HOME/<resource>/`` exists, and return its path.
'resource' should normally be the name of your application or a shared
resource."""
resource = os.path.join(*resource)
assert not resource.startswith('/')
path = os.path.join(xdg_state_home, resource)
if not os.path.isdir(path):
os.makedirs(path)
return path
def load_config_paths(*resource): def load_config_paths(*resource):
"""Returns an iterator which gives each directory named 'resource' in the """Returns an iterator which gives each directory named 'resource' in the
configuration search path. Information provided by earlier directories should configuration search path. Information provided by earlier directories should

View file

@ -56,38 +56,37 @@ class IniFile:
return return
# parse file # parse file
for line in fd: with fd:
line = line.strip() for line in fd:
# empty line line = line.strip()
if not line: # empty line
continue if not line:
# comment continue
elif line[0] == '#': # comment
continue elif line[0] == '#':
# new group continue
elif line[0] == '[': # new group
currentGroup = line.lstrip("[").rstrip("]") elif line[0] == '[':
if debug and self.hasGroup(currentGroup): currentGroup = line.lstrip("[").rstrip("]")
raise DuplicateGroupError(currentGroup, filename) if debug and self.hasGroup(currentGroup):
else: raise DuplicateGroupError(currentGroup, filename)
content[currentGroup] = {}
# key
else:
try:
key, value = line.split("=", 1)
except ValueError:
raise ParsingError("Invalid line: " + line, filename)
key = key.strip() # Spaces before/after '=' should be ignored
try:
if debug and self.hasKey(key, currentGroup):
raise DuplicateKeyError(key, currentGroup, filename)
else: else:
content[currentGroup][key] = value.strip() content[currentGroup] = {}
except (IndexError, UnboundLocalError): # key
raise ParsingError("Parsing error on key, group missing", filename) else:
try:
key, value = line.split("=", 1)
except ValueError:
raise ParsingError("Invalid line: " + line, filename)
fd.close() key = key.strip() # Spaces before/after '=' should be ignored
try:
if debug and self.hasKey(key, currentGroup):
raise DuplicateKeyError(key, currentGroup, filename)
else:
content[currentGroup][key] = value.strip()
except (IndexError, UnboundLocalError):
raise ParsingError("Parsing error on key, group missing", filename)
self.filename = filename self.filename = filename
self.tainted = False self.tainted = False

View file

@ -21,6 +21,7 @@ import os
import locale import locale
import subprocess import subprocess
import ast import ast
import sys
try: try:
import xml.etree.cElementTree as etree import xml.etree.cElementTree as etree
except ImportError: except ImportError:
@ -35,6 +36,17 @@ import xdg.Locale
import xdg.Config import xdg.Config
def _ast_const(name):
if sys.version_info >= (3, 4):
name = ast.literal_eval(name)
if sys.version_info >= (3, 8):
return ast.Constant(name)
else:
return ast.NameConstant(name)
else:
return ast.Name(id=name, ctx=ast.Load())
def _strxfrm(s): def _strxfrm(s):
"""Wrapper around locale.strxfrm that accepts unicode strings on Python 2. """Wrapper around locale.strxfrm that accepts unicode strings on Python 2.
@ -298,11 +310,11 @@ class Menu:
entry.Show = NO_EXEC entry.Show = NO_EXEC
self.Visible -= 1 self.Visible -= 1
elif xdg.Config.windowmanager: elif xdg.Config.windowmanager:
if (entry.DesktopEntry.OnlyShowIn != [] and ( if (entry.DesktopEntry.getOnlyShowIn() != [] and (
xdg.Config.windowmanager not in entry.DesktopEntry.OnlyShowIn xdg.Config.windowmanager not in entry.DesktopEntry.getOnlyShowIn()
) )
) or ( ) or (
xdg.Config.windowmanager in entry.DesktopEntry.NotShowIn xdg.Config.windowmanager in entry.DesktopEntry.getNotShowIn()
): ):
entry.Show = NOT_SHOW_IN entry.Show = NOT_SHOW_IN
self.Visible -= 1 self.Visible -= 1
@ -710,11 +722,12 @@ class XMLMenuBuilder(object):
inline_header=_to_bool(node.attrib.get("inline_header", True)), inline_header=_to_bool(node.attrib.get("inline_header", True)),
inline_alias=_to_bool(node.attrib.get("inline_alias", False)) inline_alias=_to_bool(node.attrib.get("inline_alias", False))
) )
order = []
for child in node: for child in node:
tag, text = child.tag, child.text tag, text = child.tag, child.text
text = text.strip() if text else None text = text.strip() if text else None
if tag == "Menuname" and text: if tag == "Menuname" and text:
layout.order.append([ order.append([
"Menuname", "Menuname",
text, text,
_to_bool(child.attrib.get("show_empty", False)), _to_bool(child.attrib.get("show_empty", False)),
@ -724,14 +737,15 @@ class XMLMenuBuilder(object):
_to_bool(child.attrib.get("inline_alias", False)) _to_bool(child.attrib.get("inline_alias", False))
]) ])
elif tag == "Separator": elif tag == "Separator":
layout.order.append(['Separator']) order.append(['Separator'])
elif tag == "Filename" and text: elif tag == "Filename" and text:
layout.order.append(["Filename", text]) order.append(["Filename", text])
elif tag == "Merge": elif tag == "Merge":
layout.order.append([ order.append([
"Merge", "Merge",
child.attrib.get("type", "all") child.attrib.get("type", "all")
]) ])
layout.order = order
return layout return layout
def parse_move(self, node): def parse_move(self, node):
@ -754,7 +768,7 @@ class XMLMenuBuilder(object):
if expr: if expr:
tree.body = expr tree.body = expr
else: else:
tree.body = ast.Name('False', ast.Load()) tree.body = _ast_const('False')
ast.fix_missing_locations(tree) ast.fix_missing_locations(tree)
return Rule(type, tree) return Rule(type, tree)
@ -781,7 +795,7 @@ class XMLMenuBuilder(object):
expr = self.parse_bool_op(node, ast.Or()) expr = self.parse_bool_op(node, ast.Or())
return ast.UnaryOp(ast.Not(), expr) if expr else None return ast.UnaryOp(ast.Not(), expr) if expr else None
elif tag == 'All': elif tag == 'All':
return ast.Name('True', ast.Load()) return _ast_const('True')
elif tag == 'Category': elif tag == 'Category':
category = node.text category = node.text
return ast.Compare( return ast.Compare(
@ -994,8 +1008,8 @@ class XMLMenuBuilder(object):
menuentry = MenuEntry(directory, dir) menuentry = MenuEntry(directory, dir)
if not menu.Directory: if not menu.Directory:
menu.Directory = menuentry menu.Directory = menuentry
elif menuentry.Type == MenuEntry.TYPE_SYSTEM: elif menuentry.getType() == MenuEntry.TYPE_SYSTEM:
if menu.Directory.Type == MenuEntry.TYPE_USER: if menu.Directory.getType() == MenuEntry.TYPE_USER:
menu.Directory.Original = menuentry menu.Directory.Original = menuentry
if menu.Directory: if menu.Directory:
break break

View file

@ -54,7 +54,7 @@ class MenuEditor(object):
try: try:
self.tree = etree.parse(self.filename) self.tree = etree.parse(self.filename)
except IOError: except IOError:
root = etree.fromtring(""" root = etree.fromstring("""
<!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" "http://standards.freedesktop.org/menu-spec/menu-1.0.dtd"> <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" "http://standards.freedesktop.org/menu-spec/menu-1.0.dtd">
<Menu> <Menu>
<Name>Applications</Name> <Name>Applications</Name>

View file

@ -749,14 +749,16 @@ def install_mime_info(application, package_file):
file with the same name (if the contents are different)""" file with the same name (if the contents are different)"""
application += '.xml' application += '.xml'
new_data = open(package_file).read() with open(package_file) as f:
new_data = f.read()
# See if the file is already installed # See if the file is already installed
package_dir = os.path.join('mime', 'packages') package_dir = os.path.join('mime', 'packages')
resource = os.path.join(package_dir, application) resource = os.path.join(package_dir, application)
for x in BaseDirectory.load_data_paths(resource): for x in BaseDirectory.load_data_paths(resource):
try: try:
old_data = open(x).read() with open(x) as f:
old_data = f.read()
except: except:
continue continue
if old_data == new_data: if old_data == new_data:
@ -770,7 +772,8 @@ def install_mime_info(application, package_file):
new_file = os.path.join(BaseDirectory.save_data_path(package_dir), application) new_file = os.path.join(BaseDirectory.save_data_path(package_dir), application)
# Write the file... # Write the file...
open(new_file, 'w').write(new_data) with open(new_file, 'w') as f:
f.write(new_data)
# Update the database... # Update the database...
command = 'update-mime-database' command = 'update-mime-database'

View file

@ -71,28 +71,27 @@ class RecentFiles:
elif not filename: elif not filename:
filename = self.filename filename = self.filename
f = open(filename, "w") with open(filename, "w") as f:
fcntl.lockf(f, fcntl.LOCK_EX) fcntl.lockf(f, fcntl.LOCK_EX)
f.write('<?xml version="1.0"?>\n') f.write('<?xml version="1.0"?>\n')
f.write("<RecentFiles>\n") f.write("<RecentFiles>\n")
for r in self.RecentFiles: for r in self.RecentFiles:
f.write(" <RecentItem>\n") f.write(" <RecentItem>\n")
f.write(" <URI>%s</URI>\n" % xml.sax.saxutils.escape(r.URI)) f.write(" <URI>%s</URI>\n" % xml.sax.saxutils.escape(r.URI))
f.write(" <Mime-Type>%s</Mime-Type>\n" % r.MimeType) f.write(" <Mime-Type>%s</Mime-Type>\n" % r.MimeType)
f.write(" <Timestamp>%s</Timestamp>\n" % r.Timestamp) f.write(" <Timestamp>%s</Timestamp>\n" % r.Timestamp)
if r.Private == True: if r.Private == True:
f.write(" <Private/>\n") f.write(" <Private/>\n")
if len(r.Groups) > 0: if len(r.Groups) > 0:
f.write(" <Groups>\n") f.write(" <Groups>\n")
for group in r.Groups: for group in r.Groups:
f.write(" <Group>%s</Group>\n" % group) f.write(" <Group>%s</Group>\n" % group)
f.write(" </Groups>\n") f.write(" </Groups>\n")
f.write(" </RecentItem>\n") f.write(" </RecentItem>\n")
f.write("</RecentFiles>\n") f.write("</RecentFiles>\n")
fcntl.lockf(f, fcntl.LOCK_UN) fcntl.lockf(f, fcntl.LOCK_UN)
f.close()
def getFiles(self, mimetypes=None, groups=None, limit=0): def getFiles(self, mimetypes=None, groups=None, limit=0):
"""Get a list of recently used files. """Get a list of recently used files.

View file

@ -1,3 +1,3 @@
__all__ = [ "BaseDirectory", "DesktopEntry", "Menu", "Exceptions", "IniFile", "IconTheme", "Locale", "Config", "Mime", "RecentFiles", "MenuEditor" ] __all__ = [ "BaseDirectory", "DesktopEntry", "Menu", "Exceptions", "IniFile", "IconTheme", "Locale", "Config", "Mime", "RecentFiles", "MenuEditor" ]
__version__ = "0.26" __version__ = "0.28"