# -*- python -*- ''' xpybar – xmobar replacement written in python Copyright © 2014, 2015, 2016, 2017, 2018, 2019 Mattias Andrée (m@maandreese) 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 . ''' from util import * class Pacman: ''' Retrieve package information using Arch Linux's pacman Unique variables for installed: @variable required:list Packages that require this package @variable optrequired:list Packages that this package is optional for @variable install_date:str The date and time the package was installed @variable installed_explicitly:bool Whether the package was installed explicitly @variable install_script:bool Whether the package contains and install script Unique variables for not installed: @variable repository:str The repository the package is located in @variable download_size:float The download size of the package in kilobytes Common variables: @variable name:str The name of the package @variable version:str The version of the package @variable description:str The description of the package @variable architecture:str The microprocessor architecture of the package @variable url:str The home URL of the project @variable licenses:list The licenses used by the package @variable groups:list Package groups the package is a member of @variable provides:list Packages the package provides @variable depends:list Packages the package depends on @variable optdepends:list<(str, str?, bool)> Optional packages for this package, stored as a tuple of: The name of the package, the reason for using it, and whether or not it is installed. @variable conflicts:list Packages the package conflicts with @variable replaces:list Packages the package replaces @variable installed_size:float The installed size of the package in kilobytes @variable packager:str? The packager of the package, `None` if unknown @variable build_date:str The date and time the package was built @variable validated_by:list Methods used to validate the package's integrity ''' def __init__(self, package, installed): ''' Constructor @param package:str The name of the package, can be %repo/%name @param installed:bool Whether it is information about the installed version that should be fetched ''' verb = '-Qi' if installed else '-Si' # -Sii and -Qii, while a bit different, would get us more info. info = spawn_read('env', 'LOCALE=C', 'pacman', verb, package).split('\n') if len(info) == 1: raise Exception('Package `%s\' is not installed' % package) last_field = None fields = {} for line in info: continued = line.startswith(' ') line = list(filter(lambda cell : not cell == '', line.split(' '))) colon = -1 if not continued: for i in range(len(line)): if line[i] == ':': colon = i break field = last_field if colon >= 0: last_field = field = ' '.join(line[:colon]) line = line[colon + 1:] if field not in fields: fields[field] = [] fields[field].append(line) word = lambda x : fields[x][0][0] text = lambda x : ' '.join(fields[x][0]) plur = lambda x : list(filter(lambda w : not w == 'None', fields[x][0])) if installed: self.required = plur('Required By') self.optrequired = plur('Optional For') self.install_date = text('Install Date') self.installed_explicitly = text('Install Reason') == 'Explicitly installed' self.install_script = text('Install Script') == 'Yes' if not installed: self.repository = word('Name') self.download_size = float(word('Download Size')) self.name = word('Name') self.version = word('Version') self.description = text('Description') self.architecture = word('Architecture') self.url = text('URL') self.licenses = plur('Licences') self.groups = plur('Groups') self.provides = plur('Provides') self.depends = plur('Depends On') self.optdepends = [] optdepends_ = [' '.join(x) for x in fields['Optional Deps']] for deps in optdepends_: inst = deps.endswith(' [installed]') if installed: deps = deps[:-len(' [installed]')] if ': ' in deps: deps = deps.split(': ') name = deps[0] deps = ': '.join(deps[1:]) self.optdepends.append((name, deps, inst)) else: self.optdepends.append((deps, None, inst)) self.conflicts = plur('Conflicts With') self.replaces = plur('Replaces') self.installed_size = float(word('Installed Size')) self.packager = text('Packager') if self.packager == 'Unknown Packager': self.packager = None self.build_date = text('Build Date') self.validated_by = list(filter(lambda x : not x == 'Sum', plur('Validated By')))