home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.6) ''' Implementation of the XDG Menu Specification Version 1.0.draft-1 http://standards.freedesktop.org/menu-spec/ ''' from __future__ import generators import locale import os import xml.dom.minidom as xml from xdg.BaseDirectory import * from xdg.DesktopEntry import * from xdg.Exceptions import * import xdg.Locale as xdg import xdg.Config as xdg ELEMENT_NODE = xml.dom.Node.ELEMENT_NODE class Menu: def __init__(self): self.Name = '' self.Directory = None self.Entries = [] self.Doc = '' self.Filename = '' self.Depth = 0 self.Parent = None self.NotInXml = False self.Show = True self.Visible = 0 self.AppDirs = [] self.DefaultLayout = None self.Deleted = 'notset' self.Directories = [] self.DirectoryDirs = [] self.Layout = None self.MenuEntries = [] self.Moves = [] self.OnlyUnallocated = 'notset' self.Rules = [] self.Submenus = [] def __str__(self): return self.Name def __add__(self, other): for dir in other.AppDirs: self.AppDirs.append(dir) for dir in other.DirectoryDirs: self.DirectoryDirs.append(dir) for directory in other.Directories: self.Directories.append(directory) if other.Deleted != 'notset': self.Deleted = other.Deleted if other.OnlyUnallocated != 'notset': self.OnlyUnallocated = other.OnlyUnallocated if other.Layout: self.Layout = other.Layout if other.DefaultLayout: self.DefaultLayout = other.DefaultLayout for rule in other.Rules: self.Rules.append(rule) for move in other.Moves: self.Moves.append(move) for submenu in other.Submenus: self.addSubmenu(submenu) return self def __cmp__(self, other): return locale.strcoll(self.getName(), other.getName()) def __eq__(self, other): if self.Name == str(other): return True return False def getEntries(self, hidden = False): for entry in self.Entries: if hidden == True: yield entry continue if entry.Show == True: yield entry continue def getMenuEntry(self, desktopfileid, deep = False): for menuentry in self.MenuEntries: if menuentry.DesktopFileID == desktopfileid: return menuentry if deep == True: for submenu in self.Submenus: submenu.getMenuEntry(desktopfileid, deep) def getMenu(self, path): array = path.split('/', 1) for submenu in self.Submenus: if submenu.Name == array[0]: if len(array) > 1: return submenu.getMenu(array[1]) return submenu submenu.Name == array[0] def getPath(self, org = False, toplevel = False): parent = self names = [] while org: names.append(parent.Name) names.append(parent.getName()) if parent.Depth > 0: parent = parent.Parent continue break continue names.reverse() path = '' if toplevel == False: names.pop(0) for name in names: path = os.path.join(path, name) return path def getName(self): try: return self.Directory.DesktopEntry.getName() except AttributeError: return self.Name def getGenericName(self): try: return self.Directory.DesktopEntry.getGenericName() except AttributeError: return '' def getComment(self): try: return self.Directory.DesktopEntry.getComment() except AttributeError: return '' def getIcon(self): try: return self.Directory.DesktopEntry.getIcon() except AttributeError: return '' def addSubmenu(self, newmenu): for submenu in self.Submenus: if submenu == newmenu: submenu += newmenu break continue else: newmenu.Parent = self newmenu.Depth = self.Depth + 1 class Move: '''A move operation''' def __init__(self, node = None): if node: self.parseNode(node) else: self.Old = '' self.New = '' def __cmp__(self, other): return cmp(self.Old, other.Old) def parseNode(self, node): for child in node.childNodes: if child.nodeType == ELEMENT_NODE: if child.tagName == 'Old': try: self.parseOld(child.childNodes[0].nodeValue) except IndexError: raise ValidationError('Old cannot be empty', '??') except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError if child.tagName == 'New': try: self.parseNew(child.childNodes[0].nodeValue) except IndexError: raise ValidationError('New cannot be empty', '??') except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError continue def parseOld(self, value): self.Old = value def parseNew(self, value): self.New = value class Layout: '''Menu Layout class''' def __init__(self, node = None): self.order = [] if node: if not node.getAttribute('show_empty'): pass self.show_empty = 'false' if not node.getAttribute('inline'): pass self.inline = 'false' if not node.getAttribute('inline_limit'): pass self.inline_limit = 4 if not node.getAttribute('inline_header'): pass self.inline_header = 'true' if not node.getAttribute('inline_alias'): pass self.inline_alias = 'false' self.inline_limit = int(self.inline_limit) self.parseNode(node) else: self.show_empty = 'false' self.inline = 'false' self.inline_limit = 4 self.inline_header = 'true' self.inline_alias = 'false' self.order.append([ 'Merge', 'menus']) self.order.append([ 'Merge', 'files']) def parseNode(self, node): for child in node.childNodes: if child.nodeType == ELEMENT_NODE: if child.tagName == 'Menuname': try: if not child.getAttribute('show_empty'): pass if not child.getAttribute('inline'): pass if not child.getAttribute('inline_limit'): pass if not child.getAttribute('inline_header'): pass if not child.getAttribute('inline_alias'): pass self.parseMenuname(child.childNodes[0].nodeValue, 'false', 'false', 4, 'true', 'false') except IndexError: raise ValidationError('Menuname cannot be empty', '') except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError if child.tagName == 'Separator': self.parseSeparator() elif child.tagName == 'Filename': try: self.parseFilename(child.childNodes[0].nodeValue) except IndexError: raise ValidationError('Filename cannot be empty', '') except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError if child.tagName == 'Merge': if not child.getAttribute('type'): pass self.parseMerge('all') child.tagName == 'Merge' def parseMenuname(self, value, empty = 'false', inline = 'false', inline_limit = 4, inline_header = 'true', inline_alias = 'false'): self.order.append([ 'Menuname', value, empty, inline, inline_limit, inline_header, inline_alias]) self.order[-1][4] = int(self.order[-1][4]) def parseSeparator(self): self.order.append([ 'Separator']) def parseFilename(self, value): self.order.append([ 'Filename', value]) def parseMerge(self, type = 'all'): self.order.append([ 'Merge', type]) class Rule: '''Inlcude / Exclude Rules Class''' def __init__(self, type, node = None): self.Type = type self.Rule = '' self.Depth = 0 self.Expr = [ 'or'] self.New = True if node: self.parseNode(node) self.compile() def __str__(self): return self.Rule def compile(self): exec '\ndef do(menuentries, type, run):\n for menuentry in menuentries:\n\t\tif run == 2 and ( menuentry.MatchedInclude == True \t\tor menuentry.Allocated == True ):\n\t\t\tcontinue\n\t\telif %s:\n\t\t if type == "Include":\n\t\t\t\tmenuentry.Add = True\n\t\t\t\tmenuentry.MatchedInclude = True\n\t\t else:\n\t\t\t\tmenuentry.Add = False\n return menuentries\n' % self.Rule in self.__dict__ def parseNode(self, node): for child in node.childNodes: if child.nodeType == ELEMENT_NODE: if child.tagName == 'Filename': try: self.parseFilename(child.childNodes[0].nodeValue) except IndexError: raise ValidationError('Filename cannot be empty', '???') except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError if child.tagName == 'Category': try: self.parseCategory(child.childNodes[0].nodeValue) except IndexError: raise ValidationError('Category cannot be empty', '???') except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError if child.tagName == 'All': self.parseAll() elif child.tagName == 'And': self.parseAnd(child) elif child.tagName == 'Or': self.parseOr(child) elif child.tagName == 'Not': self.parseNot(child) child.tagName == 'All' def parseNew(self, set = True): if not self.New: self.Rule += ' ' + self.Expr[self.Depth] + ' ' if not set: self.New = True elif set: self.New = False def parseFilename(self, value): self.parseNew() self.Rule += "menuentry.DesktopFileID == '%s'" % value.strip().replace('\\', '\\\\').replace("'", "\\'") def parseCategory(self, value): self.parseNew() self.Rule += "'%s' in menuentry.Categories" % value.strip() def parseAll(self): self.parseNew() self.Rule += 'True' def parseAnd(self, node): self.parseNew(False) self.Rule += '(' self.Depth += 1 self.Expr.append('and') self.parseNode(node) self.Depth -= 1 self.Expr.pop() self.Rule += ')' def parseOr(self, node): self.parseNew(False) self.Rule += '(' self.Depth += 1 self.Expr.append('or') self.parseNode(node) self.Depth -= 1 self.Expr.pop() self.Rule += ')' def parseNot(self, node): self.parseNew(False) self.Rule += 'not (' self.Depth += 1 self.Expr.append('or') self.parseNode(node) self.Depth -= 1 self.Expr.pop() self.Rule += ')' class MenuEntry: """Wrapper for 'Menu Style' Desktop Entries""" def __init__(self, filename, dir = '', prefix = ''): self.DesktopEntry = DesktopEntry(os.path.join(dir, filename)) self.setAttributes(filename, dir, prefix) self.Show = True self.Original = None self.Parents = [] self.Allocated = False self.Add = False self.MatchedInclude = False self.Categories = self.DesktopEntry.getCategories() def save(self): if self.DesktopEntry.tainted == True: self.DesktopEntry.write() def getDir(self): return self.DesktopEntry.filename.replace(self.Filename, '') def getType(self): if xdg.Config.root_mode == False: if self.Original: return 'Both' if xdg_data_dirs[0] in self.DesktopEntry.filename: return 'User' return 'System' xdg.Config.root_mode == False return 'User' def setAttributes(self, filename, dir = '', prefix = ''): self.Filename = filename self.Prefix = prefix self.DesktopFileID = os.path.join(prefix, filename).replace('/', '-') if not os.path.isabs(self.DesktopEntry.filename): self._MenuEntry__setFilename() def updateAttributes(self): if self.getType() == 'System': self.Original = MenuEntry(self.Filename, self.getDir(), self.Prefix) self._MenuEntry__setFilename() def __setFilename(self): if xdg.Config.root_mode == False: path = xdg_data_dirs[0] else: path = xdg_data_dirs[1] if self.DesktopEntry.getType() == 'Application': dir = os.path.join(path, 'applications') else: dir = os.path.join(path, 'desktop-directories') self.DesktopEntry.filename = os.path.join(dir, self.Filename) def __cmp__(self, other): return locale.strcoll(self.DesktopEntry.getName(), other.DesktopEntry.getName()) def __eq__(self, other): if self.DesktopFileID == str(other): return True return False def __repr__(self): return self.DesktopFileID class Separator: '''Just a dummy class for Separators''' def __init__(self, parent): self.Parent = parent self.Show = True class Header: '''Class for Inline Headers''' def __init__(self, name, generic_name, comment): self.Name = name self.GenericName = generic_name self.Comment = comment def __str__(self): return self.Name tmp = { } def __getFileName(filename): dirs = xdg_config_dirs[:] if xdg.Config.root_mode == True: dirs.pop(0) for dir in dirs: menuname = os.path.join(dir, 'menus', filename) if os.path.isdir(dir) and os.path.isfile(menuname): return menuname def parse(filename = None): if filename and not os.path.isabs(filename): filename = __getFileName(filename) if not filename: filename = __getFileName('applications.menu') if not filename: raise ParsingError('File not found', '/etc/xdg/menus/applications.menu') filename if not os.path.splitext(filename)[1] == '.menu': raise ParsingError('Not a .menu file', filename) os.path.splitext(filename)[1] == '.menu' try: doc = xml.dom.minidom.parse(filename) except xml.parsers.expat.ExpatError: raise ParsingError('Not a valid .menu file', filename) tmp['Root'] = '' tmp['mergeFiles'] = [] tmp['DirectoryDirs'] = [] tmp['cache'] = MenuEntryCache() __parse(doc, filename, tmp['Root']) __parsemove(tmp['Root']) __postparse(tmp['Root']) tmp['Root'].Doc = doc tmp['Root'].Filename = filename __genmenuNotOnlyAllocated(tmp['Root']) __genmenuOnlyAllocated(tmp['Root']) sort(tmp['Root']) return tmp['Root'] def __parse(node, filename, parent = None): for child in node.childNodes: if child.nodeType == ELEMENT_NODE: if child.tagName == 'Menu': __parseMenu(child, filename, parent) elif child.tagName == 'AppDir': try: __parseAppDir(child.childNodes[0].nodeValue, filename, parent) except IndexError: raise ValidationError('AppDir cannot be empty', filename) except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError if child.tagName == 'DefaultAppDirs': __parseDefaultAppDir(filename, parent) elif child.tagName == 'DirectoryDir': try: __parseDirectoryDir(child.childNodes[0].nodeValue, filename, parent) except IndexError: raise ValidationError('DirectoryDir cannot be empty', filename) except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError if child.tagName == 'DefaultDirectoryDirs': __parseDefaultDirectoryDir(filename, parent) elif child.tagName == 'Name': try: parent.Name = child.childNodes[0].nodeValue except IndexError: raise ValidationError('Name cannot be empty', filename) except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError if child.tagName == 'Directory': try: parent.Directories.append(child.childNodes[0].nodeValue) except IndexError: raise ValidationError('Directory cannot be empty', filename) except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError if child.tagName == 'OnlyUnallocated': parent.OnlyUnallocated = True elif child.tagName == 'NotOnlyUnallocated': parent.OnlyUnallocated = False elif child.tagName == 'Deleted': parent.Deleted = True elif child.tagName == 'NotDeleted': parent.Deleted = False elif child.tagName == 'Include' or child.tagName == 'Exclude': parent.Rules.append(Rule(child.tagName, child)) elif child.tagName == 'MergeFile': try: if child.getAttribute('type') == 'parent': __parseMergeFile('applications.menu', child, filename, parent) else: __parseMergeFile(child.childNodes[0].nodeValue, child, filename, parent) except IndexError: raise ValidationError('MergeFile cannot be empty', filename) except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError if child.tagName == 'MergeDir': try: __parseMergeDir(child.childNodes[0].nodeValue, child, filename, parent) except IndexError: raise ValidationError('MergeDir cannot be empty', filename) except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError if child.tagName == 'DefaultMergeDirs': __parseDefaultMergeDirs(child, filename, parent) elif child.tagName == 'Move': parent.Moves.append(Move(child)) elif child.tagName == 'Layout': if len(child.childNodes) > 1: parent.Layout = Layout(child) elif child.tagName == 'DefaultLayout': if len(child.childNodes) > 1: parent.DefaultLayout = Layout(child) elif child.tagName == 'LegacyDir': try: __parseLegacyDir(child.childNodes[0].nodeValue, child.getAttribute('prefix'), filename, parent) except IndexError: raise ValidationError('LegacyDir cannot be empty', filename) except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError if child.tagName == 'KDELegacyDirs': __parseKDELegacyDirs(filename, parent) child.tagName == 'KDELegacyDirs' def __parsemove(menu): for submenu in menu.Submenus: __parsemove(submenu) for move in menu.Moves: move_from_menu = menu.getMenu(move.Old) if move_from_menu: move_to_menu = menu.getMenu(move.New) menus = move.New.split('/') oldparent = None while len(menus) > 0: if not oldparent: oldparent = menu newmenu = oldparent.getMenu(menus[0]) if not newmenu: newmenu = Menu() newmenu.Name = menus[0] if len(menus) > 1: newmenu.NotInXml = True oldparent.addSubmenu(newmenu) oldparent = newmenu menus.pop(0) newmenu += move_from_menu move_from_menu.Parent.Submenus.remove(move_from_menu) continue def __postparse(menu): if menu.Deleted == 'notset': menu.Deleted = False if menu.OnlyUnallocated == 'notset': menu.OnlyUnallocated = False if not (menu.Layout) or not (menu.DefaultLayout): if menu.DefaultLayout: menu.Layout = menu.DefaultLayout elif menu.Layout: if menu.Depth > 0: menu.DefaultLayout = menu.Parent.DefaultLayout else: menu.DefaultLayout = Layout() elif menu.Depth > 0: menu.Layout = menu.Parent.DefaultLayout menu.DefaultLayout = menu.Parent.DefaultLayout else: menu.Layout = Layout() menu.DefaultLayout = Layout() if menu.Depth > 0: menu.AppDirs = menu.Parent.AppDirs + menu.AppDirs menu.DirectoryDirs = menu.Parent.DirectoryDirs + menu.DirectoryDirs menu.Directories = __removeDuplicates(menu.Directories) menu.DirectoryDirs = __removeDuplicates(menu.DirectoryDirs) menu.AppDirs = __removeDuplicates(menu.AppDirs) for submenu in menu.Submenus: __postparse(submenu) menu.Directories.reverse() menu.DirectoryDirs.reverse() menu.AppDirs.reverse() for directory in menu.Directories: for dir in menu.DirectoryDirs: if os.path.isfile(os.path.join(dir, directory)): menuentry = MenuEntry(directory, dir) if not menu.Directory: menu.Directory = menuentry elif menuentry.getType() == 'System': if menu.Directory.getType() == 'User': menu.Directory.Original = menuentry menu.Directory if menu.Directory: break continue def __parseMenu(child, filename, parent): m = Menu() __parse(child, filename, m) if parent: parent.addSubmenu(m) else: tmp['Root'] = m def __check(value, filename, type): path = os.path.dirname(filename) if not os.path.isabs(value): value = os.path.join(path, value) value = os.path.abspath(value) if type == 'dir' and os.path.exists(value) and os.path.isdir(value): return value if type == 'file' and os.path.exists(value) and os.path.isfile(value): return value return False def __parseAppDir(value, filename, parent): value = __check(value, filename, 'dir') if value: parent.AppDirs.append(value) def __parseDefaultAppDir(filename, parent): for dir in reversed(xdg_data_dirs): __parseAppDir(os.path.join(dir, 'applications'), filename, parent) def __parseDirectoryDir(value, filename, parent): value = __check(value, filename, 'dir') if value: parent.DirectoryDirs.append(value) def __parseDefaultDirectoryDir(filename, parent): for dir in reversed(xdg_data_dirs): __parseDirectoryDir(os.path.join(dir, 'desktop-directories'), filename, parent) def __parseMergeFile(value, child, filename, parent): if child.getAttribute('type') == 'parent': for dir in xdg_config_dirs: rel_file = filename.replace(dir, '').strip('/') if rel_file != filename: for p in xdg_config_dirs: if dir == p: continue if os.path.isfile(os.path.join(p, rel_file)): __mergeFile(os.path.join(p, rel_file), child, parent) break continue else: value = __check(value, filename, 'file') if value: __mergeFile(value, child, parent) def __parseMergeDir(value, child, filename, parent): value = __check(value, filename, 'dir') if value: for item in os.listdir(value): try: if os.path.splitext(item)[1] == '.menu': __mergeFile(os.path.join(value, item), child, parent) continue except UnicodeDecodeError: continue continue def __parseDefaultMergeDirs(child, filename, parent): basename = os.path.splitext(os.path.basename(filename))[0] for dir in reversed(xdg_config_dirs): __parseMergeDir(os.path.join(dir, 'menus', basename + '-merged'), child, filename, parent) def __mergeFile(filename, child, parent): if filename in tmp['mergeFiles']: if debug: raise ParsingError('Infinite MergeFile loop detected', filename) debug return None filename in tmp['mergeFiles'] tmp['mergeFiles'].append(filename) try: doc = xml.dom.minidom.parse(filename) except IOError: if debug: raise ParsingError('File not found', filename) debug return None except xml.parsers.expat.ExpatError: if debug: raise ParsingError('Not a valid .menu file', filename) debug return None for child in doc.childNodes: if child.nodeType == ELEMENT_NODE: __parse(child, filename, parent) break continue def __parseLegacyDir(dir, prefix, filename, parent): m = __mergeLegacyDir(dir, prefix, filename, parent) if m: parent += m def __mergeLegacyDir(dir, prefix, filename, parent): dir = __check(dir, filename, 'dir') if dir and dir not in tmp['DirectoryDirs']: tmp['DirectoryDirs'].append(dir) m = Menu() m.AppDirs.append(dir) m.DirectoryDirs.append(dir) m.Name = os.path.basename(dir) m.NotInXml = True for item in os.listdir(dir): try: if item == '.directory': m.Directories.append(item) elif os.path.isdir(os.path.join(dir, item)): m.addSubmenu(__mergeLegacyDir(os.path.join(dir, item), prefix, filename, parent)) continue except UnicodeDecodeError: continue continue tmp['cache'].addMenuEntries([ dir], prefix, True) menuentries = tmp['cache'].getMenuEntries([ dir], False) for menuentry in menuentries: categories = menuentry.Categories if len(categories) == 0: r = Rule('Include') r.parseFilename(menuentry.DesktopFileID) r.compile() m.Rules.append(r) if dir not in parent.AppDirs: categories.append('Legacy') menuentry.Categories = categories continue return m def __parseKDELegacyDirs(filename, parent): f = os.popen3('kde-config --path apps') output = f[1].readlines() try: for dir in output[0].split(':'): __parseLegacyDir(dir, 'kde', filename, parent) except IndexError: pass def __removeDuplicates(list): set = { } list.reverse() list = _[1] list.reverse() return list def __genmenuNotOnlyAllocated(menu): for submenu in menu.Submenus: __genmenuNotOnlyAllocated(submenu) if menu.OnlyUnallocated == False: tmp['cache'].addMenuEntries(menu.AppDirs) menuentries = [] for rule in menu.Rules: menuentries = rule.do(tmp['cache'].getMenuEntries(menu.AppDirs), rule.Type, 1) for menuentry in menuentries: if menuentry.Add == True: menuentry.Parents.append(menu) menuentry.Add = False menuentry.Allocated = True menu.MenuEntries.append(menuentry) continue def __genmenuOnlyAllocated(menu): for submenu in menu.Submenus: __genmenuOnlyAllocated(submenu) if menu.OnlyUnallocated == True: tmp['cache'].addMenuEntries(menu.AppDirs) menuentries = [] for rule in menu.Rules: menuentries = rule.do(tmp['cache'].getMenuEntries(menu.AppDirs), rule.Type, 2) for menuentry in menuentries: if menuentry.Add == True: menuentry.Parents.append(menu) menu.MenuEntries.append(menuentry) continue def sort(menu): menu.Entries = [] menu.Visible = 0 for submenu in menu.Submenus: sort(submenu) tmp_s = [] tmp_e = [] for order in menu.Layout.order: if order[0] == 'Filename': tmp_e.append(order[1]) continue if order[0] == 'Menuname': tmp_s.append(order[1]) continue for order in menu.Layout.order: if order[0] == 'Separator': separator = Separator(menu) if len(menu.Entries) > 0 and isinstance(menu.Entries[-1], Separator): separator.Show = False menu.Entries.append(separator) continue if order[0] == 'Filename': menuentry = menu.getMenuEntry(order[1]) if menuentry: menu.Entries.append(menuentry) menuentry if order[0] == 'Menuname': submenu = menu.getMenu(order[1]) if submenu: __parse_inline(submenu, menu) submenu if order[0] == 'Merge': if order[1] == 'files' or order[1] == 'all': menu.MenuEntries.sort() for menuentry in menu.MenuEntries: if menuentry not in tmp_e: menu.Entries.append(menuentry) continue elif order[1] == 'menus' or order[1] == 'all': menu.Submenus.sort() for submenu in menu.Submenus: if submenu.Name not in tmp_s: __parse_inline(submenu, menu) continue order[1] == 'all' for entry in menu.Entries: entry.Show = True menu.Visible += 1 if isinstance(entry, Menu): if entry.Deleted == True: entry.Show = 'Deleted' menu.Visible -= 1 elif isinstance(entry.Directory, MenuEntry): if entry.Directory.DesktopEntry.getNoDisplay() == True: entry.Show = 'NoDisplay' menu.Visible -= 1 elif entry.Directory.DesktopEntry.getHidden() == True: entry.Show = 'Hidden' menu.Visible -= 1 entry.Deleted == True if isinstance(entry, MenuEntry): if entry.DesktopEntry.getNoDisplay() == True: entry.Show = 'NoDisplay' menu.Visible -= 1 elif entry.DesktopEntry.getHidden() == True: entry.Show = 'Hidden' menu.Visible -= 1 elif entry.DesktopEntry.getTryExec() and not __try_exec(entry.DesktopEntry.getTryExec()): entry.Show = 'NoExec' menu.Visible -= 1 elif xdg.Config.windowmanager: if entry.DesktopEntry.getOnlyShowIn() != [] or xdg.Config.windowmanager not in entry.DesktopEntry.getOnlyShowIn() or xdg.Config.windowmanager in entry.DesktopEntry.getNotShowIn(): entry.Show = 'NotShowIn' menu.Visible -= 1 not __try_exec(entry.DesktopEntry.getTryExec()) if isinstance(entry, Separator): menu.Visible -= 1 continue menu if len(menu.Entries) > 0: if isinstance(menu.Entries[0], Separator): menu.Entries[0].Show = False if len(menu.Entries) > 1: if isinstance(menu.Entries[-1], Separator): menu.Entries[-1].Show = False for entry in menu.Entries: if isinstance(entry, Menu) and entry.Layout.show_empty == 'false' and entry.Visible == 0: entry.Show = 'Empty' menu.Visible -= 1 if entry.NotInXml == True: menu.Entries.remove(entry) entry.NotInXml == True def __try_exec(executable): paths = os.environ['PATH'].split(os.pathsep) if not os.path.isfile(executable): for p in paths: f = os.path.join(p, executable) if os.path.isfile(f): if os.access(f, os.X_OK): return True continue os.access(f, os.X_OK) elif os.access(executable, os.X_OK): return True return False def __parse_inline(submenu, menu): if submenu.Layout.inline == 'true': if len(submenu.Entries) == 1 and submenu.Layout.inline_alias == 'true': menuentry = submenu.Entries[0] menuentry.DesktopEntry.set('Name', submenu.getName(), locale = True) menuentry.DesktopEntry.set('GenericName', submenu.getGenericName(), locale = True) menuentry.DesktopEntry.set('Comment', submenu.getComment(), locale = True) menu.Entries.append(menuentry) elif len(submenu.Entries) <= submenu.Layout.inline_limit or submenu.Layout.inline_limit == 0: if submenu.Layout.inline_header == 'true': header = Header(submenu.getName(), submenu.getGenericName(), submenu.getComment()) menu.Entries.append(header) for entry in submenu.Entries: menu.Entries.append(entry) else: menu.Entries.append(submenu) else: menu.Entries.append(submenu) class MenuEntryCache: '''Class to cache Desktop Entries''' def __init__(self): self.cacheEntries = { } self.cacheEntries['legacy'] = [] self.cache = { } def addMenuEntries(self, dirs, prefix = '', legacy = False): for dir in dirs: if not self.cacheEntries.has_key(dir): self.cacheEntries[dir] = [] self._MenuEntryCache__addFiles(dir, '', prefix, legacy) continue def __addFiles(self, dir, subdir, prefix, legacy): for item in os.listdir(os.path.join(dir, subdir)): if os.path.splitext(item)[1] == '.desktop': try: menuentry = MenuEntry(os.path.join(subdir, item), dir, prefix) except ParsingError: continue self.cacheEntries[dir].append(menuentry) if legacy == True: self.cacheEntries['legacy'].append(menuentry) legacy == True if os.path.isdir(os.path.join(dir, subdir, item)) and legacy == False: self._MenuEntryCache__addFiles(dir, os.path.join(subdir, item), prefix, legacy) continue def getMenuEntries(self, dirs, legacy = True): list = [] ids = [] appdirs = dirs[:] if legacy == True: appdirs.append('legacy') key = ''.join(appdirs) try: return self.cache[key] except KeyError: pass for dir in appdirs: for menuentry in self.cacheEntries[dir]: try: if menuentry.DesktopFileID not in ids: ids.append(menuentry.DesktopFileID) list.append(menuentry) elif menuentry.getType() == 'System': i = list.index(menuentry) e = list[i] if e.getType() == 'User': e.Original = menuentry continue except UnicodeDecodeError: continue continue self.cache[key] = list return list