diff options
author | Mattias Andrée <maandree@operamail.com> | 2015-04-04 14:40:34 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2015-04-04 14:40:34 +0200 |
commit | 0d65a9c9faca8f06dc70c577e7ddb42fba5359fd (patch) | |
tree | 89473b4253c9f9630f1601dd891026b0119e02e1 /src | |
parent | m (diff) | |
download | xpybar-0d65a9c9faca8f06dc70c577e7ddb42fba5359fd.tar.gz xpybar-0d65a9c9faca8f06dc70c577e7ddb42fba5359fd.tar.bz2 xpybar-0d65a9c9faca8f06dc70c577e7ddb42fba5359fd.tar.xz |
.desktop file support
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/application.py | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/src/plugins/application.py b/src/plugins/application.py new file mode 100644 index 0000000..6af7227 --- /dev/null +++ b/src/plugins/application.py @@ -0,0 +1,147 @@ +# -*- python -*- +''' +xpybar – xmobar replacement written in python +Copyright © 2014, 2015 Mattias Andrée (maandree@member.fsf.org) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +''' + + +class Application: + ''' + Applications and .desktop files + + @variable desktop_file:str The .desktop file for the application + @variable settings:dict<str?, dict<str, dict<str?, str>>> Section → key → locale → value map of settings + ''' + + + def __init__(self, file): + ''' + Constructor + + @param file:str The .desktop file if it contains '/', otherwise the name of the application + ''' + import os + if '/' not in file: + import pwd + directories = [] + home = pwd.getpwuid(os.getuid()).pw_dir + directories.append('%s/.local/share/applications' % home) + if 'HOME' in os.environ: + if not os.environ['HOME'] == home: + home = os.environ['HOME'] + directories.append('%s/.local/share/applications' % home) + directories += ['/usr/local/share/applications', '/usr/share/applications', '/share/applications'] + directories = [d for d in directories if os.path.exists(d) and os.path.isdir(d)] + + file = ['%s/%s.desktop' % (d, file) for d in directories] + file = [f for f in file if os.path.exists(f) and os.path.isfile(f)] + if len(file) == 0: + raise Exception('Application not found') + file = file[0] + + self.desktop_file = file + with open(self.desktop_file, 'rb') as file: + data = file.read() + data = [l for l in data.decode('utf-8', 'replace').replace('\r', '\n').split('\n') if not l == ''] + + section = None + self.settings = {} + for line in data: + line = line.strip() + if line.startswith('[') and line.endswith(']'): + section = line[1 : -1] + elif line.startswith(';') or line.startswith('#'): + pass + elif (':' in line) or ('=' in line): + line_e = line.split('=') + line_c = line.split(':') + if len(line_e[0]) < len(line_c[0]): + first = '=' + line = line_e + else: + first = ':' + line = line_c + key, value = line[0].rstrip(), first.join(line[1:]).lstrip() + locale = None + if ('[' in key) and key.endswith(']'): + key = key[:-1].split('[') + key, locale = '['.join(key[:-1]), key[-1] + if section not in self.settings: + self.settings[section] = {} + section_map = self.settings[section] + if key not in section_map: + section_map[key] = {} + key_map = section_map[key] + if locale not in key_map: + key_map[locale] = value + + self.locales = [None] + if 'LANG' in os.environ: + locale = os.environ['LANG'] + elif 'LOCALE' in os.environ: + locale = os.environ['LOCALE'] + else: + return + locale = locale.split(' ')[0].split('.')[0].split('_') + for i in range(len(locale)): + self.locales.append('_'.join(locale[:i])) + self.locales.reverse() + + + def get_setting(self, key, section = 'Desktop Entry', locales = None): + ''' + Read a setting in the application's .desktop file + + @param key:str The key + @param section:str? The section where the key is located + @param locale:list<str?>? Acceptable locales in order of preference, + `None` to use the default for your locale + ''' + map = self.settings + if section not in map: + return None + map = map[section] + if key not in map: + return None + map = map[key] + if locales is None: + locales = self.locales + for locale in locales: + if locale in map: + return map[locale] + return None + + + @staticmethod + def strip_placeholders(text): + ''' + Remove placeholders form an exec string + + @param text:str The exec string with placeholders + @return :str The exec string without placeholders + ''' + buf, esc = '', False + for c in text: + if esc: + esc = False + if c == '%': + buf += c + elif c == '%': + esc = True + else: + buf += c + return buf + |