# Copyright (C) 2016-2022 The Sipwise Team - http://sipwise.com # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . import json import re from datetime import datetime from django.db import models from django_extensions.db.fields import ModificationDateTimeField from .conf import settings from gerrit.utils import get_filtered_json class Project(models.Model): name = models.CharField(max_length=50, unique=True, null=False) json_tags = models.JSONField(null=True) json_branches = models.JSONField(null=True) modified = ModificationDateTimeField(null=True) @classmethod def _filter_values(cls, values, val_ok_filter, regex=None): if values is None: return list() res = set() for value in values: match = re.search(val_ok_filter, value["ref"]) if match: val_ok = match.group(1) if regex is not None: if re.search(regex, val_ok): res.add(val_ok) else: res.add(val_ok) return sorted(res, reverse=True) def __str__(self): return self.name @property def tags(self): return Project._filter_values( self.json_tags, settings.RELEASE_DASHBOARD_FILTER_TAGS ) @tags.setter def tags(self, value): self.json_tags = get_filtered_json(value) @property def branches(self): return Project._filter_values( self.json_branches, settings.RELEASE_DASHBOARD_FILTER_BRANCHES ) @branches.setter def branches(self, value): self.json_branches = get_filtered_json(value) def filter_tags(self, regex): return Project._filter_values( self.json_tags, settings.RELEASE_DASHBOARD_FILTER_TAGS, regex ) def filter_branches(self, regex): return Project._filter_values( self.json_branches, settings.RELEASE_DASHBOARD_FILTER_BRANCHES, regex, ) def filter_docker_images(self, images): r = re.compile(self.name) return filter(r.search, images) def branches_mrXX(self): return self.filter_branches(settings.RELEASE_DASHBOARD_FILTER_MRXX) def branches_mrXXX(self): return self.filter_branches(settings.RELEASE_DASHBOARD_FILTER_MRXXX) class DockerImageManager(models.Manager): def images_with_tags(self, project=None): qs = self.get_queryset().filter(dockertag__isnull=False) if project: qs = qs.filter(project__name=project) return qs.distinct() class DockerImage(models.Model): name = models.CharField(max_length=50, unique=True, null=False) project = models.ForeignKey(Project, on_delete=models.CASCADE) objects = DockerImageManager() def __str__(self): return "%s[%s]" % (self.name, self.project.name) @property def tags(self): res = self.dockertag_set.all().values_list("name", flat=True) return res class DockerTag(models.Model): name = models.CharField(max_length=50, null=False) manifests = models.JSONField(null=False) image = models.ForeignKey(DockerImage, on_delete=models.CASCADE) reference = models.CharField(max_length=150, unique=True, null=False) class Meta: unique_together = (("name", "image"),) def __str__(self): return "%s:%s" % (self.image.name, self.name) @property def date(self): if self.manifests is None: return None if isinstance(self.manifests, dict): manifests = self.manifests else: try: manifests = json.loads(self.manifests) except json.JSONDecodeError: return None try: value = manifests["history"][0]["v1Compatibility"] time = json.loads(value) created = time["created"].split(".") return datetime.strptime(created[0], "%Y-%m-%dT%H:%M:%S") except json.JSONDecodeError: return None