diff --git a/packageship/packageship/application/apps/lifecycle/function/download_yaml.py b/packageship/packageship/application/apps/lifecycle/function/download_yaml.py index 63c1751eb6e9a1e16f786fc381bd175c2d479ae4..9e50ba3f4a36cf8dbe9e396348d998aa1e7ae8c3 100644 --- a/packageship/packageship/application/apps/lifecycle/function/download_yaml.py +++ b/packageship/packageship/application/apps/lifecycle/function/download_yaml.py @@ -9,6 +9,7 @@ from concurrent.futures import ThreadPoolExecutor import datetime as date import requests import yaml +from retrying import retry from sqlalchemy.exc import SQLAlchemyError from requests.exceptions import HTTPError from packageship import system_config @@ -17,9 +18,9 @@ from packageship.application.models.package import PackagesMaintainer from packageship.libs.dbutils import DBHelper from packageship.libs.exception import Error, ContentNoneException from packageship.libs.configutils.readconfig import ReadConfig - from .base import Base from .gitee import Gitee +from .concurrent import ProducerConsumer class ParseYaml(): @@ -43,6 +44,7 @@ class ParseYaml(): self.openeuler_advisor_url = self._path_stitching(pkg_info.name) self._yaml_content = None self.timed_task_open = self._timed_task_status() + self.producer_consumer = ProducerConsumer() def _timed_task_status(self): """ @@ -123,22 +125,25 @@ class ParseYaml(): self.pkg.maintainer = _maintainer[0] self.pkg.maintainlevel = self._yaml_content.get('maintainlevel') try: - with DBHelper(db_name="lifecycle") as database: - database.session.begin(subtransactions=True) - database.add(self.pkg) - if self.timed_task_open and self.pkg.maintainer: - _packages_maintainer = database.session.query( - PackagesMaintainer).filter( - PackagesMaintainer.name == self.pkg.name).first() - if _packages_maintainer: - _packages_maintainer.name = self.pkg.name - _packages_maintainer.maintainer = self.pkg.maintainer - _packages_maintainer.maintainlevel = self.pkg.maintainlevel - else: - database.add(PackagesMaintainer( - name=self.pkg.name, maintainer=self.pkg.maintainer, - maintainlevel=self.pkg.maintainlevel)) - database.session.commit() + self.producer_consumer.put(copy.deepcopy(self.pkg)) + if self.timed_task_open and self.pkg.maintainer: + @retry(stop_max_attempt_number=3, stop_max_delay=500) + def _save_maintainer_info(): + with DBHelper(db_name="lifecycle") as database: + _packages_maintainer = database.session.query( + PackagesMaintainer).filter( + PackagesMaintainer.name == self.pkg.name).first() + if _packages_maintainer: + _packages_maintainer.name = self.pkg.name + _packages_maintainer.maintainer = self.pkg.maintainer + _packages_maintainer.maintainlevel = self.pkg.maintainlevel + else: + _packages_maintainer = PackagesMaintainer( + name=self.pkg.name, maintainer=self.pkg.maintainer, + maintainlevel=self.pkg.maintainlevel) + self.producer_consumer.put( + copy.deepcopy(_packages_maintainer)) + _save_maintainer_info() except (Error, ContentNoneException, SQLAlchemyError) as error: self.base.log.logger.error(error) diff --git a/packageship/packageship/application/models/package.py b/packageship/packageship/application/models/package.py index 509bbd57b1a5866b6303550f83d5b0b027a2c915..9a13ac4094e087a9b4cc40d54579b2deb7f64808 100644 --- a/packageship/packageship/application/models/package.py +++ b/packageship/packageship/application/models/package.py @@ -7,7 +7,7 @@ from sqlalchemy import Column, Integer, String, Text from packageship.libs.dbutils.sqlalchemy_helper import DBHelper -class SrcPack(DBHelper.BASE): # pylint: disable=C0103,R0903 +class SrcPack(DBHelper.BASE): """ Source package model """ @@ -44,7 +44,7 @@ class SrcPack(DBHelper.BASE): # pylint: disable=C0103,R0903 maintainlevel = Column(String(100), nullable=True) -class BinPack(DBHelper.BASE): # pylint: disable=C0103,R0903 +class BinPack(DBHelper.BASE): """ Description: functional description:Binary package data """ @@ -79,7 +79,7 @@ class BinPack(DBHelper.BASE): # pylint: disable=C0103,R0903 src_name = Column(String(500), nullable=True) -class BinRequires(DBHelper.BASE): # pylint: disable=C0103,R0903 +class BinRequires(DBHelper.BASE): """ Binary package dependent package entity model """ @@ -96,7 +96,7 @@ class BinRequires(DBHelper.BASE): # pylint: disable=C0103,R0903 pre = Column(String(20), nullable=True) -class SrcRequires(DBHelper.BASE): # pylint: disable=C0103,R0903 +class SrcRequires(DBHelper.BASE): """ Source entity package dependent package entity model """ @@ -112,7 +112,7 @@ class SrcRequires(DBHelper.BASE): # pylint: disable=C0103,R0903 pre = Column(String(20), nullable=True) -class BinProvides(DBHelper.BASE): # pylint: disable=C0103,R0903 +class BinProvides(DBHelper.BASE): """ Component entity model provided by binary package """ @@ -127,7 +127,7 @@ class BinProvides(DBHelper.BASE): # pylint: disable=C0103,R0903 pkgKey = Column(Integer, nullable=True) -class Packages(): # pylint: disable=C0103,R0903 +class Packages(): """ Source code package version, issuer and other information """ @@ -164,7 +164,7 @@ class Packages(): # pylint: disable=C0103,R0903 return model -class PackagesIssue(DBHelper.BASE): # pylint: disable=C0103,R0903 +class PackagesIssue(DBHelper.BASE): """ Source package issue """ @@ -181,7 +181,7 @@ class PackagesIssue(DBHelper.BASE): # pylint: disable=C0103,R0903 related_release = Column(String(500), nullable=True) -class PackagesMaintainer(DBHelper.BASE): # pylint: disable=C0103,R0903 +class PackagesMaintainer(DBHelper.BASE): """ Correspondence between source code package and maintainer """ diff --git a/packageship/packageship/pkgship.py b/packageship/packageship/pkgship.py index 59c76623508f31bec5475f1f1a25ccab9cf8a73b..8da7a46bdfee54d48851df7c4077faae156f9b5a 100644 --- a/packageship/packageship/pkgship.py +++ b/packageship/packageship/pkgship.py @@ -1,13 +1,15 @@ -#!/usr/bin/python3 +#!/usr/bin/python3 # pylint: disable= too-many-lines + """ Description: Entry method for custom commands -Class: BaseCommand,PkgshipCommand,RemoveCommand,InitDatabaseCommand,UpdateDatabaseCommand, +Class: BaseCommand,PkgshipCommand,RemoveCommand,InitDatabaseCommand, AllPackageCommand,UpdatePackageCommand,BuildDepCommand,InstallDepCommand, SelfBuildCommand,BeDependCommand,SingleCommand """ import os import json - +import threading +from json.decoder import JSONDecodeError try: import argparse import requests @@ -15,6 +17,7 @@ try: from requests.exceptions import HTTPError import prettytable from prettytable import PrettyTable + from packageship import system_config from packageship.libs.log import Log from packageship.libs.exception import Error from packageship.libs.configutils.readconfig import ReadConfig @@ -26,6 +29,7 @@ except ImportError as import_error: else: from packageship.application.apps.package.function.constants import ResponseCode from packageship.application.apps.package.function.constants import ListNode + from packageship.application.apps.lifecycle.function.download_yaml import update_pkg_info DB_NAME = 0 @@ -62,7 +66,7 @@ class BaseCommand(): Description: Class instance initialization """ - self._read_config = ReadConfig() + self._read_config = ReadConfig(system_config.SYS_CONFIG_PATH) self.write_host = None self.read_host = None self.__http = 'http://' @@ -139,11 +143,11 @@ class PkgshipCommand(BaseCommand): """ super(PkgshipCommand, self).__init__() self.statistics = dict() - self.table = PkgshipCommand.create_table( - ['package name', 'src name', 'version', 'database']) + self.table = PkgshipCommand.create_table() # Calculate the total width of the current terminal - self.columns = int(os.popen('stty size', 'r').read().split()[1]) + # self.columns = int(os.popen('stty size', 'r').read().split()[1]) + self.columns = 100 self.params = [] @staticmethod @@ -173,6 +177,7 @@ class PkgshipCommand(BaseCommand): for command_params in self.params: self.parse.add_argument( # pylint: disable=E1101 command_params[0], + # type=eval(command_params[1]), # pylint: disable=W0123 help=command_params[2], default=command_params[3], action=command_params[4]) @@ -190,7 +195,6 @@ class PkgshipCommand(BaseCommand): """ cls.register_command(RemoveCommand()) cls.register_command(InitDatabaseCommand()) - cls.register_command(UpdateDatabaseCommand()) cls.register_command(AllPackageCommand()) cls.register_command(UpdatePackageCommand()) cls.register_command(BuildDepCommand()) @@ -198,32 +202,15 @@ class PkgshipCommand(BaseCommand): cls.register_command(SelfBuildCommand()) cls.register_command(BeDependCommand()) cls.register_command(SingleCommand()) + cls.register_command(IssueCommand()) + cls.register_command(AllTablesCommand()) + cls.register_command(BatchTaskCommand()) try: args = cls.parser.parse_args() args.func(args) except Error: print('command error') - def parse_package(self, response_data): - """ - Description: Parse the corresponding data of the package - Args: - response_data: http request response content - Returns: - - Raises: - - """ - if response_data.get('code') == ResponseCode.SUCCESS: - package_all = response_data.get('data') - if isinstance(package_all, list): - for package_item in package_all: - row_data = [package_item.get('sourceName'), package_item.get( - 'dbname'), package_item.get('version'), package_item.get('license')] - self.table.add_row(row_data) - else: - print(response_data.get('msg')) - def parse_depend_package(self, response_data): """ Description: Parsing package data with dependencies @@ -299,7 +286,7 @@ class PkgshipCommand(BaseCommand): print(character * self.columns) @staticmethod - def create_table(title): + def create_table(title=None): """ Description: Create printed forms Args: @@ -412,12 +399,17 @@ class RemoveCommand(PkgshipCommand): else: # Determine whether to delete the mysql database or sqlite database if response.status_code == 200: - data = json.loads(response.text) - if data.get('code') == ResponseCode.SUCCESS: - print('delete success') + try: + data = json.loads(response.text) + except JSONDecodeError as json_error: + LOGGER.logger.error(json_error) + print(response.text) else: - LOGGER.logger.error(data.get('msg')) - print(data.get('msg')) + if data.get('code') == ResponseCode.SUCCESS: + print('delete success') + else: + LOGGER.logger.error(data.get('msg')) + print(data.get('msg')) else: self.http_error(response) @@ -465,7 +457,8 @@ class InitDatabaseCommand(PkgshipCommand): """ file_path = params.filepath try: - file_path = os.path.abspath(file_path) + if file_path: + file_path = os.path.abspath(file_path) response = requests.post(self.write_host + '/initsystem', data=json.dumps({'configfile': file_path}), headers=self.headers) @@ -474,61 +467,21 @@ class InitDatabaseCommand(PkgshipCommand): print(str(conn_error)) else: if response.status_code == 200: - response_data = json.loads(response.text) - if response_data.get('code') == ResponseCode.SUCCESS: - print('Database initialization success ') + try: + response_data = json.loads(response.text) + except JSONDecodeError as json_error: + LOGGER.logger.error(json_error) + print(response.text) else: - LOGGER.logger.error(response_data.get('msg')) - print(response_data.get('msg')) + if response_data.get('code') == ResponseCode.SUCCESS: + print('Database initialization success ') + else: + LOGGER.logger.error(response_data.get('msg')) + print(response_data.get('msg')) else: self.http_error(response) -class UpdateDatabaseCommand(PkgshipCommand): - """ - Description: update database command - Attributes: - parse: Command line parsing example - params: Command line parameters - """ - - def __init__(self): - """ - Description: Class instance initialization - """ - super(UpdateDatabaseCommand, self).__init__() - - self.parse = PkgshipCommand.subparsers.add_parser( - 'updatedb', help='database update operation') - self.params = [ - ('db', 'str', 'name of the database operated', '', 'store')] - - def register(self): - """ - Description: Command line parameter injection - Args: - - Returns: - - Raises: - - """ - super(UpdateDatabaseCommand, self).register() - self.parse.set_defaults(func=self.do_command) - - def do_command(self, params): - """ - Description: Action to execute command - Args: - - Returns: - - Raises: - - """ - pass # pylint: disable= W0107 - - class AllPackageCommand(PkgshipCommand): """ Description: get all package commands @@ -547,10 +500,20 @@ class AllPackageCommand(PkgshipCommand): self.parse = PkgshipCommand.subparsers.add_parser( 'list', help='get all package data') self.table = self.create_table( - ['packagenames', 'database', 'version', 'license']) - self.params = [('-db', 'str', 'name of the database operated', '', 'store'), + ['packagenames', 'database', 'version', 'license', 'maintainer', + 'release date', 'used time']) + self.params = [('tablename', 'str', 'name of the database operated', '', 'store'), ('-remote', 'str', 'The address of the remote service', False, 'store_true'), + ('-pkgname', 'str', + 'Package name that needs fuzzy matching', '', 'store'), + ('-maintainner', 'str', 'Maintainer\'s name', '', 'store'), + ('-maintainlevel', 'str', + 'Maintain the level of data', '', 'store'), + ('-page', 'int', + 'Need to query the data on the first few pages', 1, 'store'), + ('-pagesize', 'int', + 'The size of the data displayed on each page', 10, 'store') ] def register(self): @@ -566,6 +529,35 @@ class AllPackageCommand(PkgshipCommand): super(AllPackageCommand, self).register() self.parse.set_defaults(func=self.do_command) + def __parse_package(self, response_data, table_name): + """ + Description: Parse the corresponding data of the package + Args: + response_data: http request response content + Returns: + + Raises: + + """ + if response_data.get('code') == ResponseCode.SUCCESS: + package_all = response_data.get('data') + if isinstance(package_all, list): + for package_item in package_all: + row_data = [package_item.get('name'), + table_name, + package_item.get('version') if package_item.get( + 'version') else '', + package_item.get('rpm_license') if package_item.get( + 'rpm_license') else '', + package_item.get('maintainer') if package_item.get( + 'maintainer') else '', + package_item.get('release_time') if package_item.get( + 'release_time') else '', + package_item.get('used_time')] + self.table.add_row(row_data) + else: + print(response_data.get('msg')) + def do_command(self, params): """ Description: Action to execute command @@ -578,7 +570,15 @@ class AllPackageCommand(PkgshipCommand): """ self._set_read_host(params.remote) _url = self.read_host + \ - '/packages?dbName={dbName}'.format(dbName=params.db) + '/packages?table_name={table_name}&query_pkg_name={pkg_name}&\ + maintainner={maintainner}&maintainlevel={maintainlevel}&\ + page_num={page}&page_size={pagesize}'.format( + table_name=params.tablename, + pkg_name=params.pkgname, + maintainner=params.maintainner, + maintainlevel=params.maintainlevel, + page=params.page, + pagesize=params.pagesize).replace(' ', '') try: response = requests.get(_url) except ConnErr as conn_error: @@ -586,10 +586,20 @@ class AllPackageCommand(PkgshipCommand): print(str(conn_error)) else: if response.status_code == 200: + try: + response_data = json.loads(response.text) + self.__parse_package(response_data, params.tablename) + except JSONDecodeError as json_error: + LOGGER.logger.error(json_error) + print(response.text) - self.parse_package(json.loads(response.text)) - if self.table: + if getattr(self.table, 'rowcount'): + print('total count : %d' % response_data['total_count']) + print('total page : %d' % response_data['total_page']) + print('current page : %s ' % params.page) print(self.table) + else: + print('Sorry, no relevant information has been found yet') else: self.http_error(response) @@ -611,10 +621,12 @@ class UpdatePackageCommand(PkgshipCommand): self.parse = PkgshipCommand.subparsers.add_parser( 'updatepkg', help='update package data') self.params = [ - ('packagename', 'str', 'Source package name', '', 'store'), - ('db', 'str', 'name of the database operated', '', 'store'), - ('-m', 'str', 'Maintainers name', '', 'store'), - ('-l', 'int', 'database priority', 1, 'store'), + ('-packagename', 'str', 'Source package name', '', 'store'), + ('-maintainer', 'str', 'Maintainers name', '', 'store'), + ('-maintainlevel', 'int', 'database priority', 1, 'store'), + ('-filefolder', 'str', 'Path of yaml file for batch update', '', 'store'), + ('--batch', 'str', 'The address of the remote service', + False, 'store_true'), ] def register(self): @@ -640,25 +652,34 @@ class UpdatePackageCommand(PkgshipCommand): Raises: ConnectionError: Request connection error """ - _url = self.write_host + '/packages/packageInfo' + _url = self.write_host + '/lifeCycle/updatePkgInfo' try: + _folder = params.filefolder + if _folder: + _folder = os.path.abspath(_folder) response = requests.put( - _url, data=json.dumps({'sourceName': params.packagename, - 'dbName': params.db, - 'maintainer': params.m, - 'maintainlevel': params.l}), + _url, data=json.dumps({'pkg_name': params.packagename, + 'maintainer': params.maintainer, + 'maintainlevel': params.maintainlevel, + 'batch': params.batch, + 'filepath': _folder}), headers=self.headers) except ConnErr as conn_error: LOGGER.logger.error(conn_error) print(str(conn_error)) else: if response.status_code == 200: - data = json.loads(response.text) - if data.get('code') == ResponseCode.SUCCESS: - print('update completed') + try: + data = json.loads(response.text) + except JSONDecodeError as json_error: + LOGGER.logger.error(json_error) + print(response.text) else: - LOGGER.logger.error(data.get('msg')) - print(data.get('msg')) + if data.get('code') == ResponseCode.SUCCESS: + print('update completed') + else: + LOGGER.logger.error(data.get('msg')) + print(data.get('msg')) else: self.http_error(response) @@ -678,7 +699,8 @@ class BuildDepCommand(PkgshipCommand): Description: Class instance initialization """ super(BuildDepCommand, self).__init__() - + self.table = PkgshipCommand.create_table( + ['Binary name', 'Source name', 'Version', 'Database name']) self.parse = PkgshipCommand.subparsers.add_parser( 'builddep', help='query the compilation dependencies of the specified package') self.collection = True @@ -731,14 +753,19 @@ class BuildDepCommand(PkgshipCommand): print(str(conn_error)) else: if response.status_code == 200: - statistics_table = self.parse_depend_package( - json.loads(response.text)) - if getattr(self.table, 'rowcount'): - self.print_('query {} buildDepend result display:'.format( - params.packagename)) - print(self.table) - self.print_('statistics') - print(statistics_table) + try: + statistics_table = self.parse_depend_package( + json.loads(response.text)) + except JSONDecodeError as json_error: + LOGGER.logger.error(json_error) + print(response.text) + else: + if getattr(self.table, 'rowcount'): + self.print_('query {} buildDepend result display:'.format( + params.packagename)) + print(self.table) + self.print_('statistics') + print(statistics_table) else: self.http_error(response) @@ -788,7 +815,7 @@ class InstallDepCommand(PkgshipCommand): cmd_params[0], nargs='*', default=None, help=cmd_params[1]) self.parse.set_defaults(func=self.do_command) - def parse_package(self, response_data): + def __parse_package(self, response_data): """ Description: Parse the corresponding data of the package Args: @@ -798,6 +825,8 @@ class InstallDepCommand(PkgshipCommand): Raises: """ + self.table = PkgshipCommand.create_table( + ['Binary name', 'Source name', 'Version', 'Database name']) if getattr(self, 'statistics'): setattr(self, 'statistics', dict()) bin_package_count = 0 @@ -866,14 +895,19 @@ class InstallDepCommand(PkgshipCommand): print(str(conn_error)) else: if response.status_code == 200: - statistics_table = self.parse_package( - json.loads(response.text)) - if getattr(self.table, 'rowcount'): - self.print_('query{} InstallDepend result display:'.format( - params.packagename)) - print(self.table) - self.print_('statistics') - print(statistics_table) + try: + statistics_table = self.__parse_package( + json.loads(response.text)) + except JSONDecodeError as json_error: + LOGGER.logger.error(json_error) + print(response.text) + else: + if getattr(self.table, 'rowcount'): + self.print_('query{} InstallDepend result display:'.format( + params.packagename)) + print(self.table) + self.print_('statistics') + print(statistics_table) else: self.http_error(response) @@ -1002,7 +1036,7 @@ class SelfBuildCommand(PkgshipCommand): return src_package_count - def parse_package(self, response_data): + def __parse_package(self, response_data): """ Description: Parse the corresponding data of the package Args: @@ -1062,17 +1096,22 @@ class SelfBuildCommand(PkgshipCommand): print(str(conn_error)) else: if response.status_code == 200: - statistics_table = self.parse_package( - json.loads(response.text)) - if getattr(self.bin_package_table, 'rowcount') \ - and getattr(self.src_package_table, 'rowcount'): - self.print_('query {} selfDepend result display :'.format( - params.packagename)) - print(self.bin_package_table) - self.print_(character='=') - print(self.src_package_table) - self.print_('statistics') - print(statistics_table) + try: + statistics_table = self.__parse_package( + json.loads(response.text)) + except JSONDecodeError as json_error: + LOGGER.logger.error(json_error) + print(response.text) + else: + if getattr(self.bin_package_table, 'rowcount') \ + and getattr(self.src_package_table, 'rowcount'): + self.print_('query {} selfDepend result display :'.format( + params.packagename)) + print(self.bin_package_table) + self.print_(character='=') + print(self.src_package_table) + self.print_('statistics') + print(statistics_table) else: self.http_error(response) @@ -1090,7 +1129,8 @@ class BeDependCommand(PkgshipCommand): Description: Class instance initialization """ super(BeDependCommand, self).__init__() - + self.table = PkgshipCommand.create_table( + ['Binary name', 'Source name', 'Version', 'Database name']) self.parse = PkgshipCommand.subparsers.add_parser( 'bedepend', help='dependency query for the specified package') self.params = [ @@ -1138,14 +1178,19 @@ class BeDependCommand(PkgshipCommand): print(str(conn_error)) else: if response.status_code == 200: - statistics_table = self.parse_depend_package( - json.loads(response.text)) - if getattr(self.table, 'rowcount'): - self.print_('query {} beDepend result display :'.format( - params.packagename)) - print(self.table) - self.print_('statistics') - print(statistics_table) + try: + statistics_table = self.parse_depend_package( + json.loads(response.text)) + except JSONDecodeError as json_error: + LOGGER.logger.error(json_error) + print(response.text) + else: + if getattr(self.table, 'rowcount'): + self.print_('query {} beDepend result display :'.format( + params.packagename)) + print(self.table) + self.print_('statistics') + print(statistics_table) else: self.http_error(response) @@ -1168,9 +1213,11 @@ class SingleCommand(PkgshipCommand): 'single', help='query the information of a single package') self.params = [ ('packagename', 'str', 'source package name', '', 'store'), - ('-db', 'str', 'name of the database operated', '', 'store'), + ('tablename', 'str', 'name of the database operated', '', 'store'), ('-remote', 'str', 'The address of the remote service', False, 'store_true') ] + self.provides_table = self.create_table(['Symbol', 'Required by']) + self.requires_table = self.create_table(['Symbol', 'Provides by']) def register(self): """ @@ -1185,7 +1232,72 @@ class SingleCommand(PkgshipCommand): super(SingleCommand, self).register() self.parse.set_defaults(func=self.do_command) - def parse_package(self, response_data): + def __parse_package_detail(self, response_data): + """ + + """ + _show_field_name = ('pkg_name', 'version', 'release', 'url', 'license', 'feature', + 'maintainer', 'maintainlevel', 'gitee_url', 'issue', 'summary', + 'description', 'buildrequired') + _package_detail_info = response_data.get('data') + _line_content = [] + if _package_detail_info: + for key in _show_field_name: + value = _package_detail_info.get(key) + if value is None: + value = '' + if isinstance(value, list): + value = '、'.join(value) if value else '' + _line_content.append('%-15s:%s' % (key, value)) + for content in _line_content: + self.print_(content=content) + + def __parse_provides(self, provides): + """ + + """ + if provides and isinstance(provides, list): + for _provide in provides: + _required_by = '\n'.join( + _provide['requiredby']) if _provide['requiredby'] else '' + self.provides_table.add_row( + [_provide['name'], _required_by]) + self.print_('Provides') + if getattr(self.provides_table, 'rowcount'): + print(self.provides_table) + else: + print('No relevant dependent data') + self.provides_table.clear_rows() + + def __parse_requires(self, requires): + """ + + """ + if requires and isinstance(requires, list): + for _require in requires: + _provide_by = '\n'.join( + _require['providedby']) if _require['providedby'] else '' + self.requires_table.add_row( + [_require['name'], _provide_by]) + self.print_('Requires') + if getattr(self.requires_table, 'rowcount'): + print(self.requires_table) + else: + print('No related components') + self.requires_table.clear_rows() + + def __parse_subpack(self, subpacks): + """ + Data analysis of binary package + """ + for subpack_item in subpacks: + print('-' * 50) + self.print_(subpack_item['name']) + + self.__parse_provides(subpack_item['provides']) + self.__parse_requires(subpack_item['requires']) + + def __parse_package(self, response_data): """ Description: Parse the corresponding data of the package Args: @@ -1195,25 +1307,113 @@ class SingleCommand(PkgshipCommand): Raises: """ - show_field_name = ('sourceName', 'dbname', 'version', - 'license', 'maintainer', 'maintainlevel') - print_contents = [] if response_data.get('code') == ResponseCode.SUCCESS: - package_all = response_data.get('data') - if isinstance(package_all, list): - for package_item in package_all: - for key, value in package_item.items(): - if value is None: - value = '' - if key in show_field_name: - line_content = '%-15s:%s' % (key, value) - print_contents.append(line_content) - print_contents.append('=' * self.columns) + + self.__parse_package_detail(response_data) + try: + _subpacks = response_data['data']['subpack'] + self.__parse_subpack(_subpacks) + except KeyError as key_error: + LOGGER.logger.error(key_error) + else: + print(response_data.get('msg')) + + def do_command(self, params): + """ + Description: Action to execute command + Args: + params: command lines params + Returns: + + Raises: + ConnectionError: requests connection error + """ + self._set_read_host(params.remote) + _url = self.read_host + \ + '/packages/packageInfo?table_name={db_name}&pkg_name={packagename}' \ + .format(db_name=params.tablename, packagename=params.packagename) + try: + response = requests.get(_url) + except ConnErr as conn_error: + LOGGER.logger.error(conn_error) + print(str(conn_error)) + else: + if response.status_code == 200: + try: + self.__parse_package(json.loads(response.text)) + except JSONDecodeError as json_error: + LOGGER.logger.error(json_error) + print(response.text) + + else: + self.http_error(response) + + +class IssueCommand(PkgshipCommand): + """ + Description: Get the issue list + Attributes: + parse: Command line parsing example + params: Command line parameters + """ + + def __init__(self): + """ + Description: Class instance initialization + """ + super(IssueCommand, self).__init__() + + self.parse = PkgshipCommand.subparsers.add_parser( + 'issue', help='Query the issue list of the specified package') + self.params = [ + ('-pkg_name', 'str', 'Query source package name', '', 'store'), + + ('-issue_type', 'str', 'Type of issue', '', 'store'), + ('-issue_status', 'str', 'the status of the issue', '', 'store'), + ('-maintainer', 'str', 'Maintainer\'s name', '', 'store'), + ('-page', 'int', + 'Need to query the data on the first few pages', 1, 'store'), + ('-pagesize', 'int', + 'The size of the data displayed on each page', 100, 'store'), + ('-remote', 'str', 'The address of the remote service', False, 'store_true') + ] + self.table = self.create_table( + ['issue_id', 'pkg_name', 'issue_title', + 'issue_status', 'issue_type', 'maintainer']) + + def register(self): + """ + Description: Command line parameter injection + + """ + super(IssueCommand, self).register() + self.parse.set_defaults(func=self.do_command) + + def __parse_package(self, response_data): + """ + Description: Parse the corresponding data of the package + + Args: + response_data: http response data + """ + if response_data.get('code') == ResponseCode.SUCCESS: + issue_all = response_data.get('data') + if isinstance(issue_all, list): + for issue_item in issue_all: + _row_data = [ + issue_item.get('issue_id'), + issue_item.get('pkg_name') if issue_item.get( + 'pkg_name') else '', + issue_item.get('issue_title')[:50]+'...' if issue_item.get( + 'issue_title') else '', + issue_item.get('issue_status') if issue_item.get( + 'issue_status') else '', + issue_item.get('issue_type') if issue_item.get( + 'issue_type') else '', + issue_item.get('maintainer') if issue_item.get('maintainer') else ''] + self.table.add_row(_row_data) else: print(response_data.get('msg')) - if print_contents: - for content in print_contents: - self.print_(content=content) def do_command(self, params): """ @@ -1227,8 +1427,15 @@ class SingleCommand(PkgshipCommand): """ self._set_read_host(params.remote) _url = self.read_host + \ - '/packages/packageInfo?dbName={db_name}&sourceName={packagename}' \ - .format(db_name=params.db, packagename=params.packagename) + '/lifeCycle/issuetrace?page_num={page_num}&\ + page_size={page_size}&pkg_name={pkg_name}&issue_type={issue_type}\ + &issue_status={issue_status}&maintainer={maintainer}'\ + .format(page_num=params.page, + page_size=params.pagesize, + pkg_name=params.pkg_name, + issue_type=params.issue_type, + issue_status=params.issue_status, + maintainer=params.maintainer).replace(' ', '') try: response = requests.get(_url) except ConnErr as conn_error: @@ -1236,10 +1443,139 @@ class SingleCommand(PkgshipCommand): print(str(conn_error)) else: if response.status_code == 200: - self.parse_package(json.loads(response.text)) + try: + response_data = json.loads(response.text) + self.__parse_package(response_data) + except JSONDecodeError as json_error: + LOGGER.logger.error(json_error) + print(response.text) + if getattr(self.table, "rowcount"): + print('total count : %d' % response_data['total_count']) + print('total page : %d' % response_data['total_page']) + print('current page : %s ' % params.page) + print(self.table) + else: + print("Sorry, no relevant information has been found yet") + else: + self.http_error(response) + + +class AllTablesCommand(PkgshipCommand): + """ + Description: Get all data tables in the current life cycle + Attributes: + parse: Command line parsing example + params: Command line parameters + """ + + def __init__(self): + """ + Description: Class instance initialization + """ + super(AllTablesCommand, self).__init__() + + self.parse = PkgshipCommand.subparsers.add_parser( + 'tables', help='Get all data tables in the current life cycle') + self.params = [ + ('-remote', 'str', 'The address of the remote service', False, 'store_true') + ] + + def register(self): + """ + Description: Command line parameter injection + + """ + super(AllTablesCommand, self).register() + self.parse.set_defaults(func=self.do_command) + + def do_command(self, params): + """ + Description: Action to execute command + Args: + params: command lines params + Returns: + + Raises: + ConnectionError: requests connection error + """ + self._set_read_host(params.remote) + _url = self.read_host + '/lifeCycle/tables' + try: + response = requests.get(_url, headers=self.headers) + except ConnErr as conn_error: + LOGGER.logger.error(conn_error) + print(str(conn_error)) + else: + if response.status_code == 200: + try: + _response_content = json.loads(response.text) + if _response_content.get('code') == ResponseCode.SUCCESS: + print( + 'The version libraries that exist in the ', + 'current life cycle are as follows:') + for table in _response_content.get('data', []): + print(table) + else: + print('Failed to get the lifecycle repository') + except JSONDecodeError as json_error: + LOGGER.logger.error(json_error) + print(response.text) else: self.http_error(response) +class BatchTaskCommand(PkgshipCommand): + """ + Description: Issue and life cycle information involved in batch processing packages + Attributes: + parse: Command line parsing example + params: Command line parameters + """ + + def __init__(self): + """ + Description: Class instance initialization + """ + super(BatchTaskCommand, self).__init__() + + self.parse = PkgshipCommand.subparsers.add_parser( + 'update', + help='Issue and life cycle information involved in batch processing packages') + self.params = [ + ('--issue', 'str', 'Batch operation on issue', False, 'store_true'), + ('--package', 'str', 'Package life cycle information processing', + False, 'store_true'), + ] + + def register(self): + """ + Description: Command line parameter injection + + """ + super(BatchTaskCommand, self).register() + self.parse.set_defaults(func=self.do_command) + + def do_command(self, params): + """ + Description: Action to execute command + Args: + params: command lines params + Returns: + + Raises: + ConnectionError: requests connection error + """ + if not params.issue and not params.package: + print('Please select the way to operate') + if params.issue: + issue_thread = threading.Thread( + target=update_pkg_info, args=(False,)) + issue_thread.start() + if params.package: + update_pkg_thread = threading.Thread( + target=update_pkg_info) + update_pkg_thread.start() + + if __name__ == '__main__': main()