Use links for release downloads

This commit is contained in:
Lacey Williams Henschel
2023-07-20 15:34:08 -07:00
parent 25ee520876
commit f44a49d179
6 changed files with 117 additions and 106 deletions

View File

@@ -75,58 +75,25 @@
<th scope="col" width="200" class="px-2 text-base bg-gray-100 border border-r-0 border-b-0 border-gray-200 dark:bg-charcoal">File</th>
<th scope="col" colspan="2" class="px-2 text-base bg-gray-100 rounded-tr-lg border border-b-0 border-gray-200 dark:bg-charcoal">SHA256 Hash</th>
</tr>
<tr>
<th scope="row" rowspan="2" class="px-2 h-14 whitespace-nowrap bg-gray-100 border border-r-0 border-b-0 border-gray-200 dark:bg-charcoal"><i class="fab fa-linux"></i> Linux</th>
<td class="px-2 border border-r-0 border-b-0 border-gray-200"><a href="https://boostorg.jfrog.io/artifactory/main/release/1.81.0/source/boost_1_81_0.tar.bz2">boost_1_81_0.tar.bz2</a>
</td>
<td width="30" class="px-1 mx-1 text-center align-bottom whitespace-nowrap border border-r-0 border-b-0 border-gray-200">
<button class="justify-center items-center w-4 h-full font-semibold shadow" @click="$clipboard($el.parentElement.nextSibling.nextSibling.title)">
<svg class="link" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m6 19v2c0 .621.52 1 1 1h2v-1.5h-1.5v-1.5zm7.5 3h-3.5v-1.5h3.5zm4.5 0h-3.5v-1.5h3.5zm4-3h-1.5v1.5h-1.5v1.5h2c.478 0 1-.379 1-1zm-1.5-1v-3.363h1.5v3.363zm0-4.363v-3.637h1.5v3.637zm-13-3.637v3.637h-1.5v-3.637zm11.5-4v1.5h1.5v1.5h1.5v-2c0-.478-.379-1-1-1zm-10 0h-2c-.62 0-1 .519-1 1v2h1.5v-1.5h1.5zm4.5 1.5h-3.5v-1.5h3.5zm3-1.5v-2.5h-13v13h2.5v-1.863h1.5v3.363h-4.5c-.48 0-1-.379-1-1v-14c0-.481.38-1 1-1h14c.621 0 1 .522 1 1v4.5h-3.5v-1.5z"/>
</svg>
</button>
</td>
<td class="bg-gray-100 border border-b-0 border-l-0 border-gray-200 truncCell dark:bg-charcoal" title="71feeed900fbccca04a3b4f2f84a7c217186f28a940ed8b7ed4725986baf99fa">71feeed900fbccca04a3b4f2f84a7c217186f28a940ed8b7ed4725986baf99fa</td>
</tr>
<tr >
<td class="px-2 border border-r-0 border-b-0 border-gray-200"><a href="https://boostorg.jfrog.io/artifactory/main/release/1.81.0/source/boost_1_81_0.tar.gz">boost_1_81_0.tar.gz</a>
</td>
<td width="30" class="px-1 mx-1 text-center align-bottom whitespace-nowrap border border-r-0 border-b-0 border-gray-200">
<button class="justify-center items-center w-4 h-full font-semibold shadow" @click="$clipboard($el.parentElement.nextSibling.nextSibling.title)">
<svg class="link" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m6 19v2c0 .621.52 1 1 1h2v-1.5h-1.5v-1.5zm7.5 3h-3.5v-1.5h3.5zm4.5 0h-3.5v-1.5h3.5zm4-3h-1.5v1.5h-1.5v1.5h2c.478 0 1-.379 1-1zm-1.5-1v-3.363h1.5v3.363zm0-4.363v-3.637h1.5v3.637zm-13-3.637v3.637h-1.5v-3.637zm11.5-4v1.5h1.5v1.5h1.5v-2c0-.478-.379-1-1-1zm-10 0h-2c-.62 0-1 .519-1 1v2h1.5v-1.5h1.5zm4.5 1.5h-3.5v-1.5h3.5zm3-1.5v-2.5h-13v13h2.5v-1.863h1.5v3.363h-4.5c-.48 0-1-.379-1-1v-14c0-.481.38-1 1-1h14c.621 0 1 .522 1 1v4.5h-3.5v-1.5z"/>
</svg>
</button>
</td>
<td class="bg-gray-100 border border-b-0 border-l-0 border-gray-200 truncCell dark:bg-charcoal" title="205666dea9f6a7cfed87c7a6dfbeb52a2c1b9de55712c9c1a87735d7181452b6">205666dea9f6a7cfed87c7a6dfbeb52a2c1b9de55712c9c1a87735d7181452b6</td>
</tr>
<tr class="border border-gray-200">
<th scope="row" rowspan="2" class="px-2 h-14 whitespace-nowrap bg-gray-100 rounded-bl-lg border border-r-0 border-gray-200 md:rounded-bl-none dark:bg-charcoal"><i class="fab fa-windows"></i> Windows</th>
<td class="px-2 border border-r-0 border-b-0 border-gray-200"><a
href="https://boostorg.jfrog.io/artifactory/main/release/1.81.0/source/boost_1_81_0.7z">boost_1_81_0.7z</a>
</td>
<td width="30" class="px-1 mx-1 text-center align-bottom whitespace-nowrap border border-r-0 border-b-0 border-gray-200">
<button class="justify-center items-center w-4 h-full font-semibold shadow" @click="$clipboard($el.parentElement.nextSibling.nextSibling.title)">
<svg class="link" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m6 19v2c0 .621.52 1 1 1h2v-1.5h-1.5v-1.5zm7.5 3h-3.5v-1.5h3.5zm4.5 0h-3.5v-1.5h3.5zm4-3h-1.5v1.5h-1.5v1.5h2c.478 0 1-.379 1-1zm-1.5-1v-3.363h1.5v3.363zm0-4.363v-3.637h1.5v3.637zm-13-3.637v3.637h-1.5v-3.637zm11.5-4v1.5h1.5v1.5h1.5v-2c0-.478-.379-1-1-1zm-10 0h-2c-.62 0-1 .519-1 1v2h1.5v-1.5h1.5zm4.5 1.5h-3.5v-1.5h3.5zm3-1.5v-2.5h-13v13h2.5v-1.863h1.5v3.363h-4.5c-.48 0-1-.379-1-1v-14c0-.481.38-1 1-1h14c.621 0 1 .522 1 1v4.5h-3.5v-1.5z"/>
</svg>
</button>
</td>
<td class="bg-gray-100 border border-b-0 border-l-0 border-gray-200 truncCell dark:bg-charcoal" title="d7bc4e2a2aee374a8c24832cacfed1265680c1e824d09fab3e00f87508155353">d7bc4e2a2aee374a8c24832cacfed1265680c1e824d09fab3e00f87508155353</td>
</tr>
<tr class="border border-gray-200">
<td class="px-2 border border-r-0 border-gray-200"><a
href="https://boostorg.jfrog.io/artifactory/main/release/1.81.0/source/boost_1_81_0.zip">boost_1_81_0.zip</a>
</td>
<td width="30" class="px-1 mx-1 text-center align-bottom whitespace-nowrap border border-r-0 border-gray-200">
<button class="justify-center items-center w-4 h-full font-semibold shadow" @click="$clipboard($el.parentElement.nextSibling.nextSibling.title)">
<svg class="link" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m6 19v2c0 .621.52 1 1 1h2v-1.5h-1.5v-1.5zm7.5 3h-3.5v-1.5h3.5zm4.5 0h-3.5v-1.5h3.5zm4-3h-1.5v1.5h-1.5v1.5h2c.478 0 1-.379 1-1zm-1.5-1v-3.363h1.5v3.363zm0-4.363v-3.637h1.5v3.637zm-13-3.637v3.637h-1.5v-3.637zm11.5-4v1.5h1.5v1.5h1.5v-2c0-.478-.379-1-1-1zm-10 0h-2c-.62 0-1 .519-1 1v2h1.5v-1.5h1.5zm4.5 1.5h-3.5v-1.5h3.5zm3-1.5v-2.5h-13v13h2.5v-1.863h1.5v3.363h-4.5c-.48 0-1-.379-1-1v-14c0-.481.38-1 1-1h14c.621 0 1 .522 1 1v4.5h-3.5v-1.5z"/>
</svg>
</button>
</td>
<td class="bg-gray-100 rounded-br-lg border border-l-0 border-gray-200 truncCell dark:bg-charcoal" title="6e689b266b27d4db57f648b1e5c905c8acd6716b46716a12f6fc73fc80af842e">6e689b266b27d4db57f648b1e5c905c8acd6716b46716a12f6fc73fc80af842e</td>
</tr>
{% if downloads %}
{% for os, download_files in downloads.items %}
{% for download in download_files %}
<tr>
{% if forloop.first %}<th scope="row" rowspan="{{ download_files|length }}" class="px-2 h-14 whitespace-nowrap bg-gray-100 border border-r-0 border-b-0 border-gray-200 dark:bg-charcoal"><i class="fab fa-{% if os == 'Unix' %}linux{% else %}windows{% endif %}"></i> {{ os }}</th>{% endif %}
<td class="px-2 border border-r-0 border-b-0 border-gray-200"><a href="{{ download.url }}">{{ download.display_name }}</a>
</td>
<td width="30" class="px-1 mx-1 text-center align-bottom whitespace-nowrap border border-r-0 border-b-0 border-gray-200">
<button class="justify-center items-center w-4 h-full font-semibold shadow" @click="$clipboard($el.parentElement.nextSibling.nextSibling.title)">
<svg class="link" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m6 19v2c0 .621.52 1 1 1h2v-1.5h-1.5v-1.5zm7.5 3h-3.5v-1.5h3.5zm4.5 0h-3.5v-1.5h3.5zm4-3h-1.5v1.5h-1.5v1.5h2c.478 0 1-.379 1-1zm-1.5-1v-3.363h1.5v3.363zm0-4.363v-3.637h1.5v3.637zm-13-3.637v3.637h-1.5v-3.637zm11.5-4v1.5h1.5v1.5h1.5v-2c0-.478-.379-1-1-1zm-10 0h-2c-.62 0-1 .519-1 1v2h1.5v-1.5h1.5zm4.5 1.5h-3.5v-1.5h3.5zm3-1.5v-2.5h-13v13h2.5v-1.863h1.5v3.363h-4.5c-.48 0-1-.379-1-1v-14c0-.481.38-1 1-1h14c.621 0 1 .522 1 1v4.5h-3.5v-1.5z"/>
</svg>
</button>
</td>
<td class="bg-gray-100 border border-b-0 border-l-0 border-gray-200 truncCell dark:bg-charcoal" title="{{ download.checksum }}">{{ download.checksum }}</td>
</tr>
{% endfor %}
{% endfor %}
{% endif %}
</tbody>
</table>

View File

@@ -0,0 +1,37 @@
# Generated by Django 4.2.2 on 2023-07-20 20:23
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("versions", "0007_version_data_version_github_url"),
]
operations = [
migrations.RemoveField(
model_name="versionfile",
name="file",
),
migrations.AddField(
model_name="versionfile",
name="display_name",
field=models.CharField(blank=True, max_length=256, null=True),
),
migrations.AddField(
model_name="versionfile",
name="url",
field=models.URLField(default="https://example.com"),
preserve_default=False,
),
migrations.AlterField(
model_name="versionfile",
name="version",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="downloads",
to="versions.version",
),
),
]

View File

@@ -1,4 +1,3 @@
import hashlib
from django.db import models
from django.utils.functional import cached_property
from django.utils.text import slugify
@@ -83,25 +82,14 @@ class VersionFile(models.Model):
(Windows, "Windows"),
)
version = models.ForeignKey(Version, related_name="files", on_delete=models.CASCADE)
version = models.ForeignKey(
Version, related_name="downloads", on_delete=models.CASCADE
)
operating_system = models.CharField(
choices=OPERATING_SYSTEM_CHOICES, max_length=15, default=Unix
)
checksum = models.CharField(max_length=64, unique=True, default=None)
file = models.FileField(upload_to="uploads/")
url = models.URLField()
display_name = models.CharField(max_length=256, blank=True, null=True)
objects = VersionFileManager()
def save(self, *args, **kwargs):
# Calculate sha256 hash
if self.file is not None and self.checksum is None:
h = hashlib.sha256()
with self.file.open("rb") as f:
data = f.read()
while data:
h.update(data)
data = f.read()
self.checksum = h.hexdigest()
super().save(*args, **kwargs)

View File

@@ -3,10 +3,7 @@ import hashlib
import pytest
import random
from pathlib import Path
from model_bakery import baker
from django.core.files import File
from django.core.files.base import ContentFile
from versions.models import VersionFile
@@ -26,10 +23,14 @@ def version(db):
release_date=yesterday,
)
# Make verison file
# Make version download file
c = fake_checksum()
f1 = ContentFile("Version 1 Fake Content")
baker.make("versions.VersionFile", version=v, checksum=c, file=f1)
baker.make(
"versions.VersionFile",
version=v,
checksum=c,
url="https://example.com/version_1.tar.gz",
)
return v
@@ -46,10 +47,14 @@ def inactive_version(db):
active=False,
)
# Make verison file
# Make version download file
c = fake_checksum()
f1 = ContentFile("Old Version Fake Content")
baker.make("versions.VersionFile", version=v, checksum=c, file=f1)
baker.make(
"versions.VersionFile",
version=v,
checksum=c,
url="https://example.com/old_version.tar.gz",
)
return v
@@ -65,23 +70,23 @@ def old_version(db):
release_date=last_year,
)
# Make verison file
# Make version download file
c = fake_checksum()
f1 = ContentFile("Version 1 Fake Content")
baker.make("versions.VersionFile", version=v, checksum=c, file=f1)
baker.make(
"versions.VersionFile",
version=v,
checksum=c,
url="https://example.com/version_1_fake.tar.gz",
)
return v
def get_version_file_path(name):
BASE_DIR = Path(__file__).parent
return BASE_DIR.joinpath(f"files/{name}")
@pytest.fixture
def full_version_one(db):
"""Build a full version with 3 attached files"""
yesterday = datetime.date.today() - datetime.timedelta(days=1)
base_url = "https://example.com/"
base_url_suffix = ".tar.gz"
v = baker.make(
"versions.Version",
name="1.79.0",
@@ -90,28 +95,34 @@ def full_version_one(db):
active=False,
)
vf1 = baker.prepare(
"versions.VersionFile", version=v, operating_system=VersionFile.Unix
f1_url = f"{base_url}version1{base_url_suffix}"
c1 = fake_checksum()
baker.make(
"versions.VersionFile",
version=v,
operating_system=VersionFile.Unix,
url=f1_url,
checksum=c1,
)
f1_path = get_version_file_path("version1.tar.gz")
with open(f1_path, "rb") as f:
vf1.file.save(f1_path.name, File(f), save=True)
vf1.save()
vf2 = baker.prepare(
"versions.VersionFile", version=v, operating_system=VersionFile.Unix
f2_url = f"{base_url}version1_2{base_url_suffix}"
c2 = fake_checksum()
baker.make(
"versions.VersionFile",
version=v,
operating_system=VersionFile.Unix,
url=f2_url,
checksum=c2,
)
f2_path = get_version_file_path("version1.tar.bz2")
with open(f2_path, "rb") as f:
vf2.file.save(f2_path.name, File(f), save=True)
vf2.save()
vf3 = baker.prepare(
"versions.VersionFile", version=v, operating_system=VersionFile.Windows
f3_url = f"{base_url}version1_3{base_url_suffix}"
c3 = fake_checksum()
baker.make(
"versions.VersionFile",
version=v,
operating_system=VersionFile.Windows,
url=f3_url,
checksum=c3,
)
f3_path = get_version_file_path("version1.zip")
with open(f3_path, "rb") as f:
vf3.file.save(f3_path.name, File(f), save=True)
vf3.save()
return v

View File

@@ -54,4 +54,4 @@ def test_version_documentation_url(version):
def test_version_file_creation(full_version_one):
assert full_version_one.files.count() == 3
assert full_version_one.downloads.count() == 3

View File

@@ -3,6 +3,8 @@ import structlog
from django.views.generic import DetailView
from django.views.generic.edit import FormMixin
from django.shortcuts import redirect
from itertools import groupby
from operator import attrgetter
from libraries.forms import VersionSelectionForm
from versions.models import Version
@@ -20,7 +22,13 @@ class VersionDetail(FormMixin, DetailView):
def get_context_data(self, **kwargs):
context = super().get_context_data()
obj = self.get_object()
context["versions"] = Version.objects.active().order_by("-release_date")
downloads = obj.downloads.all().order_by("operating_system")
context["downloads"] = {
k: list(v)
for k, v in groupby(downloads, key=attrgetter("operating_system"))
}
current_release = Version.objects.most_recent()
context["current_release"] = current_release
obj = self.get_object()