--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+@author: Frank Brehm
+@contact: frank.brehm@pixelpark.com
+@copyright: © 2023 by Frank Brehm, Digitas Pixelpark GmbH, Berlin
+@summary: A module for encapsulating all information about a Puppet module
+"""
+from __future__ import absolute_import
+
+# Standard modules
+import logging
+import copy
+import datetime
+
+# Thisrd party modules
+from fb_tools.common import to_bool
+
+# Own modules
+from .. import pp
+from ..xlate import XLATOR
+
+from . import parse_forge_date
+
+from ..module_metadata import ModuleMetadata
+
+from .mod_release_info import ModuleReleaseInfo
+
+from .base_module_info import BaseForgeModuleInfo
+
+__version__ = '0.2.0'
+
+LOG = logging.getLogger(__name__)
+
+_ = XLATOR.gettext
+ngettext = XLATOR.ngettext
+
+
+# =============================================================================
+class CurrentModuleReleaseInfo(ModuleReleaseInfo):
+ """Class for encapsulating information about the current release of a Puppet module
+ from Puppet Forge."""
+
+ # -------------------------------------------------------------------------
+ def __init__(
+ self, appname=None, verbose=0, version=__version__, base_dir=None,
+ initialized=None):
+
+ self._changelog = None
+ self._deleted_for = None
+ self._downloads = None
+ self._file_md5 = None
+ self._license = None
+ self.metadata = None
+ self.module = None
+ self._pdk = False
+ self._readme = None
+ self._reference = None
+ self.tags = []
+ self.tasks = []
+ self._updated_at = None
+ self._validation_score = None
+
+ super(CurrentModuleReleaseInfo, 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(CurrentModuleReleaseInfo, self).as_dict(short=short)
+
+ res['changelog'] = self.changelog
+ res['deleted_for'] = self.deleted_for
+ res['downloads'] = self.downloads
+ res['file_md5'] = self.file_md5
+ res['license'] = self.license
+ res['pdk'] = self.pdk
+ res['readme'] = self.readme
+ res['reference'] = self.reference
+ res['updated_at'] = self.updated_at
+ res['validation_score'] = self.validation_score
+
+ return res
+
+ # -------------------------------------------------------------------------
+ @property
+ def changelog(self):
+ """The change log of this module release."""
+ return self._changelog
+
+ @changelog.setter
+ def changelog(self, value):
+ if value is None:
+ self._changelog = None
+ return
+ v = str(value).strip()
+ if v == '':
+ self._changelog = None
+ return
+ self._changelog = v
+
+ # -------------------------------------------------------------------------
+ @property
+ def deleted_for(self):
+ """The reason, why this module release was deleted."""
+ return self._deleted_for
+
+ @deleted_for.setter
+ def deleted_for(self, value):
+ if value is None:
+ self._deleted_for = None
+ return
+ v = str(value).strip()
+ if v == '':
+ self._deleted_for = None
+ return
+ self._deleted_for = v
+
+ # -------------------------------------------------------------------------
+ @property
+ def downloads(self):
+ "The number of downloads of this module release."""
+ return self._downloads
+
+ @downloads.setter
+ def downloads(self, value):
+ if value is None:
+ self._downloads = None
+ return
+ try:
+ v = int(value)
+ self._downloads = v
+ return
+ except Exception as e:
+ LOG.error(_("Got a {c} setting {w}: {e}").format(
+ c=e.__class__.__name__, w='downloads', e=e))
+
+ # -------------------------------------------------------------------------
+ @property
+ def file_md5(self):
+ """The MD5-sum of the current release package."""
+ return self._file_md5
+
+ @file_md5.setter
+ def file_md5(self, value):
+ if value is None:
+ self._file_md5 = None
+ return
+ v = str(value).strip()
+ if v == '':
+ self._file_md5 = None
+ return
+ self._file_md5 = v
+
+ # -------------------------------------------------------------------------
+ @property
+ def license(self):
+ """The license of module source."""
+ return self._license
+
+ @license.setter
+ def license(self, value):
+ if value is None:
+ self._license = None
+ return
+ v = str(value).strip()
+ if v == '':
+ self._license = None
+ return
+ self._license = v
+
+ # -------------------------------------------------------------------------
+ @property
+ def pdk(self):
+ """The pdk of this release."""
+ return self._pdk
+
+ @pdk.setter
+ def pdk(self, value):
+ if value is None:
+ self._pdk = None
+ return
+ self._pdk = to_bool(value)
+
+ # -------------------------------------------------------------------------
+ @property
+ def readme(self):
+ """The readme of module release."""
+ return self._readme
+
+ @readme.setter
+ def readme(self, value):
+ if value is None:
+ self._readme = None
+ return
+ v = str(value).strip()
+ if v == '':
+ self._readme = None
+ return
+ self._readme = v
+
+ # -------------------------------------------------------------------------
+ @property
+ def reference(self):
+ """The reference of module release."""
+ return self._reference
+
+ @reference.setter
+ def reference(self, value):
+ if value is None:
+ self._reference = None
+ return
+ v = str(value).strip()
+ if v == '':
+ self._reference = None
+ return
+ self._reference = v
+
+ # -------------------------------------------------------------------------
+ @property
+ def updated_at(self):
+ """Update date of this release."""
+ return self._updated_at
+
+ @updated_at.setter
+ def updated_at(self, value):
+ if value is None:
+ self._updated_at = None
+ return
+ if isinstance(value, datetime.datetime):
+ self._updated_at = value
+ return
+ v = str(value).strip()
+ if v == '':
+ self._updated_at = None
+ return
+ self._updated_at = parse_forge_date(v)
+
+ # -------------------------------------------------------------------------
+ @property
+ def validation_score(self):
+ "The validation score of this module release."""
+ return self._validation_score
+
+ @validation_score.setter
+ def validation_score(self, value):
+ if value is None:
+ self._validation_score = None
+ return
+ try:
+ v = int(value)
+ self._validation_score = v
+ return
+ except Exception as e:
+ LOG.error(_("Got a {c} setting {w}: {e}").format(
+ c=e.__class__.__name__, w='validation_score', e=e))
+
+ # -------------------------------------------------------------------------
+ def to_data(self):
+ """Returning a dict, which can be used to re-instantiate this module info."""
+
+ res = super(CurrentModuleReleaseInfo, self).to_data()
+
+ res['changelog'] = self.changelog
+ res['deleted_for'] = self.deleted_for
+ res['downloads'] = self.downloads
+ res['file_md5'] = self.file_md5
+ res['license'] = self.license
+ res['pdk'] = self.pdk
+ res['readme'] = self.readme
+ res['reference'] = self.reference
+ res['validation_score'] = self.validation_score
+
+ res['metadata'] = None
+ if self.metadata:
+ res['metadata'] = self.metadata.to_data()
+
+ res['module'] = None
+ if self.module:
+ res['module'] = self.module.to_data()
+
+ res['updated_at'] = None
+ if self.updated_at:
+ res['updated_at'] = self.updated_at.strftime('%Y-%m-%d %H:%M:%S %z')
+
+ res['tags'] = []
+ for tag in self.tags:
+ res['tags'].append(tag)
+
+ res['tasks'] = []
+ for task in self.tasks:
+ res['tasks'].append(copy.copy(task))
+
+ return res
+
+ # -------------------------------------------------------------------------
+ def apply_to(self, new):
+
+ if not isinstance(new, CurrentModuleReleaseInfo):
+ msg = _("Parameter {p!r} is not of class {c!r}, but of {e!r} instead.").format(
+ p='new', c='CurrentModuleReleaseInfo', e=new.__class__.__name__)
+ raise TypeError(msg)
+
+ super(CurrentModuleReleaseInfo, self).apply_to(new)
+
+ new.changelog = self.changelog
+ new.deleted_for = self.deleted_for
+ new.downloads = self.downloads
+ new.file_md5 = self.file_md5
+ new.license = self.license
+ new.pdk = self.pdk
+ new.readme = self.readme
+ new.reference = self.reference
+ new.updated_at = self.updated_at
+ new.validation_score = self.validation_score
+
+ new.metadata = None
+ if self.metadata:
+ new.metadata = copy.copy(self.metadata)
+
+ new.module = None
+ if self.module:
+ new.module = copy.copy(self.module)
+
+ new.tags = []
+ if self.tags:
+ for tag in self.tags:
+ new.tags.append(tag)
+
+ new.tasks = []
+ if self.tasks:
+ for task in self.tasks:
+ new.tasks.append(copy.copy(task))
+
+ # -------------------------------------------------------------------------
+ def __eq__(self, other):
+
+ if self.verbose > 4:
+ LOG.debug(_("Comparing {} objects ...").format(self.__class__.__name__))
+
+ if not super(CurrentModuleReleaseInfo, self).__eq__(other):
+ return False
+
+ if not isinstance(other, CurrentModuleReleaseInfo):
+ return False
+
+ if self.changelog != other.changelog:
+ return False
+ if self.deleted_for != other.deleted_for:
+ return False
+ if self.downloads != other.downloads:
+ return False
+ if self.file_md5 != other.file_md5:
+ return False
+ if self.license != other.license:
+ return False
+ if self.pdk != other.pdk:
+ return False
+ if self.readme != other.readme:
+ return False
+ if self.reference != other.reference:
+ return False
+ if self.updated_at != other.updated_at:
+ return False
+ if self.validation_score != other.validation_score:
+ return False
+ if self.metadata != other.metadata:
+ return False
+ if self.module != other.module:
+ return False
+ if self.tags != other.tags:
+ return False
+ if self.tasks != other.tasks:
+ return False
+
+ return True
+
+ # -------------------------------------------------------------------------
+ def apply_data(self, data):
+
+ super(CurrentModuleReleaseInfo, self).apply_data(data)
+
+ if 'changelog' in data and data['changelog']:
+ self.changelog = data['changelog']
+ if 'deleted_for' in data and data['deleted_for']:
+ self.deleted_for = data['deleted_for']
+ if 'downloads' in data and data['downloads']:
+ self.downloads = data['downloads']
+ if 'file_md5' in data and data['file_md5']:
+ self.file_md5 = data['file_md5']
+ if 'license' in data and data['license']:
+ self.license = data['license']
+
+ if 'metadata' in data and data['metadata']:
+ self.metadata = ModuleMetadata.from_json_data(
+ data['metadata'], appname=self.appname,
+ verbose=self.verbose, base_dir=self.base_dir)
+
+ if 'module' in data and data['module']:
+ self.module = BaseForgeModuleInfo.from_data(
+ data['module'], appname=self.appname,
+ verbose=self.verbose, base_dir=self.base_dir)
+
+ if 'pdk' in data:
+ self.pdk = data['pdk']
+ if 'readme' in data:
+ self.readme = data['readme']
+ if 'reference' in data:
+ self.reference = data['reference']
+ if 'updated_at' in data:
+ self.updated_at = data['updated_at']
+ if 'validation_score' in data:
+ self.validation_score = data['validation_score']
+
+ self.tags = []
+ if 'tags' in data and data['tags']:
+ if self.verbose > 2:
+ LOG.debug(
+ "Tags in current release of {!r}:".format(self.slug) + '\n' + pp(data['tags']))
+ for tag in data['tags']:
+ self.tags.append(tag)
+
+ self.tasks = []
+ if 'tasks' in data and data['tasks']:
+ if self.verbose > 3:
+ LOG.debug(
+ "Tasks in current release of {!r}:".format(self.slug) +
+ '\n' + pp(data['tasks']))
+ for task in data['tasks']:
+ self.tasks.append(copy.copy(task))
+
+
+# =============================================================================
+if __name__ == "__main__":
+
+ pass
+
+# =============================================================================
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list