Source code for univention.appcenter.actions.list_apps

#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Univention App Center
#  univention-app module for listing all apps
#
# Copyright 2015-2022 Univention GmbH
#
# https://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <https://www.gnu.org/licenses/>.
#

import re
from fnmatch import fnmatch

from univention.appcenter.actions import UniventionAppAction
from univention.appcenter.app_cache import Apps
from univention.appcenter.udm import get_app_ldap_object, get_machine_connection
from univention.appcenter.utils import flatten
from univention.appcenter.ucr import ucr_get, ucr_is_true


[docs]class List(UniventionAppAction): '''Lists all available apps; shows installed version.''' help = 'List all apps'
[docs] def setup_parser(self, parser): parser.add_argument('app', nargs='?', help='The ID of the App that shall be listed. May contain asterisk. Default: list all apps') parser.add_argument('--with-repository', action='store_true', help='Also list the repository name') parser.add_argument('--ids-only', action='store_true', help='Only list the IDs. Does not respect APP argument')
[docs] def main(self, args): first = True if args.ids_only: for app in self.get_apps(): self.log('%s' % app.id) return for app, versions, installations in self._list(args.app): if not first: self.log('') self.log('%s' % app.id) self.log(' Name: %s' % app.name) if args.with_repository: self.log(' Repository: %s' % app.component_id) if args.app: self.log(' Versions:') for version in versions: self.log(' %s' % version) version_installations = installations.get(version) if version_installations: self.log(' Installed: %s' % ' '.join(sorted(version_installations))) else: self.log(' Latest version: %s' % app.version) self.log(' Installations: %s' % ' '.join(sorted(flatten(installations.values())))) first = False
[docs] @classmethod def get_apps(cls): ret = [] apps = Apps().get_all_apps() blacklist = ucr_get('repository/app_center/blacklist') whitelist = ucr_get('repository/app_center/whitelist') if blacklist: blacklist = re.split(r'\s*,\s*', blacklist) if whitelist: whitelist = re.split(r'\s*,\s*', whitelist) for app in apps: if blacklist or whitelist: unlocalised_app = app.get_app_cache_obj().copy(locale='en').find_by_component_id(app.component_id) if cls._blacklist_includes_app(blacklist, unlocalised_app) and not cls._blacklist_includes_app(whitelist, unlocalised_app): continue if app.end_of_life and not app.is_installed(): continue if ucr_is_true('ad/member') and app.ad_member_issue_hide: continue if ucr_get('server/role') not in app.server_role: continue docker_prudence = app._docker_prudence_is_true() install_permissions = app.install_permissions_exist() if docker_prudence or not install_permissions: _apps = Apps().get_all_apps_with_id(app.id) if docker_prudence: _apps = [_app for _app in _apps if _app.docker_migration_works or not _app.docker] if not install_permissions: _apps = [_app for _app in _apps if not _app.install_permissions] or _apps try: app = sorted(_apps)[-1] except IndexError: continue ret.append(app) return ret
@classmethod def _blacklist_includes_app(cls, the_list, app): if not the_list: return False if '*' in the_list: return True the_list = [item.lower() for item in the_list] if app.id.lower() in the_list: return True if app.name.lower() in the_list: return True if any(category.lower() in the_list for category in app.categories): return True return False def _list(self, pattern): ret = [] lo, pos = get_machine_connection() for app in self.get_apps(): versions = [] installations = {} if pattern: if not fnmatch(app.id, pattern): continue app = Apps().find(app.id, latest=True) for _app in Apps().get_all_apps_with_id(app.id): ldap_obj = get_app_ldap_object(_app, lo, pos) servers = ldap_obj.installed_on_servers() versions.append(_app.version) installations[_app.version] = servers ret.append((app, versions, installations)) return ret