mirror of
https://github.com/boostorg/website-v2.git
synced 2026-01-19 04:42:17 +00:00
179 lines
6.1 KiB
Python
179 lines
6.1 KiB
Python
from django.db import models
|
|
from django.db.models import Func, Value, Count, Q
|
|
from django.db.models.functions import Replace
|
|
from django.contrib.postgres.fields import ArrayField
|
|
|
|
from libraries.constants import (
|
|
MASTER_RELEASE_URL_PATH_STR,
|
|
DEVELOP_RELEASE_URL_PATH_STR,
|
|
)
|
|
|
|
|
|
class VersionQuerySet(models.QuerySet):
|
|
def active(self):
|
|
"""Return active versions"""
|
|
return self.filter(active=True, fully_imported=True)
|
|
|
|
def most_recent(self):
|
|
"""Return most recent active non-beta version"""
|
|
return (
|
|
self.active()
|
|
.filter(beta=False, full_release=True)
|
|
.order_by("-name")
|
|
.first()
|
|
)
|
|
|
|
def most_recent_beta(self):
|
|
"""Return most recent active beta version.
|
|
|
|
Note: There should only ever be one beta version in the database, as
|
|
old ones are generally deleted. But just in case."""
|
|
return self.active().filter(beta=True).order_by("-name").first()
|
|
|
|
def with_version_split(self):
|
|
"""Separates name into an array of [major, minor, patch].
|
|
|
|
Anything not matching the regex is removed from the queryset.
|
|
|
|
Example:
|
|
name = boost-1.85.0
|
|
version_array -> [1, 85, 0]
|
|
major -> 1
|
|
minor -> 85
|
|
patch -> 0
|
|
|
|
"""
|
|
return self.filter(name__regex=r"^(boost-)?\d+\.\d+\.\d+$").annotate(
|
|
simple_version=Replace("name", Value("boost-"), Value("")),
|
|
version_array=Func(
|
|
"simple_version",
|
|
Value(r"\."),
|
|
function="regexp_split_to_array",
|
|
template="(%(function)s(%(expressions)s)::int[])",
|
|
arity=2,
|
|
output_field=ArrayField(models.IntegerField()),
|
|
),
|
|
major=models.F("version_array__0"),
|
|
minor=models.F("version_array__1"),
|
|
patch=models.F("version_array__2"),
|
|
)
|
|
|
|
|
|
class VersionManager(models.Manager):
|
|
def get_queryset(self):
|
|
return VersionQuerySet(self.model, using=self._db)
|
|
|
|
def active(self):
|
|
"""Return active versions"""
|
|
return self.get_queryset().active()
|
|
|
|
def most_recent(self):
|
|
"""Return most recent active non-beta version"""
|
|
return self.get_queryset().most_recent()
|
|
|
|
def most_recent_beta(self):
|
|
"""Return most recent active beta version"""
|
|
return self.get_queryset().most_recent_beta()
|
|
|
|
def minor_versions(self):
|
|
"""Filters for versions with patch = 0
|
|
|
|
Beta versions are removed.
|
|
|
|
"""
|
|
return self.get_queryset().with_version_split().filter(patch=0)
|
|
|
|
def get_dropdown_versions(
|
|
self,
|
|
*,
|
|
allow_develop: bool = False,
|
|
allow_master: bool = False,
|
|
flag_versions_without_library: "Library" = None, # noqa: F821
|
|
order_by: str = "-name",
|
|
):
|
|
"""
|
|
Returns the versions to be shown in the drop-down, basics:
|
|
* does not include the development branches
|
|
* includes the most recent beta if it is newer than the most recent full release
|
|
* doesn't return versions where full_release=False and beta=False
|
|
|
|
Args:
|
|
allow_develop (bool): allow the develop branch version to show in result
|
|
allow_master (bool): allow the master branch version to show in the result
|
|
order_by (str): the field to order by
|
|
flag_versions_without_library (Library): flag the version when it doesn't
|
|
have the matching library - e.g. used for library detail page
|
|
"""
|
|
all_versions = self.active().filter(beta=False)
|
|
most_recent_beta = self.most_recent_beta()
|
|
|
|
def should_show_beta(most_recent_beta):
|
|
"""
|
|
Returns bool for whether to show beta version in dropdown. Returns True only
|
|
when the most recent beta version is newer than the most recent full release
|
|
"""
|
|
most_recent = self.most_recent()
|
|
if not most_recent_beta or most_recent is None:
|
|
return False
|
|
|
|
return (
|
|
most_recent_beta.cleaned_version_parts
|
|
> most_recent.cleaned_version_parts
|
|
)
|
|
|
|
queryset = all_versions
|
|
include_beta = should_show_beta(most_recent_beta)
|
|
if include_beta:
|
|
beta_queryset = self.active().filter(models.Q(name=most_recent_beta.name))
|
|
queryset = queryset | beta_queryset
|
|
|
|
# beta=False here is not redundant, it only applies to the exclusion while a
|
|
# beta is allowed for most_recent_beta
|
|
flag_exclusions = Q(full_release=False, beta=False)
|
|
name_exclusions = [
|
|
"head",
|
|
MASTER_RELEASE_URL_PATH_STR,
|
|
DEVELOP_RELEASE_URL_PATH_STR,
|
|
]
|
|
if allow_master:
|
|
flag_exclusions = flag_exclusions & ~Q(name="master")
|
|
name_exclusions.remove(MASTER_RELEASE_URL_PATH_STR)
|
|
if allow_develop:
|
|
flag_exclusions = flag_exclusions & ~Q(name="develop")
|
|
name_exclusions.remove(DEVELOP_RELEASE_URL_PATH_STR)
|
|
|
|
queryset = (
|
|
queryset.exclude(name__in=name_exclusions)
|
|
.exclude(flag_exclusions)
|
|
.defer("data")
|
|
)
|
|
|
|
if flag_versions_without_library:
|
|
# Annotate each version with a flag `has_library` indicating if it has the
|
|
# provided library version or not
|
|
queryset = queryset.annotate(
|
|
has_library=Count(
|
|
"library_version",
|
|
filter=models.Q(
|
|
library_version__library=flag_versions_without_library
|
|
),
|
|
)
|
|
)
|
|
|
|
return queryset.order_by(order_by)
|
|
|
|
|
|
class VersionFileQuerySet(models.QuerySet):
|
|
def active(self):
|
|
"""Return files for active versions"""
|
|
return self.filter(version__active=True)
|
|
|
|
|
|
class VersionFileManager(models.Manager):
|
|
def get_queryset(self):
|
|
return VersionFileQuerySet(self.model, using=self._db)
|
|
|
|
def active(self):
|
|
"""Return files active versions"""
|
|
return self.get_queryset().active()
|