From 77e7c17363ac0db31b74a9c6e414ad2dc5f2e3d1 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Wed, 13 Feb 2019 17:04:20 +0100 Subject: [PATCH] Completed class ModuleReleaseInfo --- lib/webhooks/forge_module_info.py | 273 ++++++++++++++++++++++++++++-- lib/webhooks/get_forge_modules.py | 13 +- 2 files changed, 268 insertions(+), 18 deletions(-) diff --git a/lib/webhooks/forge_module_info.py b/lib/webhooks/forge_module_info.py index ed07a96..d878f89 100644 --- a/lib/webhooks/forge_module_info.py +++ b/lib/webhooks/forge_module_info.py @@ -28,7 +28,7 @@ from .xlate import XLATOR from .base_module_info import BaseModuleInfoError, BaseModuleInfo -__version__ = '0.2.0' +__version__ = '0.3.0' LOG = logging.getLogger(__name__) @@ -61,19 +61,14 @@ class ForgeModuleInfoTypeError(ForgeModuleInfoError, TypeError): # ============================================================================= -class ModuleReleaseInfo(BaseModuleInfo): +class ModuleReleaseInfo(FbBaseObject): """Class for encapsulating information about a Puppet module release from Puppet Forge.""" - re_split_name = re.compile(r'^\s*([a-z0-9]+)[-/_](\S+)\s*$', re.IGNORECASE) - # ------------------------------------------------------------------------- def __init__( self, appname=None, verbose=0, version=__version__, base_dir=None, - initialized=None, name=None, vendor=None, full_name=None): + initialized=None): - self._name = None - self._vendor = None - self._full_name_orig = None self._created_at = None self._deleted_at = None self._file_size = None @@ -81,9 +76,240 @@ class ModuleReleaseInfo(BaseModuleInfo): self._slug = None self._supported = None self._uri = None - self._version = None + self._release_version = None super(ModuleReleaseInfo, self).__init__( + appname=appname, verbose=verbose, version=version, base_dir=base_dir, initialized=False) + + if initialized is not None: + self.initialized = initialized + + # ------------------------------------------------------------------------- + def as_dict(self, short=True): + """ + Transforms the elements of the object into a dict + + @return: structure as dict + @rtype: dict + """ + + res = super(ModuleReleaseInfo, self).as_dict(short=short) + + res['created_at'] = self.created_at + res['deleted_at'] = self.deleted_at + res['file_size'] = self.file_size + res['file_uri'] = self.file_uri + res['slug'] = self.slug + res['supported'] = self.supported + res['uri'] = self.uri + res['release_version'] = self.release_version + + return res + + # ------------------------------------------------------------------------- + @property + def created_at(self): + """Creation date of this release.""" + return self._created_at + + @created_at.setter + def created_at(self, value): + if value is None: + self._created_at = None + return + if isinstance(value, datetime.datetime): + self._created_at = value + return + v = str(value).strip() + if value == '': + self._created_at = None + return + self._created_at = parse_forge_date(v) + + # ------------------------------------------------------------------------- + @property + def deleted_at(self): + """Deletion date of this release.""" + return self._deleted_at + + @deleted_at.setter + def deleted_at(self, value): + if value is None: + self._deleted_at = None + return + if isinstance(value, datetime.datetime): + self._deleted_at = value + return + v = str(value).strip() + if value == '': + self._deleted_at = None + return + self._deleted_at = parse_forge_date(v) + + # ------------------------------------------------------------------------- + @property + def file_size(self): + """The file size in bytes of this release.""" + return self._file_size + + @file_size.setter + def file_size(self, value): + if value is None: + self._file_size = None + return + v = int(value) + if v < 0: + msg = _( + "The file size of a release must be greater or equal to zero " + "(Given: {}).").format(value) + raise ValueError(msg) + self._file_size = v + + # ------------------------------------------------------------------------- + @property + def file_uri(self): + """The file URI of this release.""" + return self._file_uri + + @file_uri.setter + def file_uri(self, value): + if value is None: + self._file_uri = None + return + v = str(value).strip() + if value == '': + self._file_uri = None + return + self._file_uri = v + + # ------------------------------------------------------------------------- + @property + def slug(self): + """The slug of this release.""" + return self._slug + + @slug.setter + def slug(self, value): + if value is None: + self._slug = None + return + v = str(value).strip() + if value == '': + self._slug = None + return + self._slug = v + + # ------------------------------------------------------------------------- + @property + def supported(self): + """The URI of this release.""" + return self._supported + + @supported.setter + def supported(self, value): + if value is None: + self._supported = None + return + self._supported = to_bool(value) + + # ------------------------------------------------------------------------- + @property + def uri(self): + """The URI of this release.""" + return self._uri + + @uri.setter + def uri(self, value): + if value is None: + self._uri = None + return + v = str(value).strip() + if value == '': + self._uri = None + return + self._uri = v + + # ------------------------------------------------------------------------- + @property + def release_version(self): + """The URI of this release.""" + return self._release_version + + @release_version.setter + def release_version(self, value): + if value is None: + self._release_version = None + return + v = str(value).strip() + if value == '': + self._release_version = None + return + self._release_version = v + + # ------------------------------------------------------------------------- + def to_data(self): + """Returning a dict, which can be used to re-instantiate this module info.""" + + res = {} + + res['created_at'] = None + if self.created_at: + res['created_at'] = self.created_at.strftime('%Y-%m-%d %H:%M:%S %z') + + res['deleted_at'] = None + if self.deleted_at: + res['deleted_at'] = self.deleted_at.strftime('%Y-%m-%d %H:%M:%S %z') + + res['file_size'] = self.file_size + res['file_uri'] = self.file_uri + res['slug'] = self.slug + res['supported'] = self.supported + res['uri'] = self.uri + res['version'] = self.release_version + + return res + + + # ------------------------------------------------------------------------- + @classmethod + def get_from_forge(cls, data, appname=None, verbose=0, base_dir=None): + + release = cls(appname=appname, verbose=verbose, base_dir=base_dir) + + if 'created_at' in data and data['created_at']: + release.created_at = data['created_at'] + if 'deleted_at' in data and data['deleted_at']: + release.deleted_at = data['deleted_at'] + if 'file_size' in data and data['file_size']: + release.file_size = data['file_size'] + if 'file_uri' in data and data['file_uri']: + release.file_uri = data['file_uri'] + if 'slug' in data and data['slug']: + release.slug = data['slug'] + if 'supported' in data and data['supported']: + release.supported = data['supported'] + if 'uri' in data and data['uri']: + release.uri = data['uri'] + if 'version' in data and data['version']: + release.release_version = data['version'] + + if verbose > 2: + LOG.debug(_("Got {}:").format(cls.__name__) + '\n' + pp(release.as_dict())) + + return release + +# ============================================================================= +class ForgeModuleInfo(BaseModuleInfo): + """Class for encapsulating all information about a Puppet module from Puppet Forge.""" + + # ------------------------------------------------------------------------- + def __init__( + self, appname=None, verbose=0, version=__version__, base_dir=None, + initialized=None, name=None, vendor=None, full_name=None): + + self.releases = [] + + super(ForgeModuleInfo, self).__init__( appname=appname, verbose=verbose, version=version, base_dir=base_dir, initialized=False, name=name, vendor=vendor, full_name=full_name ) @@ -91,6 +317,17 @@ class ModuleReleaseInfo(BaseModuleInfo): if initialized is not None: self.initialized = initialized + # ------------------------------------------------------------------------- + def as_dict(self, short=True): + + res = super(ForgeModuleInfo, self).as_dict(short=short) + + res['releases'] = [] + for release in self.releases: + res['releases'].append(release.as_dict(short=short)) + + return res + # ------------------------------------------------------------------------- @classmethod def get_from_forge( @@ -129,7 +366,7 @@ class ModuleReleaseInfo(BaseModuleInfo): LOG.debug(msg) try: - release_info = cls( + module_info = cls( appname=appname, verbose=verbose, base_dir=base_dir, full_name=full_name, ) @@ -137,10 +374,17 @@ class ModuleReleaseInfo(BaseModuleInfo): LOG.warn("{c}: {e}".format(c=e.__class__.__name__, e=e)) return None - version = None - source = None + js_info = response.json() + if verbose > 4: + LOG.debug("Performing forge data:\n" + pp(js_info)) + + if 'releases' in js_info: + for rel in js_info['releases']: + release = ModuleReleaseInfo.get_from_forge( + rel, appname=appname, verbose=verbose, base_dir=base_dir) + if release: + module_info.releases.append(release) -# js_info = response.json() # if 'current_release' in js_info and js_info['current_release']: # if 'version' in js_info['current_release']: # version = js_info['current_release']['version'] @@ -176,8 +420,7 @@ class ModuleReleaseInfo(BaseModuleInfo): # module_info.set_ts_checked() - return release_info - + return module_info # ============================================================================= diff --git a/lib/webhooks/get_forge_modules.py b/lib/webhooks/get_forge_modules.py index 9fa606c..41e1fcf 100644 --- a/lib/webhooks/get_forge_modules.py +++ b/lib/webhooks/get_forge_modules.py @@ -38,7 +38,7 @@ from . import __version__ from .base_app import BaseHookError, BaseHookApp -from .forge_module_info import ModuleReleaseInfo +from .forge_module_info import ForgeModuleInfo from .module_info import ModuleInfo @@ -240,13 +240,17 @@ class GetForgeModulesApp(BaseHookApp): self.print_out(msg) modules_done = [] + i = 0 for env in self.environments: for full_name in self.env_modules[env].keys(): if full_name in modules_done: continue - self.get_forge_module_info(full_name) + modules_done.append(full_name) + i += 1 + if i >= 3: + break if not self.verbose: if self.modules[full_name].forge_avail: print('.', end='', flush=True) @@ -258,10 +262,13 @@ class GetForgeModulesApp(BaseHookApp): # ------------------------------------------------------------------------- def get_forge_module_info(self, full_name): - release_info = ModuleReleaseInfo.get_from_forge( + release_info = ForgeModuleInfo.get_from_forge( full_name, forge_uri=self.forge_uri, http_timeout=self.http_timeout, appname=self.appname, verbose=self.verbose, base_dir=self.base_dir, ) + if self.verbose > 2: + LOG.debug(_("Got module info from Forge:") + '\n' + pp(release_info.as_dict())) + # module_info = self.modules[full_name] # # module_info_forge = ModuleInfo.get_from_forge( -- 2.39.5