File indexing completed on 2024-03-24 03:55:15
0001 # -*- coding: utf-8 -*- 0002 # 0003 # SPDX-FileCopyrightText: 2016 Olivier Churlaud <olivier@churlaud.com> 0004 # 0005 # SPDX-License-Identifier: BSD-2-Clause 0006 0007 import logging 0008 import os.path 0009 import string 0010 from kapidox import utils 0011 0012 ## @package kapidox.models 0013 # 0014 # Contains the classes representing the objects used by kapidox 0015 # 0016 0017 class Library(object): 0018 """ Library 0019 """ 0020 0021 def __init__(self, metainfo, products, platforms, all_maintainers): 0022 """ 0023 Constructor of the Library object 0024 0025 Args: 0026 metainfo: (dict) dictionary describing a library 0027 products: (list of Products) list of all already created products 0028 platforms: (dict) dictionary of all platforms for which the library 0029 is available, where the key is a platform and the value 0030 is a restriction. For instance: 0031 { 0032 'Linux': '', 0033 'Windows': 'Tested with Windows 10 only' 0034 } 0035 would work. 0036 all_maintainers: (dict of dict) all possible maintainers, where the main key 0037 is a username/unique pseudo, and the key is a dictionary of name, 0038 email address. For example: 0039 { 0040 'username01': { 'name': 'Paul Developer', 'email': 'mail@example.com' }, 0041 'username02': { 'name': 'Marc Developer2', 'email': 'mail2@example.com' } 0042 } 0043 would work. 0044 0045 """ 0046 self.product = None 0047 self.subproduct = None 0048 0049 if 'group' in metainfo: 0050 productname = metainfo['group'] 0051 self.part_of_group = True 0052 else: 0053 productname = metainfo['name'] 0054 self.part_of_group = False 0055 if utils.serialize_name(productname) not in products: 0056 productname = metainfo['name'] 0057 del metainfo['group'] 0058 products[utils.serialize_name(metainfo['name'])] = Product(metainfo, all_maintainers) 0059 self.part_of_group = False 0060 logging.warning("Group of {fancyname} not found: dropped.".format_map(metainfo)) 0061 self.product = products[utils.serialize_name(productname)] 0062 if self.product is None: 0063 raise ValueError("'{name}' does not belong to a product." 0064 .format_map(metainfo)) 0065 0066 if 'subgroup' in metainfo and self.part_of_group: 0067 for sp in self.product.subproducts: 0068 if sp.name == utils.serialize_name(metainfo['subgroup']): 0069 self.subproduct = sp 0070 if self.subproduct is None: 0071 logging.warning("Subgroup {subgroup} of library {name} not documented, subgroup will be None" 0072 .format_map(metainfo)) 0073 0074 if self.subproduct is not None: 0075 self.parent = self.subproduct 0076 self.subproduct.libraries.append(self) 0077 else: 0078 self.parent = self.product 0079 self.product.libraries.append(self) 0080 0081 self.metainfo = metainfo 0082 self.name = metainfo['name'] 0083 self.fancyname = metainfo['fancyname'] 0084 self.description = metainfo.get('description') 0085 self.maintainers = utils.set_maintainers(metainfo.get('maintainer'), all_maintainers) 0086 self.platforms = platforms 0087 self.outputdir = self._set_outputdir(self.part_of_group) 0088 self.href = '../' + self.outputdir.lower() + '/html/index.html' 0089 self.path = metainfo['path'] 0090 self.srcdirs = utils.tolist(metainfo.get('public_source_dirs', ['src'])) 0091 self.docdir = utils.tolist(metainfo.get('public_doc_dir', ['docs'])) 0092 if 'public_example_dirs' in metainfo: 0093 self.exampledirs = utils.tolist(metainfo.get('public_example_dirs', ['examples'])) 0094 else: 0095 # backward compat 0096 self.exampledirs = utils.tolist(metainfo.get('public_example_dir', ['examples'])) 0097 self.dependency_diagram = None 0098 self.type = metainfo.get('type', '') 0099 self.portingAid = metainfo.get('portingAid', False) 0100 self.deprecated = metainfo.get('deprecated', False) 0101 self.libraries = metainfo.get('libraries', []) 0102 self.cmakename = metainfo.get('cmakename', '') 0103 self.irc = metainfo.get('irc', self.product.irc) 0104 self.mailinglist = metainfo.get('mailinglist', self.product.mailinglist) 0105 self.repopath = utils.set_repopath(metainfo['repo_id']) 0106 0107 def _extend_parent(self, metainfo, key, key_obj, default): 0108 if key in metainfo: 0109 return metainfo[key] 0110 elif getattr(self.product, key_obj) is not None: 0111 return getattr(self.product, key_obj) 0112 else: 0113 return default 0114 0115 def _set_outputdir(self, grouped): 0116 outputdir = self.name 0117 if grouped: 0118 outputdir = os.path.join(self.product.outputdir, outputdir) 0119 return outputdir.lower() 0120 0121 0122 class Product(object): 0123 """ Product 0124 """ 0125 0126 # TODO: If no name and no group, it will fail ! 0127 def __init__(self, metainfo, all_maintainers): 0128 """ 0129 Constructor of the Product object 0130 0131 Args: 0132 metainfo: (dict) dictionary describing a product 0133 all_maintainers: (dict of dict) all possible maintainers, where the main key 0134 is a username/unique pseudo, and the key is a dictionary of name, 0135 email address. For example: 0136 { 0137 'username01': { 'name': 'Paul Developer', 'email': 'mail@example.com' }, 0138 'username02': { 'name': 'Marc Developer2', 'email': 'mail2@example.com' } 0139 } 0140 would work. 0141 0142 """ 0143 0144 self.metainfo = metainfo 0145 self.parent = None 0146 # if there is a group, the product is the group 0147 # else the product is directly the library 0148 0149 if 'group_info' in metainfo: 0150 self.name = utils.serialize_name(metainfo['group_info'].get('name', metainfo.get('group'))) 0151 self.fancyname = metainfo['group_info'].get('fancyname', string.capwords(self.name)) 0152 self.description = metainfo['group_info'].get('description') 0153 self.long_description = metainfo['group_info'].get('long_description', []) 0154 self.maintainers = utils.set_maintainers(metainfo['group_info'].get('maintainer'), 0155 all_maintainers) 0156 self.platforms = metainfo['group_info'].get('platforms') 0157 self.outputdir = self.name 0158 self.href = self.outputdir + '/index.html' 0159 self.logo_url_src = self._set_logo_src(metainfo['path'], 0160 metainfo['group_info']) 0161 self.logo_url = self._set_logo() 0162 self.libraries = [] # We'll set this later 0163 self.subgroups = [] # We'll set this later 0164 self.irc = metainfo['group_info'].get('irc', 'kde-devel') 0165 self.mailinglist = metainfo['group_info'].get('mailinglist', 'kde-devel') 0166 self.subproducts = self._extract_subproducts(metainfo['group_info']) 0167 self.part_of_group = True 0168 0169 elif 'group' not in metainfo: 0170 self.name = utils.serialize_name(metainfo['name']) 0171 self.fancyname = metainfo['fancyname'] 0172 self.description = metainfo.get('description') 0173 self.maintainers = utils.set_maintainers(metainfo.get('maintainer'), all_maintainers) 0174 self.platforms = [x['name'] for x in metainfo.get('platforms', [{'name': None}])] 0175 self.outputdir = self.name 0176 self.href = self.outputdir + '/html/index.html' 0177 self.logo_url_src = self._set_logo_src(metainfo['path'], metainfo) 0178 self.logo_url = self._set_logo() 0179 self.libraries = [] 0180 self.irc = None 0181 self.mailinglist = None 0182 self.part_of_group = False 0183 else: 0184 raise ValueError("I do not recognize a product in {name}." 0185 .format_map(metainfo)) 0186 0187 def _extract_subproducts(self, groupinfo): 0188 subproducts = [] 0189 if 'subgroups' in groupinfo: 0190 for sg in groupinfo['subgroups']: 0191 if 'name' in sg: 0192 subproducts.append(Subproduct(sg, self)) 0193 return subproducts 0194 0195 def _set_logo(self): 0196 if self.logo_url_src is not None: 0197 filename, ext = os.path.splitext(self.logo_url_src) 0198 return os.path.join(self.outputdir, self.name) + ext 0199 else: 0200 return None 0201 0202 def _set_logo_src(self, path, dct): 0203 defined_not_found = False 0204 if 'logo' in dct: 0205 logo_url = os.path.join(path, dct['logo']) 0206 if os.path.isfile(logo_url): 0207 return logo_url 0208 else: 0209 defined_not_found = True 0210 0211 logo_url = os.path.join(path, 'logo.png') 0212 if os.path.isfile(logo_url): 0213 if defined_not_found: 0214 logging.warning(f'Defined {self.fancyname} logo file does not exist, set back to found logo.png') 0215 return logo_url 0216 0217 if defined_not_found: 0218 logging.warning(f'Defined {self.fancyname} logo file does not exist, set back to None') 0219 0220 return None 0221 0222 0223 class Subproduct(object): 0224 """ Subproduct 0225 """ 0226 def __init__(self, spinfo, product): 0227 """ 0228 Constructor of the Subproduct object 0229 0230 Args: 0231 spinfo: (dict) description of the subproduct. It is not more than: 0232 { 0233 'name': 'Subproduct Name', 0234 'description': 'This subproduct does this and that', 0235 'order': 3, # this is optional 0236 } 0237 for example. 0238 product: (Product) the product it is part of. 0239 """ 0240 self.fancyname = spinfo['name'] 0241 self.name = utils.serialize_name(spinfo['name']) 0242 self.description = spinfo.get('description') 0243 self.order = spinfo.get('order', 99) # If no order, go to end 0244 self.libraries = [] 0245 self.product = product 0246 self.parent = product