diff --git a/packageship/packageship/application/initsystem/data_import.py b/packageship/packageship/application/initsystem/data_import.py index e7dafde27c2e97a506efed9b1b1eaf5f8d58d5a7..eacb9b6c2cf1ecd839305d81ace8edee4c669ea4 100644 --- a/packageship/packageship/application/initsystem/data_import.py +++ b/packageship/packageship/application/initsystem/data_import.py @@ -1,7 +1,9 @@ -''' - Initialization of data import -    Import the data in the sqlite database into the mysql database -''' +#!/usr/bin/python3 +""" +Description: Initialization of data import + Import the data in the sqlite database into the mysql database +Class: InitDataBase,MysqlDatabaseOperations,SqliteDatabaseOperations +""" import os import pathlib import yaml @@ -27,17 +29,20 @@ LOGGER = Log(__name__) class InitDataBase(): - ''' - Database initialization, generate multiple databases and data based on configuration files - ''' + """ + Description: Database initialization, generate multiple databases and data based on configuration files + Attributes: + config_file_path: configuration file path + config_file_datas: initialize the configuration content of the database + db_type: type of database + """ def __init__(self, config_file_path=None): - ''' - parameter: - config_file_path:The path of the configuration file that needs to initialize - the database in the project - ''' - + """ + Description: Class instance initialization + Args: + config_file_path: Configuration file path + """ self.config_file_path = config_file_path if self.config_file_path: @@ -53,14 +58,20 @@ class InitDataBase(): if self.db_type not in ['mysql', 'sqlite']: LOGGER.logger.error("database type configuration error") - raise Exception('database type configuration error') + raise Error('database type configuration error') def __read_config_file(self): - ''' - functional description: - Read the contents of the configuration file load each node data in the yaml - configuration file as a list to return - ''' + """ + Description: Read the contents of the configuration file load each node data in the yaml configuration file as + a list to return + Args: + + Returns: + Initialize the contents of the database configuration file + Raises: + FileNotFoundError: The specified file does not exist + TypeError: Wrong type of data + """ if not os.path.exists(self.config_file_path): raise FileNotFoundError( @@ -80,9 +91,15 @@ class InitDataBase(): return init_database_config def init_data(self): - ''' - functional description:Initialization of the database - ''' + """ + Description: Initialization of the database + Args: + + Returns: + + Raises: + IOError: An error occurred while deleting the database information file + """ if getattr(self, 'config_file_datas', None) is None or \ self.config_file_datas is None: raise ContentNoneException('Initialization file content is empty') @@ -116,9 +133,16 @@ class InitDataBase(): self._init_data(database) def _create_database(self, database): - ''' - create related databases - ''' + """ + Description: create related databases + Args: + database: Initialize the configuration content of the database + Returns: + The generated mysql database or sqlite database + Raises: + SQLAlchemyError: Abnormal database operation + """ + db_name = database.get('dbname') self._sqlite_db = SqliteDatabaseOperations(db_name=db_name) @@ -135,11 +159,20 @@ class InitDataBase(): return sqltedb_file def _init_data(self, database): - ''' - functional description:data initialization operation - parameter: - database:database configuration information - ''' + """ + Description: data initialization operation + Args: + database: Initialize the configuration content of the database + Returns: + + Raises: + ContentNoneException: Exception with empty content + TypeError: Data type error + SQLAlchemyError: Abnormal database operation + DataMergeException: Error in data integration + IOError: An error occurred while deleting the database information file + """ + try: db_file = None # 1. create a database and related tables in the database @@ -160,7 +193,7 @@ class InitDataBase(): src_package_paths, bin_package_paths) # 4. dependencies between combined data self.data_relationship(db_file) - # # 5. save data + # 5. save data self.save_data(db_name) except (SQLAlchemyError, ContentNoneException, @@ -192,9 +225,16 @@ class InitDataBase(): LOGGER.logger.error(error_msg) def _src_package_relation(self, src_package_data): - ''' - Mapping of data relations of source packages - ''' + """ + Description: Mapping of data relations of source packages + Args: + src_package_data: Source package data + Returns: + + Raises: + + """ + _src_package_name = src_package_data.name _src_package = { "name": src_package_data.name, @@ -219,9 +259,16 @@ class InitDataBase(): self._src_package_names[src_package_data.pkgKey] = _src_package_name def _src_requires_relation(self, src_requires_data): - ''' - Source package dependent package data relationship mapping - ''' + """ + Description: Source package dependent package data relationship mapping + Args: + src_requires_data: Source package dependent package data + Returns: + + Raises: + + """ + _src_package_name = self._src_package_names.get( src_requires_data.pkgKey) if _src_package_name: @@ -232,9 +279,16 @@ class InitDataBase(): }) def _bin_package_relation(self, bin_package_data): - ''' - Binary package relationship mapping problem - ''' + """ + Description: Binary package relationship mapping problem + Args: + bin_package_data: Binary package data + Returns: + + Raises: + + """ + _bin_pkg_key = bin_package_data.pkgKey self._bin_package_name[bin_package_data.name] = _bin_pkg_key @@ -257,9 +311,16 @@ class InitDataBase(): self._bin_package_dicts[src_package_name].append(_bin_package) def _bin_requires_relation(self, bin_requires_data): - ''' - Binary package dependency package relationship mapping problem - ''' + """ + Description: Binary package dependency package relationship mapping problem + Args: + bin_requires_data: Binary package dependency package data + Returns: + + Raises: + + """ + _bin_pkg_key = bin_requires_data.pkgKey if _bin_pkg_key: if _bin_pkg_key not in self._bin_requires_dicts: @@ -270,9 +331,16 @@ class InitDataBase(): }) def _bin_provides_relation(self, bin_provides_data): - ''' - Binary package provided by the relationship mapping problem - ''' + """ + Description: Binary package provided by the relationship mapping problem + Args: + bin_provides_data: Component data provided by the binary package + Returns: + + Raises: + + """ + _bin_pkg_key = bin_provides_data.pkgKey if _bin_pkg_key: if _bin_pkg_key not in self._bin_provides_dicts: @@ -282,9 +350,16 @@ class InitDataBase(): }) def data_relationship(self, db_file): - ''' - dependencies between combined data - ''' + """ + Description: dependencies between combined data + Args: + db_file: Temporary database file + Returns: + + Raises: + Error information + """ + self._bin_provides_dicts = dict() self._bin_requires_dicts = dict() self._bin_package_name = dict() @@ -320,9 +395,16 @@ class InitDataBase(): LOGGER.logger.error(error_msg) def file_merge(self, src_package_paths, bin_package_paths): - ''' - integration of multiple data files - ''' + """ + Description: integration of multiple data files + Args: + src_package_paths: Source package database file + bin_package_paths: Binary package database file + Returns: + Path of the generated temporary database file + Raises: + DataMergeException: Abnormal data integration + """ _db_file = os.path.join( self._sqlite_db.database_file_folder, 'temporary_database') @@ -361,14 +443,15 @@ class InitDataBase(): return _db_file def __exists_repeat_database(self): - ''' - functional description:Determine if the same database name exists - parameter: - return value: - exception description: - modify record: - ''' + """ + Description: Determine if the same database name exists + Args: + Returns: + True if there are duplicate databases, false otherwise + Raises: + + """ db_names = [name.get('dbname') for name in self.config_file_datas] @@ -378,9 +461,15 @@ class InitDataBase(): return False def _save_bin_package(self, src_packages): - ''' - Save binary package data - ''' + """ + Description: Save binary package data + Args: + src_packages: Source package data + Returns: + Binary package data + Raises: + + """ bin_packages = [] for package_data in src_packages: try: @@ -428,9 +517,15 @@ class InitDataBase(): return bin_packages def _save_bin_provides(self, bin_packages): - ''' - Save package data provided by binary - ''' + """ + Description: Save package data provided by binary + Args: + bin_packages: Binary package data + Returns: + Package data provided by binary + Raises: + + """ bin_provides_list = [] for bin_pack_entity in bin_packages: @@ -459,9 +554,16 @@ class InitDataBase(): return bin_provides_list def save_data(self, db_name): - ''' - save related package data - ''' + """ + Description: save related package data + Args: + db_name: The name of the database + Returns: + + Raises: + + """ + with DBHelper(db_name=db_name) as data_base: # Add source package data data_base.batch_add( @@ -490,13 +592,17 @@ class InitDataBase(): @staticmethod def __updata_settings_file(**Kwargs): - ''' - update some configuration files related to the database in the system - parameter: - **Kwargs:data related to configuration file nodes - database_name: Name database - priority: priority - ''' + """ + Description: update some configuration files related to the database in the system + Args: + **Kwargs: data related to configuration file nodes + database_name: Name database + Returns: + + Raises: + FileNotFoundError: The specified file was not found + IOError: File or network operation io abnormal + """ try: if not os.path.exists(DATABASE_FILE_INFO): pathlib.Path(DATABASE_FILE_INFO).touch() @@ -515,13 +621,16 @@ class InitDataBase(): @staticmethod def delete_settings_file(): - ''' - functional description:Delete the configuration file of the database - parameter: - return value: - exception description: - modify record: - ''' + """ + Description: Delete the configuration file of the database + Args: + + Returns: + True if the deletion is successful, otherwise false + Raises: + IOError: File or network operation io abnormal + """ + try: if os.path.exists(DATABASE_FILE_INFO): os.remove(DATABASE_FILE_INFO) @@ -532,9 +641,15 @@ class InitDataBase(): return True def delete_db(self, db_name): - ''' - Delete the database - ''' + """ + Description: elete the database + Args: + db_name: The name of the database + Returns: + + Raises: + IOError: File or network operation io abnormal + """ if self.db_type == 'mysql': del_result = MysqlDatabaseOperations.drop_database(db_name) else: @@ -560,12 +675,20 @@ class InitDataBase(): class MysqlDatabaseOperations(): - ''' - Related to database operations, creating databases, creating tables - ''' + """ + Description: Related to database operations, creating databases, creating tables + Attributes: + db_name: The name of the database + create_database_sql: SQL statement to create a database + drop_database_sql: Delete the SQL statement of the database + """ def __init__(self, db_name): - + """ + Description: Class instance initialization + Args: + db_name: Database name + """ self.db_name = db_name self.create_database_sql = ''' CREATE DATABASE if not exists `{db_name}` \ DEFAULT CHARACTER SET utf8mb4; '''.format(db_name=self.db_name) @@ -573,9 +696,15 @@ class MysqlDatabaseOperations(): db_name=self.db_name) def create_database(self): - ''' - functional description:create a database - ''' + """ + Description: create a database + Args: + + Returns: + True if successful, otherwise false + Raises: + SQLAlchemyError: An exception occurred while creating the database + """ with DBHelper(db_name='mysql') as data_base: @@ -592,14 +721,15 @@ class MysqlDatabaseOperations(): @classmethod def drop_database(cls, db_name): - ''' - functional description:Delete the database according to the specified name - parameter: - :db_name:The name of the database - return value: - exception description: - modify record: - ''' + """ + Description: Delete the database according to the specified name + Args: + db_name: The name of the database to be deleted + Returns: + True if successful, otherwise false + Raises: + SQLAlchemyError: An exception occurred while creating the database + """ if db_name is None: raise IOError( "The name of the database to be deleted cannot be empty") @@ -615,9 +745,15 @@ class MysqlDatabaseOperations(): return True def __create_tables(self): - ''' - Create the specified data table - ''' + """ + Description: Create the specified data table + Args: + + Returns: + True if successful, otherwise false + Raises: + SQLAlchemyError: An exception occurred while creating the database + """ try: with DBHelper(db_name=self.db_name) as database: tables = ['src_pack', 'bin_pack', 'pack_provides', @@ -631,9 +767,15 @@ class MysqlDatabaseOperations(): return True def create_datum_database(self): - ''' - Create a benchmark database to save the maintainer's information - ''' + """ + Description: Create a benchmark database to save the maintainer's information + Args: + + Returns: + True if successful, otherwise false + Raises: + SQLAlchemyError: An exception occurred while creating the database + """ with DBHelper(db_name='mysql') as data_base: # create database try: @@ -646,9 +788,16 @@ class MysqlDatabaseOperations(): return self.__create_datum_tables() def __create_datum_tables(self): - ''' - Create a data table of maintainer information - ''' + """ + Description: Create a data table of maintainer information + rgs: + + Returns: + True if successful, otherwise false + Raises: + SQLAlchemyError: An exception occurred while creating the database + Error: Error information + """ try: with DBHelper(db_name=self.db_name) as database: tables = ['maintenance_info'] @@ -665,12 +814,20 @@ class MysqlDatabaseOperations(): class SqliteDatabaseOperations(): - ''' - sqlite database related operations - ''' + """ + Description: sqlite database related operations + Attributes: + db_name: Name database + database_file_folder: Database folder path + """ def __init__(self, db_name, **kwargs): - + """ + Description: Class instance initialization + Args: + db_name: Database name + kwargs: data related to configuration file nodes + """ self.db_name = db_name self._read_config = ReadConfig() if getattr(kwargs, 'database_path', None) is None: @@ -678,10 +835,15 @@ class SqliteDatabaseOperations(): else: self.database_file_folder = kwargs.get('database_path') - def database_file_path(self): - ''' - Database file path - ''' + def _database_file_path(self): + """ + Description: Database file path + Args: + Returns: + + Raises: + IOError: File or network operation io abnormal + """ self.database_file_folder = self._read_config.get_system( 'data_base_path') if not self.database_file_folder: @@ -695,16 +857,24 @@ class SqliteDatabaseOperations(): self.database_file_folder = None def create_sqlite_database(self): - ''' - create sqlite database and table - ''' + """ + Description: create sqlite database and table + Args: + + Returns: + After successful generation, return the database file address, + otherwise return none + Raises: + FileNotFoundError: The specified folder path does not exist + SQLAlchemyError: An error occurred while generating the database + """ if self.database_file_folder is None: raise FileNotFoundError('Database folder does not exist') _db_file = os.path.join( self.database_file_folder, self.db_name) - if os.path.exists(_db_file+'.db'): + if os.path.exists(_db_file + '.db'): os.remove(_db_file + '.db') # create a sqlite database @@ -720,12 +890,19 @@ class SqliteDatabaseOperations(): return _db_file def drop_database(self): - ''' - Delete the specified sqlite database - ''' + """ + Description: Delete the specified sqlite database + Args: + + Returns: + Return true after successful deletion, otherwise return false + Raises: + IOError: An io exception occurred while deleting the specified database file + """ + try: db_path = os.path.join( - self.database_file_folder, self.db_name+'.db') + self.database_file_folder, self.db_name + '.db') if os.path.exists(db_path): os.remove(db_path) except IOError as exception_msg: @@ -735,16 +912,24 @@ class SqliteDatabaseOperations(): return True def create_datum_database(self): - ''' - create sqlite database and table - ''' + """ + Description: create sqlite database and table + Args: + + Returns: + After successful generation, return the database file address, + otherwise return none + Raises: + FileNotFoundError: The specified database folder does not exist + SQLAlchemyError: An error occurred while generating the database + """ if self.database_file_folder is None: raise FileNotFoundError('Database folder does not exist') _db_file = os.path.join( self.database_file_folder, self.db_name) - if not os.path.exists(_db_file+'.db'): + if not os.path.exists(_db_file + '.db'): # create a sqlite database with DBHelper(db_name=_db_file) as database: tables = ['maintenance_info'] diff --git a/packageship/packageship/application/initsystem/datamerge.py b/packageship/packageship/application/initsystem/datamerge.py index cea7512a36a41b02183cca38799fd68689aea3c5..687f7e0882800533c5a160ce1da9f4d23a372608 100644 --- a/packageship/packageship/application/initsystem/datamerge.py +++ b/packageship/packageship/application/initsystem/datamerge.py @@ -1,7 +1,8 @@ -''' - Integration of multiple sqlite file data, including - reading sqlite database and inserting data -''' +#!/usr/bin/python3 +""" +Description: Integration of multiple sqlite file data, including reading sqlite database and inserting data +Class: MergeData +""" from sqlalchemy.exc import SQLAlchemyError from packageship.application.models.temporarydb import src_package from packageship.application.models.temporarydb import src_requires @@ -16,30 +17,50 @@ LOGGER = Log(__name__) class MergeData(): - ''' - Load data from sqlite database - ''' + """ + Description: Load data from sqlite database + Attributes: + db_file: Database file + db_type: Connected database type + datum_database: Base database name + """ def __init__(self, db_file): - + """ + Description: Class instance initialization + Args: + db_file: Database file + """ self.db_file = db_file self.db_type = 'sqlite:///' self.datum_database = 'maintenance.information' @staticmethod def __columns(cursor): - ''' - functional description:Returns all the column names queried by the current cursor - ''' + """ + Description: functional description:Returns all the column names queried by the current cursor + Args: + cursor: Cursor + + Returns: + The first columns + Raises: + """ return [col[0] for col in cursor.description] def get_package_data(self): - ''' - get binary package or source package data - ''' + """ + Description: get binary package or source package data + Args: + + Returns: + All source package data queried + Raises: + SQLAlchemyError: An error occurred while executing the sql statement + """ try: - with DBHelper(db_name=self.db_file, db_type=self.db_type, import_database=True)\ + with DBHelper(db_name=self.db_file, db_type=self.db_type, import_database=True) \ as database: src_packages_data = database.session.execute( "select pkgKey,name,version,rpm_license,url,rpm_sourcerpm from packages") @@ -51,11 +72,17 @@ class MergeData(): return None def get_requires_data(self): - ''' - get dependent package data of binary package or source package - ''' + """ + Description: get dependent package data of binary package or source package + Args: + + Returns: + All dependent data queried + Raises: + SQLAlchemyError: An error occurred while executing the sql statement + """ try: - with DBHelper(db_name=self.db_file, db_type=self.db_type, import_database=True)\ + with DBHelper(db_name=self.db_file, db_type=self.db_type, import_database=True) \ as database: requires = database.session.execute( "select pkgKey,name from requires") @@ -66,11 +93,17 @@ class MergeData(): return None def get_provides(self): - ''' - get the dependency package provided by the binary package - ''' + """ + Description: get the dependency package provided by the binary package + Args: + + Returns: + Query the component data provided by all binary packages + Raises: + SQLAlchemyError: An error occurred while executing the sql statement + """ try: - with DBHelper(db_name=self.db_file, db_type=self.db_type, import_database=True)\ + with DBHelper(db_name=self.db_file, db_type=self.db_type, import_database=True) \ as database: requires = database.session.execute( "select pkgKey,name from provides") @@ -81,9 +114,15 @@ class MergeData(): return None def get_maintenance_info(self): - ''' - Obtain the information of the maintainer - ''' + """ + Description: Obtain the information of the maintainer + Args: + + Returns: + Maintainer related information + Raises: + SQLAlchemyError: An error occurred while executing the sql statement + """ try: if not hasattr(self, 'mainter_infos'): self.mainter_infos = dict() @@ -99,9 +138,17 @@ class MergeData(): LOGGER.logger.error(sql_error) def src_file_merge(self, src_package_key, db_file): - ''' - Source code related data integration - ''' + """ + Description: Source code related data integration + Args: + src_package_key: The relevant key value of the source package + db_file: Database file + Returns: + Key value after successful data combination + (0, False) or (src_package_key, True) + Raises: + SQLAlchemyError: An error occurred while executing the sql statement + """ self.get_maintenance_info() self.__compose_src_package() @@ -131,9 +178,15 @@ class MergeData(): return (src_package_key, True) def __compose_src_package(self): - ''' - Combine source package data - ''' + """ + Description: Combine source package data + Args: + + Returns: + + Raises: + + """ if getattr(self, 'src_package_datas', None) is None: self.src_package_datas = [] @@ -154,15 +207,21 @@ class MergeData(): "url": src_package_item.get('url'), "pkgKey": src_package_item.get('pkgKey'), 'maintaniner': - maintenance[0].get('maintaniner') if maintenance and len( - maintenance) > 0 else None + maintenance[0].get('maintaniner') if maintenance and len( + maintenance) > 0 else None } ) def __compose_src_rquires(self): - ''' - Combine source package dependent package data - ''' + """ + Description: Combine source package dependent package data + Args: + + Returns: + + Raises: + + """ if getattr(self, 'src_requires_dicts', None) is None: self.src_requires_dicts = dict() @@ -179,9 +238,15 @@ class MergeData(): ) def __compose_bin_package(self): - ''' - Combine binary package data - ''' + """ + Description: Combine binary package data + Args: + + Returns: + + Raises: + AttributeError + """ if getattr(self, 'bin_package_datas', None) is None: self.bin_package_datas = [] @@ -205,9 +270,14 @@ class MergeData(): ) def __compose_bin_requires(self): - ''' - Combining binary dependent package data - ''' + """ + Description: Combining binary dependent package data + Args: + + Returns: + + Raises: + """ if getattr(self, 'bin_requires_dicts', None) is None: self.bin_requires_dicts = dict() @@ -222,9 +292,15 @@ class MergeData(): }) def __compose_bin_provides(self): - ''' - Combine binary package data - ''' + """ + Description: Combine binary package data + Args: + + Returns: + + Raises: + + """ if getattr(self, 'bin_provides_dicts', None) is None: self.bin_provides_dicts = dict() @@ -239,10 +315,17 @@ class MergeData(): }) def bin_file_merge(self, bin_package_key, db_file): - ''' - Binary package related data integration - ''' - + """ + Description: Binary package related data integration + Args: + bin_package_key: Primary key of binary package + db_file: Database file + Returns: + Key value after successful data combination + (0, False) or (bin_package_key, True) + Raises: + SQLAlchemyError: An error occurred while executing the sql statement + """ self.__compose_bin_package() # binary package dependent package integration diff --git a/packageship/packageship/libs/dbutils/sqlalchemy_helper.py b/packageship/packageship/libs/dbutils/sqlalchemy_helper.py index 93097a61c6e7a6e715c42c51e39f7afdf73fe2c9..407ad2de95deeb9a32352387f94b9a47b11a8052 100644 --- a/packageship/packageship/libs/dbutils/sqlalchemy_helper.py +++ b/packageship/packageship/libs/dbutils/sqlalchemy_helper.py @@ -1,7 +1,8 @@ -''' -Simple encapsulation of sqlalchemy orm framework operation database - -''' +#!/usr/bin/python3 +""" +Description: Simple encapsulation of sqlalchemy orm framework operation database +Class: DBHelper +""" import os from sqlalchemy import create_engine from sqlalchemy import MetaData @@ -18,22 +19,34 @@ from packageship import system_config class DBHelper(): - ''' - Database connection, operation public class - ''' + """ + Description: Database connection, operation public class + Attributes: + user_name: Username + password: Password + ip_address: Ip address + port: Port + db_name: Database name + db_type: Database type + session: Session + """ # The base class inherited by the data model BASE = declarative_base() def __init__(self, user_name=None, passwrod=None, ip_address=None, # pylint: disable=R0913 port=None, db_name=None, db_type=None, **kwargs): + """ + Description: Class instance initialization + + """ self.user_name = user_name self._readconfig = ReadConfig() if self.user_name is None: self.user_name = self._readconfig.get_database('user_name') - self.passwrod = passwrod - if self.passwrod is None: - self.passwrod = self._readconfig.get_database('password') + self.password = passwrod + if self.password is None: + self.password = self._readconfig.get_database('password') self.ip_address = ip_address @@ -67,9 +80,15 @@ class DBHelper(): self.session = None def _create_engine(self): - ''' - Create a database connection object - ''' + """ + Description: Create a database connection object + Args: + + Returns: + Raises: + DisconnectionError: A disconnect is detected on a raw DB-API connection. + + """ if self.db_type.startswith('sqlite'): if not self.db_name: raise DbnameNoneException( @@ -78,11 +97,11 @@ class DBHelper(): self.db_type + self.db_name, encoding='utf-8', convert_unicode=True, connect_args={'check_same_thread': False}) else: - if all([self.user_name, self.passwrod, self.ip_address, self.port, self.db_name]): + if all([self.user_name, self.password, self.ip_address, self.port, self.db_name]): # create connection object self.engine = create_engine(URL(**{'database': self.db_name, 'username': self.user_name, - 'password': self.passwrod, + 'password': self.password, 'host': self.ip_address, 'port': self.port, 'drivername': self.db_type}), @@ -93,9 +112,14 @@ class DBHelper(): 'A disconnect is detected on a raw DB-API connection') def _db_file_path(self): - ''' - load the path stored in the sqlite database - ''' + """ + Description: load the path stored in the sqlite database + Args: + + Returns: + Raises: + + """ self.database_file_path = self._readconfig.get_system( 'data_base_path') if not self.database_file_path: @@ -104,9 +128,15 @@ class DBHelper(): os.makedirs(self.database_file_path) def __enter__(self): - ''' - functional description:Create a context manager for the database connection - ''' + """ + Description: functional description:Create a context manager for the database connection + Args: + + Returns: + Class instance + Raises: + + """ session = sessionmaker() if getattr(self, 'engine') is None: @@ -117,28 +147,42 @@ class DBHelper(): return self def __exit__(self, exc_type, exc_val, exc_tb): - ''' - functional description:Release the database connection pool and close the connection - ''' + """ + Description: functional description:Release the database connection pool and close the connection + Args: + + Returns: + exc_type: Abnormal type + exc_val: Abnormal value + exc_tb: Abnormal table + Raises: + """ self.session.close() @classmethod def create_all(cls, db_name=None): - ''' - functional description:Create all database tables - parameter: - return value: - exception description: - modify record: - ''' + """ + Description: functional description:Create all database tables + Args: + db_name: Database name + Returns: + + Raises: + + """ cls.BASE.metadata.create_all(bind=cls(db_name=db_name).engine) def create_table(self, tables): - ''' - Create a single table - ''' + """ + Description: Create a single table + Args: + tables: Table + Returns: + + Raises: + """ meta = MetaData(self.engine) for table_name in DBHelper.BASE.metadata.tables.keys(): if table_name in tables: @@ -147,12 +191,16 @@ class DBHelper(): table.create() def add(self, entity): - ''' - functional description:Insert a single data entity - parameter: - return value: + """ + Description: Insert a single data entity + Args: + entity: Data entity + Return: If the addition is successful, return the corresponding entity, otherwise return None - ''' + Raises: + ContentNoneException: An exception occurred while content is none + SQLAlchemyError: An exception occurred while creating the database + """ if entity is None: raise ContentNoneException( @@ -168,12 +216,17 @@ class DBHelper(): return entity def batch_add(self, dicts, model): - ''' - functional description:tables for adding databases in bulk - parameter: - :param dicts:Entity dictionary data to be added - :param model:Solid model class - ''' + """ + Description:tables for adding databases in bulk + Args: + dicts:Entity dictionary data to be added + model:Solid model class + Returns: + + Raises: + TypeError: An exception occurred while incoming type does not meet expectations + SQLAlchemyError: An exception occurred while creating the database + """ if model is None: raise ContentNoneException('solid model must be specified') diff --git a/packageship/packageship/pkgship.py b/packageship/packageship/pkgship.py index c22a54094fef58198b87e758d1d0e231497f0fa2..6fb34408803f404fa960b9f28836f27aec8b4f43 100644 --- a/packageship/packageship/pkgship.py +++ b/packageship/packageship/pkgship.py @@ -1,8 +1,12 @@ -''' - Entry method for custom commands -''' +#!/usr/bin/python3 +""" +Description: Entry method for custom commands +Class: BaseCommand,PkgshipCommand,RemoveCommand,InitDatabaseCommand,UpdateDatabaseCommand,AllPackageCommand, + UpdatePackageCommand,BuildDepCommand,InstallDepCommand,SelfBuildCommand,BeDependCommand,SingleCommand +""" import os import json + try: import argparse import requests @@ -13,6 +17,7 @@ try: from packageship.libs.log import Log from packageship.libs.exception import Error from packageship.libs.configutils.readconfig import ReadConfig + LOGGER = Log(__name__) except ImportError as import_error: print('Error importing related dependencies, \ @@ -21,14 +26,19 @@ else: from packageship.application.apps.package.function.constants import ResponseCode from packageship.application.apps.package.function.constants import ListNode - DB_NAME = 0 def main(): - ''' - command entry function - ''' + """ + Description: Command line tool entry, register related commands + Args: + + Returns: + + Raises: + Error: An error occurred while executing the command + """ try: packship_cmd = PkgshipCommand() packship_cmd.parser_args() @@ -38,11 +48,19 @@ def main(): class BaseCommand(): - ''' - Basic attributes used for command invocation - ''' + """ + Description: Basic attributes used for command invocation + Attributes: + write_host: Can write operation single host address + read_host: Can read the host address of the operation + headers: Send HTTP request header information + """ def __init__(self): + """ + Description: Class instance initialization + + """ self._read_config = ReadConfig() self.write_host = None self.read_host = None @@ -54,9 +72,14 @@ class BaseCommand(): self.load_write_host() def load_write_host(self): - ''' - Address to load write permission - ''' + """ + Description: Address to load write permission + Args: + + Returns: + Raises: + + """ wirte_port = self._read_config.get_system('write_port') write_ip = self._read_config.get_system('write_ip_addr') @@ -66,9 +89,14 @@ class BaseCommand(): setattr(self, 'write_host', _write_host) def load_read_host(self): - ''' - Address to load write permission - ''' + """ + Returns:Address to load read permission + Args: + + Returns: + Raises: + + """ read_port = self._read_config.get_system('query_port') read_ip = self._read_config.get_system('query_ip_addr') @@ -79,15 +107,23 @@ class BaseCommand(): class PkgshipCommand(BaseCommand): - ''' - PKG package command line - ''' + """ + Description: PKG package command line + Attributes: + statistics: Summarized data table + table: Output table + columns: Calculate the width of the terminal dynamically + params: Command parameters + """ parser = argparse.ArgumentParser( description='package related dependency management') subparsers = parser.add_subparsers( help='package related dependency management') def __init__(self): + """ + Description: Class instance initialization + """ super(PkgshipCommand, self).__init__() self.statistics = dict() self.table = PkgshipCommand.create_table( @@ -99,15 +135,28 @@ class PkgshipCommand(BaseCommand): @staticmethod def register_command(command): - ''' - Register command - ''' + """ + Description: Registration of related commands + + Args: + command: Related commands + + Returns: + Raises: + + """ command.register() def register(self): - ''' - Command line parameter injection - ''' + """ + Description: Command line parameter injection + Args: + + Returns: + + Raises: + + """ for command_params in self.params: self.parse.add_argument( # pylint: disable=E1101 command_params[0], @@ -117,9 +166,15 @@ class PkgshipCommand(BaseCommand): @classmethod def parser_args(cls): - ''' - Command parsing - ''' + """ + Description: Register the command line and parse related commands + Args: + + Returns: + + Raises: + Error: An error occurred during command parsing + """ cls.register_command(RemoveCommand()) cls.register_command(InitDatabaseCommand()) cls.register_command(UpdateDatabaseCommand()) @@ -137,9 +192,15 @@ class PkgshipCommand(BaseCommand): print('command error') def parse_package(self, response_data): - ''' - Parse the corresponding data of the package - ''' + """ + 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): @@ -151,9 +212,15 @@ class PkgshipCommand(BaseCommand): print(response_data.get('msg')) def parse_depend_package(self, response_data): - ''' - Parse the corresponding data of the package - ''' + """ + Description: Parsing package data with dependencies + Args: + response_data: http request response content + Returns: + Summarized data table + Raises: + + """ bin_package_count = 0 src_package_count = 0 if response_data.get('code') == ResponseCode.SUCCESS: @@ -179,7 +246,7 @@ class PkgshipCommand(BaseCommand): if bin_package not in \ self.statistics[package_depend[ListNode.DBNAME]]['binary']: self.statistics[package_depend[ListNode.DBNAME] - ]['binary'].append(bin_package) + ]['binary'].append(bin_package) bin_package_count += 1 # Determine whether the source package exists if package_depend[ListNode.SOURCE_NAME] not in \ @@ -198,9 +265,17 @@ class PkgshipCommand(BaseCommand): return statistics_table def print_(self, content=None, character='=', dividing_line=False): - ''' - Output formatted characters - ''' + """ + Description: Output formatted characters + Args: + content: Output content + character: Output separator content + dividing_line: Whether to show the separator + Returns: + + Raises: + + """ # Get the current width of the console if dividing_line: @@ -212,9 +287,15 @@ class PkgshipCommand(BaseCommand): @staticmethod def create_table(title): - ''' - Create printed forms - ''' + """ + Description: Create printed forms + Args: + title: Table title + Returns: + ASCII format table + Raises: + + """ table = PrettyTable(title) # table.set_style(prettytable.PLAIN_COLUMNS) table.align = 'l' @@ -225,9 +306,16 @@ class PkgshipCommand(BaseCommand): return table def statistics_table(self, bin_package_count, src_package_count): - ''' - Generate data for total statistical tables - ''' + """ + Description: Generate data for total statistical tables + Args: + bin_package_count: Number of binary packages + src_package_count: Number of source packages + Returns: + Summarized data table + Raises: + + """ statistics_table = self.create_table(['', 'binary', 'source']) statistics_table.add_row( ['self depend sum', bin_package_count, src_package_count]) @@ -240,9 +328,15 @@ class PkgshipCommand(BaseCommand): @staticmethod def http_error(response): - ''' - Log error messages for http - ''' + """ + Description: Log error messages for http + Args: + response: Response content of http request + Returns: + + Raises: + HTTPError: http request error + """ try: print(response.raise_for_status()) except HTTPError as http_error: @@ -252,27 +346,46 @@ class PkgshipCommand(BaseCommand): class RemoveCommand(PkgshipCommand): - ''' - Delete database command - ''' + """ + Description: Delete database command + Attributes: + parse: Command line parsing example + params: Command line parameters + """ def __init__(self): + """ + Description: Class instance initialization + """ super(RemoveCommand, self).__init__() self.parse = PkgshipCommand.subparsers.add_parser( 'rm', help='delete database operation') self.params = [('db', 'str', 'name of the database operated', '')] def register(self): - ''' - Command line parameter injection - ''' + """ + Description: Command line parameter injection + Args: + + Returns: + + Raises: + + """ super(RemoveCommand, self).register() self.parse.set_defaults(func=self.do_command) def do_command(self, params): - ''' - Action to execute command - ''' + """ + Description: Action to execute command + Args: + params: Command line parameters + Returns: + + Raises: + ConnErr: Request connection error + + """ if params.db is None: print('No database specified for deletion') else: @@ -296,11 +409,17 @@ class RemoveCommand(PkgshipCommand): class InitDatabaseCommand(PkgshipCommand): - ''' - Initialize database command - ''' + """ + Description: Initialize database command + Attributes: + parse: Command line parsing example + params: Command line parameters + """ def __init__(self): + """ + Description: Class instance initialization + """ super(InitDatabaseCommand, self).__init__() self.parse = PkgshipCommand.subparsers.add_parser( 'init', help='initialization of the database') @@ -308,22 +427,34 @@ class InitDatabaseCommand(PkgshipCommand): ('-filepath', 'str', 'name of the database operated', '')] def register(self): - ''' - Command line parameter injection - ''' + """ + Description: Command line parameter injection + Args: + + Returns: + + Raises: + + """ super(InitDatabaseCommand, self).register() self.parse.set_defaults(func=self.do_command) def do_command(self, params): - ''' - Action to execute command - ''' + """ + Description: Action to execute command + Args: + params: Command line parameters + Returns: + + Raises: + + """ file_path = params.filepath try: response = requests.post(self.write_host + '/initsystem', data=json.dumps({'configfile': file_path}), headers=self.headers) - except ConnectionError as conn_error: + except ConnErr as conn_error: LOGGER.logger.error(conn_error) print(str(conn_error)) else: @@ -339,11 +470,17 @@ class InitDatabaseCommand(PkgshipCommand): class UpdateDatabaseCommand(PkgshipCommand): - ''' - update database command - ''' + """ + 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( @@ -351,25 +488,44 @@ class UpdateDatabaseCommand(PkgshipCommand): self.params = [('db', 'str', 'name of the database operated', '')] def register(self): - ''' - Command line parameter injection - ''' + """ + 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): - ''' - Action to execute command - ''' + """ + Description: Action to execute command + Args: + + Returns: + + Raises: + + """ pass # pylint: disable= W0107 class AllPackageCommand(PkgshipCommand): - ''' - get all package commands - ''' + """ + Description: get all package commands + Attributes: + parse: Command line parsing example + params: Command line parameters + table: Output table + """ def __init__(self): + """ + Description: Class instance initialization + """ super(AllPackageCommand, self).__init__() self.parse = PkgshipCommand.subparsers.add_parser( @@ -379,18 +535,30 @@ class AllPackageCommand(PkgshipCommand): self.params = [('-db', 'str', 'name of the database operated', '')] def register(self): - ''' - Command line parameter injection - ''' + """ + Description: Command line parameter injection + Args: + + Returns: + + Raises: + + """ super(AllPackageCommand, self).register() self.parse.set_defaults(func=self.do_command) def do_command(self, params): - ''' - Action to execute command - ''' + """ + Description: Action to execute command + Args: + params: Command line parameters + Returns: + + Raises: + ConnectionError: Request connection error + """ _url = self.read_host + \ - '/packages?dbName={dbName}'.format(dbName=params.db) + '/packages?dbName={dbName}'.format(dbName=params.db) try: response = requests.get(_url) except ConnectionError as conn_error: @@ -407,11 +575,17 @@ class AllPackageCommand(PkgshipCommand): class UpdatePackageCommand(PkgshipCommand): - ''' - update package data - ''' + """ + Description: update package data + Attributes: + parse: Command line parsing example + params: Command line parameters + """ def __init__(self): + """ + Description: Class instance initialization + """ super(UpdatePackageCommand, self).__init__() self.parse = PkgshipCommand.subparsers.add_parser( @@ -424,16 +598,28 @@ class UpdatePackageCommand(PkgshipCommand): ] def register(self): - ''' - Command line parameter injection - ''' + """ + Description: Command line parameter injection + Args: + + Returns: + + Raises: + + """ super(UpdatePackageCommand, self).register() self.parse.set_defaults(func=self.do_command) def do_command(self, params): - ''' - Action to execute command - ''' + """ + Description: Action to execute command + Args: + params: Command line parameters + Returns: + + Raises: + ConnectionError: Request connection error + """ _url = self.write_host + '/packages/findByPackName' try: response = requests.put( @@ -458,11 +644,19 @@ class UpdatePackageCommand(PkgshipCommand): class BuildDepCommand(PkgshipCommand): - ''' - query the compilation dependencies of the specified package - ''' + """ + Description: query the compilation dependencies of the specified package + Attributes: + parse: Command line parsing example + params: Command line parameters + collection: Is there a collection parameter + collection_params: Command line collection parameters + """ def __init__(self): + """ + Description: Class instance initialization + """ super(BuildDepCommand, self).__init__() self.parse = PkgshipCommand.subparsers.add_parser( @@ -476,9 +670,15 @@ class BuildDepCommand(PkgshipCommand): ] def register(self): - ''' - Command line parameter injection - ''' + """ + Description: Command line parameter injection + Args: + + Returns: + + Raises: + + """ super(BuildDepCommand, self).register() # collection parameters @@ -488,9 +688,15 @@ class BuildDepCommand(PkgshipCommand): self.parse.set_defaults(func=self.do_command) def do_command(self, params): - ''' - Action to execute command - ''' + """ + Description: Action to execute command + Args: + params: Command line parameters + Returns: + + Raises: + ConnectionError: Request connection error + """ _url = self.read_host + '/packages/findBuildDepend' try: response = requests.post( @@ -515,11 +721,19 @@ class BuildDepCommand(PkgshipCommand): class InstallDepCommand(PkgshipCommand): - ''' - query the installation dependencies of the specified package - ''' + """ + Description: query the installation dependencies of the specified package + Attributes: + parse: Command line parsing example + params: Command line parameters + collection: Is there a collection parameter + collection_params: Command line collection parameters + """ def __init__(self): + """ + Description: Class instance initialization + """ super(InstallDepCommand, self).__init__() self.parse = PkgshipCommand.subparsers.add_parser( @@ -533,9 +747,15 @@ class InstallDepCommand(PkgshipCommand): ] def register(self): - ''' - Command line parameter injection - ''' + """ + Description: Command line parameter injection + Args: + + Returns: + + Raises: + + """ super(InstallDepCommand, self).register() # collection parameters @@ -545,9 +765,15 @@ class InstallDepCommand(PkgshipCommand): self.parse.set_defaults(func=self.do_command) def parse_package(self, response_data): - ''' - Parse the corresponding data of the package - ''' + """ + Description: Parse the corresponding data of the package + Args: + response_data: http response data + Returns: + + Raises: + + """ if getattr(self, 'statistics'): setattr(self, 'statistics', dict()) bin_package_count = 0 @@ -573,7 +799,7 @@ class InstallDepCommand(PkgshipCommand): if bin_package not in \ self.statistics[package_depend[ListNode.DBNAME]]['binary']: self.statistics[package_depend[ListNode.DBNAME] - ]['binary'].append(bin_package) + ]['binary'].append(bin_package) bin_package_count += 1 # Determine whether the source package exists if package_depend[ListNode.SOURCE_NAME] not in \ @@ -593,9 +819,15 @@ class InstallDepCommand(PkgshipCommand): return statistics_table def do_command(self, params): - ''' - Action to execute command - ''' + """ + Description: Action to execute command + Args: + params: Command line parameters + Returns: + + Raises: + ConnectionError: requests connection error + """ _url = self.read_host + '/packages/findInstallDepend' try: response = requests.post(_url, data=json.dumps( @@ -621,11 +853,19 @@ class InstallDepCommand(PkgshipCommand): class SelfBuildCommand(PkgshipCommand): - ''' - self-compiled dependency query - ''' + """ + Description: self-compiled dependency query + Attributes: + parse: Command line parsing example + params: Command line parameters + collection: Is there a collection parameter + collection_params: Command line collection parameters + """ def __init__(self): + """ + Description: Class instance initialization + """ super(SelfBuildCommand, self).__init__() self.parse = PkgshipCommand.subparsers.add_parser( @@ -647,9 +887,15 @@ class SelfBuildCommand(PkgshipCommand): ] def register(self): - ''' - Command line parameter injection - ''' + """ + Description: Command line parameter injection + Args: + + Returns: + + Raises: + + """ super(SelfBuildCommand, self).register() # collection parameters @@ -659,9 +905,16 @@ class SelfBuildCommand(PkgshipCommand): self.parse.set_defaults(func=self.do_command) def _parse_bin_package(self, bin_packages): - ''' - Parsing binary result data - ''' + """ + Description: Parsing binary result data + Args: + bin_packages: Binary package data + + Returns: + + Raises: + + """ bin_package_count = 0 if bin_packages: for bin_package, package_depend in bin_packages.items(): @@ -681,19 +934,26 @@ class SelfBuildCommand(PkgshipCommand): if bin_package not in \ self.statistics[package_depend[ListNode.DBNAME]]['binary']: self.statistics[package_depend[ListNode.DBNAME] - ]['binary'].append(bin_package) + ]['binary'].append(bin_package) bin_package_count += 1 self.bin_package_table.add_row(row_data) return bin_package_count - def _parse_src_package(self, src_apckages): - ''' - Source package data analysis - ''' + def _parse_src_package(self, src_packages): + """ + Description: Source package data analysis + Args: + src_packages: Source package + + Returns: + Source package data + Raises: + + """ src_package_count = 0 - if src_apckages: - for src_package, package_depend in src_apckages.items(): + if src_packages: + for src_package, package_depend in src_packages.items(): # distinguish whether the current data is the data of the root node if isinstance(package_depend, list): @@ -708,7 +968,7 @@ class SelfBuildCommand(PkgshipCommand): # Determine whether the current binary package exists if src_package not in self.statistics[package_depend[DB_NAME]]['source']: self.statistics[package_depend[DB_NAME] - ]['source'].append(src_package) + ]['source'].append(src_package) src_package_count += 1 self.src_package_table.add_row(row_data) @@ -716,9 +976,15 @@ class SelfBuildCommand(PkgshipCommand): return src_package_count def parse_package(self, response_data): - ''' - Parse the corresponding data of the package - ''' + """ + Description: Parse the corresponding data of the package + Args: + response_data: http response data + Returns: + Summarized data table + Raises: + + """ if getattr(self, 'statistics'): setattr(self, 'statistics', dict()) bin_package_count = 0 @@ -744,9 +1010,15 @@ class SelfBuildCommand(PkgshipCommand): return statistics_table def do_command(self, params): - ''' - Action to execute command - ''' + """ + Description: Action to execute command + Args: + params: commands lines params + Returns: + + Raises: + ConnectionError: requests connection error + """ _url = self.read_host + '/packages/findSelfDepend' try: response = requests.post(_url, @@ -778,11 +1050,17 @@ class SelfBuildCommand(PkgshipCommand): class BeDependCommand(PkgshipCommand): - ''' - dependent query - ''' + """ + Description: dependent query + Attributes: + parse: Command line parsing example + params: Command line parameters + """ def __init__(self): + """ + Description: Class instance initialization + """ super(BeDependCommand, self).__init__() self.parse = PkgshipCommand.subparsers.add_parser( @@ -794,16 +1072,28 @@ class BeDependCommand(PkgshipCommand): ] def register(self): - ''' - Command line parameter injection - ''' + """ + Description: Command line parameter injection + Args: + + Returns: + + Raises: + + """ super(BeDependCommand, self).register() self.parse.set_defaults(func=self.do_command) def do_command(self, params): - ''' - Action to execute command - ''' + """ + Description: Action to execute command + Args: + params: command lines params + Returns: + + Raises: + ConnectionError: requests connection error + """ _url = self.read_host + '/packages/findBeDepend' try: response = requests.post(_url, data=json.dumps( @@ -813,7 +1103,7 @@ class BeDependCommand(PkgshipCommand): 'withsubpack': str(params.w) } ), headers=self.headers) - except ConnectionError as conn_error: + except ConnErr as conn_error: LOGGER.logger.error(conn_error) print(str(conn_error)) else: @@ -831,11 +1121,17 @@ class BeDependCommand(PkgshipCommand): class SingleCommand(PkgshipCommand): - ''' - query single package information - ''' + """ + Description: query single package information + Attributes: + parse: Command line parsing example + params: Command line parameters + """ def __init__(self): + """ + Description: Class instance initialization + """ super(SingleCommand, self).__init__() self.parse = PkgshipCommand.subparsers.add_parser( @@ -846,16 +1142,28 @@ class SingleCommand(PkgshipCommand): ] def register(self): - ''' - Command line parameter injection - ''' + """ + Description: Command line parameter injection + Args: + + Returns: + + Raises: + + """ super(SingleCommand, self).register() self.parse.set_defaults(func=self.do_command) def parse_package(self, response_data): - ''' - Parse the corresponding data of the package - ''' + """ + Description: Parse the corresponding data of the package + Args: + response_data: http response data + Returns: + + Raises: + + """ show_field_name = ('sourceName', 'dbname', 'version', 'license', 'maintainer', 'maintainlevel') print_contents = [] @@ -867,10 +1175,9 @@ class SingleCommand(PkgshipCommand): 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) + print_contents.append('=' * self.columns) else: print(response_data.get('msg')) if print_contents: @@ -878,12 +1185,18 @@ class SingleCommand(PkgshipCommand): self.print_(content=content) def do_command(self, params): - ''' - Action to execute command - ''' + """ + Description: Action to execute command + Args: + params: command lines params + Returns: + + Raises: + ConnectionError: requests connection error + """ _url = self.read_host + \ - '/packages/findByPackName?dbName={db_name}&sourceName={packagename}' \ - .format(db_name=params.db, packagename=params.packagename) + '/packages/findByPackName?dbName={db_name}&sourceName={packagename}' \ + .format(db_name=params.db, packagename=params.packagename) try: response = requests.get(_url) except ConnectionError as conn_error: