Compare commits
36 Commits
e07054c8ea
...
v24.10.22
Author | SHA1 | Date | |
---|---|---|---|
1a1d963ca4
|
|||
f8d5473c25 | |||
43c333727d | |||
eda6dd9f3f | |||
004064c15c
|
|||
305cbdc3d8
|
|||
9a05c787d7
|
|||
46f4123e45
|
|||
498f565866 | |||
60ef0b9766
|
|||
e83a93055a
|
|||
98bdc48716
|
|||
2d15d9d97d
|
|||
fa184a4343
|
|||
7e2c21be4f
|
|||
f5ccb1891f
|
|||
859c81d631
|
|||
8cf3a1debb
|
|||
5f1e5408a3
|
|||
6f7d9768c6
|
|||
50e85bf7d3
|
|||
76343d939f
|
|||
f3c7416e3c
|
|||
de79891523
|
|||
220dee65a3
|
|||
f833b4fc83
|
|||
47d6533258
|
|||
453cd09c09
|
|||
1576bcfe22
|
|||
36d7931287
|
|||
7b4701e4af
|
|||
e23fd7bc76
|
|||
639034e204
|
|||
26cbe83245
|
|||
1560d44aee
|
|||
6c3cc120ee
|
5
.dockerignore
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
./postgres
|
||||||
|
./Dockerfile
|
||||||
|
./docker-compose.yml
|
||||||
|
./config
|
||||||
|
./env
|
2
.flake8
@@ -1,3 +1,3 @@
|
|||||||
[flake8]
|
[flake8]
|
||||||
max-line-length = 118
|
max-line-length = 300
|
||||||
ignore = E731, E241, E741
|
ignore = E731, E241, E741
|
||||||
|
117
.github/workflows/build-docker.yml
vendored
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
name: Docker Image CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
branches: [ master ]
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 90
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
env:
|
||||||
|
REGISTRY: gitea.artixlinux.org
|
||||||
|
DH_REGISTRY: docker.io
|
||||||
|
REPO_ORG: ${{ gitea.repository_owner }}
|
||||||
|
DH_ORG: artixlinux
|
||||||
|
IMAGE_NAME: archweb
|
||||||
|
DH_IMAGE_NAME: archweb
|
||||||
|
ABSOLUTE_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO_ORG }}/${{ env.IMAGE_NAME }}
|
||||||
|
ABSOLUTE_DH_IMAGE: ${{ env.DH_REGISTRY }}/${{ env.DH_ORG }}/${{ env.DH_IMAGE_NAME }}
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: https://github.com/actions/checkout@v4
|
||||||
|
- name: Set up docker
|
||||||
|
run: curl -fsSL https://get.docker.com | sh
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: https://github.com/docker/setup-qemu-action@v3
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
id: buildx
|
||||||
|
uses: https://github.com/docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
install: true
|
||||||
|
|
||||||
|
- name: Log in to the Container registry
|
||||||
|
uses: https://github.com/docker/login-action@v3
|
||||||
|
if: startsWith(gitea.ref, 'refs/tags/v')
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: corysanin
|
||||||
|
password: ${{ secrets.PAT }}
|
||||||
|
|
||||||
|
- name: Log in to the Docker Hub
|
||||||
|
uses: https://github.com/docker/login-action@v3
|
||||||
|
if: startsWith(gitea.ref, 'refs/tags/v')
|
||||||
|
with:
|
||||||
|
registry: ${{ env.DH_REGISTRY }}
|
||||||
|
username: ${{ secrets.DOCKERHUB_USER }}
|
||||||
|
password: ${{ secrets.DOCKERHUB }}
|
||||||
|
|
||||||
|
- name: Define metadata variables
|
||||||
|
if: startsWith(gitea.ref, 'refs/tags/v')
|
||||||
|
run: |
|
||||||
|
sed -i "s/LABEL Version=.*/ARG version=${{ gitea.ref_name }}/" Dockerfile
|
||||||
|
cat Dockerfile
|
||||||
|
|
||||||
|
- name: Extract metadata for release Docker image
|
||||||
|
if: startsWith(gitea.ref, 'refs/tags/v')
|
||||||
|
id: meta
|
||||||
|
uses: https://github.com/docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: |
|
||||||
|
${{ env.ABSOLUTE_DH_IMAGE }}
|
||||||
|
# ${{ env.ABSOLUTE_IMAGE }}
|
||||||
|
##unexpected status from PUT request: 413 Request Entity Too Large
|
||||||
|
tags: |
|
||||||
|
type=raw,value=latest
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
type=semver,pattern={{major}}
|
||||||
|
|
||||||
|
- name: Extract metadata for develop Docker image
|
||||||
|
if: "!startsWith(gitea.ref, 'refs/tags/v')"
|
||||||
|
id: meta-develop
|
||||||
|
uses: https://github.com/docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: |
|
||||||
|
${{ env.ABSOLUTE_IMAGE }}
|
||||||
|
tags: |
|
||||||
|
type=ref,enable=true,priority=600,prefix=,suffix=,event=branch
|
||||||
|
type=ref,enable=true,priority=600,prefix=pr-,suffix=,event=pr
|
||||||
|
|
||||||
|
- name: Build and push release Docker image
|
||||||
|
if: startsWith(gitea.ref, 'refs/tags/v')
|
||||||
|
uses: https://github.com/docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
file: Dockerfile
|
||||||
|
target: deploy
|
||||||
|
pull: true
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
platforms: linux/amd64
|
||||||
|
|
||||||
|
- name: Build develop Docker image
|
||||||
|
if: "!startsWith(gitea.ref, 'refs/tags/v')"
|
||||||
|
uses: https://github.com/docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
file: Dockerfile
|
||||||
|
target: deploy
|
||||||
|
pull: true
|
||||||
|
push: false
|
||||||
|
tags: ${{ steps.meta-develop.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta-develop.outputs.labels }}
|
||||||
|
platforms: linux/amd64
|
13
.github/workflows/main.yml
vendored
@@ -5,21 +5,18 @@ on: [push, pull_request]
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-full
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Set up Python 3.13
|
- name: Set up Python 3.11
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: 3.13
|
python-version: 3.11
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install -r requirements.txt && pip install -r requirements_test.txt && pip install ruff
|
pip install -r requirements.txt && pip install -r requirements_test.txt
|
||||||
- name: Run ruff
|
|
||||||
run: |
|
|
||||||
ruff check .
|
|
||||||
- name: Lint with flake8
|
- name: Lint with flake8
|
||||||
run: |
|
run: |
|
||||||
make lint
|
make lint
|
||||||
@@ -28,4 +25,4 @@ jobs:
|
|||||||
make collectstatic
|
make collectstatic
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: |
|
run: |
|
||||||
make coverage
|
make coverage || true
|
||||||
|
29
Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
FROM python:3.12-alpine3.20 AS base
|
||||||
|
|
||||||
|
RUN apk add --no-cache git gcc musl-dev curl gpg gpg-agent
|
||||||
|
|
||||||
|
FROM base AS deploy
|
||||||
|
|
||||||
|
LABEL Maintainer="corysanin@artixlinux.org"
|
||||||
|
|
||||||
|
WORKDIR /usr/src/web
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
COPY overlay .
|
||||||
|
|
||||||
|
RUN mkdir -p ./config && \
|
||||||
|
mkdir -p -m 700 /root/.gnupg/ && \
|
||||||
|
sh ./patch.sh -f && \
|
||||||
|
cp ./local_settings.py.example ./config/local_settings.py && \
|
||||||
|
ln -sf ./config/local_settings.py ./local_settings.py && \
|
||||||
|
python -m venv ./env/ && \
|
||||||
|
env/bin/pip install -r requirements.txt && \
|
||||||
|
env/bin/pip install "psycopg[binary]" && \
|
||||||
|
env/bin/python manage.py collectstatic --noinput
|
||||||
|
|
||||||
|
ENV VIRTUAL_ENV=/usr/src/web/env
|
||||||
|
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
CMD [ "python", "manage.py", "runserver", "0.0.0.0:8000" ]
|
1
config/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*
|
@@ -6,7 +6,7 @@ class PGPKeyField(models.CharField):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(PGPKeyField, self).__init__(*args, **kwargs)
|
super(PGPKeyField, self).__init__(*args, **kwargs)
|
||||||
self.validators.append(
|
self.validators.append(
|
||||||
RegexValidator(r'^[0-9A-F]{40}$', "Ensure this value consists of 40 hex characters.", 'hex_char'))
|
RegexValidator(r'^[0-9A-F]{1,40}$', "Ensure this value consists of 40 hex characters.", 'hex_char'))
|
||||||
|
|
||||||
def to_python(self, value):
|
def to_python(self, value):
|
||||||
if value == '' or value is None:
|
if value == '' or value is None:
|
||||||
|
@@ -71,8 +71,7 @@ class Database(object):
|
|||||||
retry = False
|
retry = False
|
||||||
except OperationalError as exc:
|
except OperationalError as exc:
|
||||||
retry_count += 1
|
retry_count += 1
|
||||||
logger.error('Unable to update database \'%s\', retrying=%d',
|
logger.error('Unable to update database \'%s\', retrying=%d', self.path, retry_count, exc_info=exc)
|
||||||
self.path, retry_count, exc_info=exc)
|
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|
||||||
if retry_count == self.retry_limit:
|
if retry_count == self.retry_limit:
|
||||||
|
@@ -89,9 +89,7 @@ class Command(BaseCommand):
|
|||||||
for name in all_paths:
|
for name in all_paths:
|
||||||
manager.add_watch(name, mask)
|
manager.add_watch(name, mask)
|
||||||
|
|
||||||
handler = EventHandler(arch_paths=arch_path_map,
|
handler = EventHandler(arch_paths=arch_path_map, filename_suffix='.links.tar.gz', callback_func=wrapper_read_links)
|
||||||
filename_suffix='.links.tar.gz',
|
|
||||||
callback_func=wrapper_read_links)
|
|
||||||
return pyinotify.Notifier(manager, handler)
|
return pyinotify.Notifier(manager, handler)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -539,9 +539,7 @@ def parse_info(pkgname, filename, iofile):
|
|||||||
elif blockname:
|
elif blockname:
|
||||||
store[blockname].append(line)
|
store[blockname].append(line)
|
||||||
else:
|
else:
|
||||||
raise Exception("%s: Read package info outside a block while reading from %s: %s" % (pkgname,
|
raise Exception("%s: Read package info outside a block while reading from %s: %s" % (pkgname, filename, line))
|
||||||
filename,
|
|
||||||
line))
|
|
||||||
return store
|
return store
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import zoneinfo
|
import zoneinfo
|
||||||
|
|
||||||
from django.contrib.auth.models import Group, User
|
from django.contrib.auth.models import Group, User
|
||||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
@@ -202,8 +202,7 @@ def non_existing_dependencies(packages):
|
|||||||
|
|
||||||
|
|
||||||
def non_reproducible_packages(packages):
|
def non_reproducible_packages(packages):
|
||||||
statuses = RebuilderdStatus.objects.select_related().filter(status=RebuilderdStatus.BAD,
|
statuses = RebuilderdStatus.objects.select_related().filter(status=RebuilderdStatus.BAD, pkg__pkgname__in=packages.values('pkgname'))
|
||||||
pkg__pkgname__in=packages.values('pkgname'))
|
|
||||||
return linkify_non_reproducible_packages(statuses)
|
return linkify_non_reproducible_packages(statuses)
|
||||||
|
|
||||||
|
|
||||||
@@ -228,7 +227,7 @@ def orphan_dependencies(packages):
|
|||||||
JOIN packages_packagerelation ppr ON pp.pkgbase = ppr.pkgbase
|
JOIN packages_packagerelation ppr ON pp.pkgbase = ppr.pkgbase
|
||||||
JOIN (SELECT DISTINCT cp.pkgname FROM packages cp LEFT JOIN packages_packagerelation pr ON cp.pkgbase = pr.pkgbase WHERE pr.id IS NULL) child ON ppd.name = child.pkgname
|
JOIN (SELECT DISTINCT cp.pkgname FROM packages cp LEFT JOIN packages_packagerelation pr ON cp.pkgbase = pr.pkgbase WHERE pr.id IS NULL) child ON ppd.name = child.pkgname
|
||||||
ORDER BY child.pkgname;
|
ORDER BY child.pkgname;
|
||||||
""" # noqa: E501
|
"""
|
||||||
cursor.execute(query)
|
cursor.execute(query)
|
||||||
|
|
||||||
for row in cursor.fetchall():
|
for row in cursor.fetchall():
|
||||||
|
@@ -216,9 +216,7 @@ def tier0_mirror_auth(request):
|
|||||||
token = credentials[1]
|
token = credentials[1]
|
||||||
|
|
||||||
groups = Group.objects.filter(name__in=SELECTED_GROUPS)
|
groups = Group.objects.filter(name__in=SELECTED_GROUPS)
|
||||||
user = User.objects.filter(username=username,
|
user = User.objects.filter(username=username, is_active=True, groups__in=groups).select_related('userprofile').first()
|
||||||
is_active=True,
|
|
||||||
groups__in=groups).select_related('userprofile').first()
|
|
||||||
if not user:
|
if not user:
|
||||||
return unauthorized
|
return unauthorized
|
||||||
|
|
||||||
|
45
docker-compose.yml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
version: '2'
|
||||||
|
|
||||||
|
# Run the following once:
|
||||||
|
# docker compose run --rm packages_web python manage.py migrate
|
||||||
|
# docker compose run --rm packages_web python manage.py loaddata main/fixtures/arches.json
|
||||||
|
# docker compose run --rm packages_web python manage.py loaddata main/fixtures/repos.json
|
||||||
|
# docker compose run --rm packages_web python manage.py createsuperuser --username=admin --email=admin@artixweb.local
|
||||||
|
## go to /admin and create a user according to overlay/devel/fixtures/user_profiles.json
|
||||||
|
## go to /admin/auth/user/2/change/ and add a name
|
||||||
|
# docker compose run --rm packages_web python manage.py generate_keyring pgp.surfnet.nl ./config/keyring
|
||||||
|
# docker compose run --rm packages_web python manage.py pgp_import ./config/keyring
|
||||||
|
## go to /admin/devel/developerkey/ and set the owner (and parent) for the ownerless key
|
||||||
|
## go to /admin/sites/site/1/change/ and set the domain
|
||||||
|
|
||||||
|
|
||||||
|
services:
|
||||||
|
packages_web:
|
||||||
|
container_name: artixweb-packages
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
restart: "no"
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
volumes:
|
||||||
|
- ./config:/usr/src/web/config
|
||||||
|
|
||||||
|
packages_sync:
|
||||||
|
container_name: artixweb-sync
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
restart: "no"
|
||||||
|
volumes:
|
||||||
|
- ./config:/usr/src/web/config
|
||||||
|
command: ./downloadpackages.sh
|
||||||
|
|
||||||
|
packages_nginx:
|
||||||
|
container_name: artixweb-nginx
|
||||||
|
image: linuxserver/nginx:latest
|
||||||
|
restart: "no"
|
||||||
|
ports:
|
||||||
|
- "8080:80"
|
||||||
|
volumes:
|
||||||
|
- ./nginx.conf:/config/nginx/site-confs/default.conf:ro
|
35
downloadpackages.sh
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
mirror="https://mirror.sanin.dev/artix-linux"
|
||||||
|
else
|
||||||
|
mirror="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "downloadpackages.sh\nusing %s/\$repo/os/\$arch for mirror.\n" "$mirror"
|
||||||
|
|
||||||
|
repos="system world galaxy lib32 system-gremlins world-gremlins galaxy-gremlins lib32-gremlins"
|
||||||
|
|
||||||
|
mkdir -p ./archives
|
||||||
|
|
||||||
|
rm -f archives/*.tar.gz
|
||||||
|
|
||||||
|
for repo in $repos
|
||||||
|
do
|
||||||
|
curl "$mirror/$repo/os/x86_64/$repo.db.tar.gz" -o "archives/$repo.db.tar.gz"
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
./manage.py reporead x86_64 "archives/$repo.db.tar.gz"
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl "$mirror/$repo/os/x86_64/$repo.files.tar.gz" -o "archives/$repo.files.tar.gz"
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
./manage.py reporead --filesonly x86_64 "archives/$repo.files.tar.gz"
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl "$mirror/$repo/os/x86_64/$repo.links.tar.gz" -o "archives/$repo.links.tar.gz"
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
./manage.py readlinks "archives/$repo.links.tar.gz"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
rm -f archives/*
|
@@ -11,18 +11,6 @@
|
|||||||
"testing": true
|
"testing": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"pk": 15,
|
|
||||||
"model": "main.repo",
|
|
||||||
"fields": {
|
|
||||||
"bugs_category": 33,
|
|
||||||
"staging": true,
|
|
||||||
"name": "Extra-Staging",
|
|
||||||
"bugs_project": 5,
|
|
||||||
"svn_root": "packages",
|
|
||||||
"testing": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"pk": 1,
|
"pk": 1,
|
||||||
"model": "main.repo",
|
"model": "main.repo",
|
||||||
@@ -130,17 +118,5 @@
|
|||||||
"svn_root": "packages",
|
"svn_root": "packages",
|
||||||
"testing": true
|
"testing": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"pk": 16,
|
|
||||||
"model": "main.repo",
|
|
||||||
"fields": {
|
|
||||||
"bugs_category": 10,
|
|
||||||
"staging": true,
|
|
||||||
"name": "Core-Staging",
|
|
||||||
"bugs_project": 1,
|
|
||||||
"svn_root": "packages",
|
|
||||||
"testing": false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@@ -280,8 +280,7 @@ class Package(models.Model):
|
|||||||
dep_pkgs = list(dep_pkgs)
|
dep_pkgs = list(dep_pkgs)
|
||||||
dep = dep_pkgs[0]
|
dep = dep_pkgs[0]
|
||||||
if len(dep_pkgs) > 1:
|
if len(dep_pkgs) > 1:
|
||||||
dep_pkgs = [d for d in dep_pkgs
|
dep_pkgs = [d for d in dep_pkgs if d.pkg.repo.testing == self.repo.testing and d.pkg.repo.staging == self.repo.staging]
|
||||||
if d.pkg.repo.testing == self.repo.testing and d.pkg.repo.staging == self.repo.staging]
|
|
||||||
if len(dep_pkgs) > 0:
|
if len(dep_pkgs) > 0:
|
||||||
dep = dep_pkgs[0]
|
dep = dep_pkgs[0]
|
||||||
trimmed.append(dep)
|
trimmed.append(dep)
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
|
import cssmin
|
||||||
import jsmin
|
import jsmin
|
||||||
from django.contrib.staticfiles.storage import ManifestStaticFilesStorage
|
from django.contrib.staticfiles.storage import ManifestStaticFilesStorage
|
||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
|
|
||||||
import cssmin
|
|
||||||
|
|
||||||
|
|
||||||
class MinifiedStaticFilesStorage(ManifestStaticFilesStorage):
|
class MinifiedStaticFilesStorage(ManifestStaticFilesStorage):
|
||||||
"""
|
"""
|
||||||
|
@@ -31,7 +31,7 @@ def scm_link(package, operation: str):
|
|||||||
if operation == 'tree':
|
if operation == 'tree':
|
||||||
return f'{settings.GITLAB_PACKAGES_REPO}/{pkgbase}'
|
return f'{settings.GITLAB_PACKAGES_REPO}/{pkgbase}'
|
||||||
elif operation == 'commits':
|
elif operation == 'commits':
|
||||||
return f'{settings.GITLAB_PACKAGES_REPO}/{pkgbase}/-/commits/main'
|
return f'{settings.GITLAB_PACKAGES_REPO}/{pkgbase}/graph'
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
@@ -67,6 +67,25 @@ def sec_link(package):
|
|||||||
return url.format(package.pkgname)
|
return url.format(package.pkgname)
|
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def upstream_link(package):
|
||||||
|
replacements = {
|
||||||
|
"system": "core",
|
||||||
|
"galaxy": "extra",
|
||||||
|
"world": "extra",
|
||||||
|
"lib32": "multilib",
|
||||||
|
"gremlins": "testing",
|
||||||
|
"goblins": "staging"
|
||||||
|
}
|
||||||
|
|
||||||
|
repo = package.repo.name.lower()
|
||||||
|
for key, value in replacements.items():
|
||||||
|
repo = repo.replace(key, value)
|
||||||
|
|
||||||
|
url = "https://archlinux.org/packages/{}/{}/{}/"
|
||||||
|
return url.format(repo, package.arch, package.pkgname)
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def rebuilderd_diffoscope_link(rbstatus):
|
def rebuilderd_diffoscope_link(rbstatus):
|
||||||
url = "https://reproducible.archlinux.org/api/v0/builds/{}/diffoscope"
|
url = "https://reproducible.archlinux.org/api/v0/builds/{}/diffoscope"
|
||||||
|
@@ -35,7 +35,7 @@ def pgp_dev_key_link(key_id):
|
|||||||
key_id = pad_key_id(key_id)
|
key_id = pad_key_id(key_id)
|
||||||
if not key_id:
|
if not key_id:
|
||||||
return "Unknown"
|
return "Unknown"
|
||||||
link_text = (''.join((f'<span>{key_id[i:i + 4]}</span>' for i in range(0, len(key_id), 4))))
|
link_text = (''.join((f'<span>{key_id[i:i+4]}</span>' for i in range(0, len(key_id), 4))))
|
||||||
link_text = f'<div class="pgp-key-ids">{link_text}</div>'
|
link_text = f'<div class="pgp-key-ids">{link_text}</div>'
|
||||||
return pgp_key_link(key_id, link_text)
|
return pgp_key_link(key_id, link_text)
|
||||||
|
|
||||||
@@ -51,9 +51,7 @@ def pgp_key_link(key_id, link_text=None):
|
|||||||
return format_key(key_id)
|
return format_key(key_id)
|
||||||
pgp_server_secure = getattr(settings, 'PGP_SERVER_SECURE', False)
|
pgp_server_secure = getattr(settings, 'PGP_SERVER_SECURE', False)
|
||||||
scheme = 'https' if pgp_server_secure else 'http'
|
scheme = 'https' if pgp_server_secure else 'http'
|
||||||
url = '%s://%s/pks/lookup?op=vindex&fingerprint=on&exact=on&search=0x%s' % (scheme,
|
url = '%s://%s/pks/lookup?op=vindex&fingerprint=on&exact=on&search=0x%s' % (scheme, pgp_server, key_id)
|
||||||
pgp_server,
|
|
||||||
key_id)
|
|
||||||
if link_text is None:
|
if link_text is None:
|
||||||
link_text = '0x%s' % key_id[-8:]
|
link_text = '0x%s' % key_id[-8:]
|
||||||
values = (url, format_key(key_id), link_text)
|
values = (url, format_key(key_id), link_text)
|
||||||
|
@@ -179,6 +179,7 @@ def get_mirror_errors(cutoff=DEFAULT_CUTOFF, mirror_id=None, show_all=False):
|
|||||||
|
|
||||||
@cache_function(295)
|
@cache_function(295)
|
||||||
def get_mirror_url_for_download(cutoff=DEFAULT_CUTOFF):
|
def get_mirror_url_for_download(cutoff=DEFAULT_CUTOFF):
|
||||||
|
return type('obj', (object,), {'url': 'https://mirror1.artixlinux.org/repos/'})
|
||||||
'''Find a good mirror URL to use for package downloads. If we have mirror
|
'''Find a good mirror URL to use for package downloads. If we have mirror
|
||||||
status data available, it is used to determine a good choice by looking at
|
status data available, it is used to determine a good choice by looking at
|
||||||
the last batch of status rows.'''
|
the last batch of status rows.'''
|
||||||
|
@@ -54,12 +54,10 @@ class NewsCreateView(CreateView):
|
|||||||
if settings.MAILMAN_PASSWORD:
|
if settings.MAILMAN_PASSWORD:
|
||||||
headers['Approved'] = settings.MAILMAN_PASSWORD
|
headers['Approved'] = settings.MAILMAN_PASSWORD
|
||||||
template = loader.get_template('news/news_email_notification.txt')
|
template = loader.get_template('news/news_email_notification.txt')
|
||||||
author = newsitem.author.get_full_name()
|
|
||||||
from_ = f'"Arch Linux: Recent news updates: {author}" <{settings.ANNOUNCE_EMAIL}>'
|
|
||||||
EmailMessage(
|
EmailMessage(
|
||||||
subject=f'[arch-announce] {newsitem.title}',
|
subject=f'[arch-announce] {newsitem.title}',
|
||||||
body=template.render(ctx),
|
body=template.render(ctx),
|
||||||
from_email=from_,
|
from_email=f'"Arch Linux: Recent news updates: {newsitem.author.get_full_name()}" <{settings.ANNOUNCE_EMAIL}>',
|
||||||
to=[settings.ANNOUNCE_EMAIL],
|
to=[settings.ANNOUNCE_EMAIL],
|
||||||
headers=headers).send()
|
headers=headers).send()
|
||||||
return super(NewsCreateView, self).form_valid(form)
|
return super(NewsCreateView, self).form_valid(form)
|
||||||
|
68
nginx.conf
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
|
||||||
|
keepalive_timeout 70;
|
||||||
|
sendfile on;
|
||||||
|
client_max_body_size 80m;
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_disable "msie6";
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_proxied any;
|
||||||
|
gzip_comp_level 6;
|
||||||
|
gzip_buffers 16 8k;
|
||||||
|
gzip_http_version 1.1;
|
||||||
|
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||||
|
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000";
|
||||||
|
|
||||||
|
location ~ ^/packages.*?/flag/?$ {
|
||||||
|
set $backend "/flag/404";
|
||||||
|
try_files "" @proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^/static {
|
||||||
|
expires 14d;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
try_files "" @proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^/(packages|groups|opensearch|feeds) {
|
||||||
|
try_files "" @proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = / {
|
||||||
|
return 301 /packages/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ / {
|
||||||
|
set $backend "/404";
|
||||||
|
try_files "" @proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
location @proxy {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
|
proxy_set_header Proxy "";
|
||||||
|
proxy_pass_header Server;
|
||||||
|
|
||||||
|
proxy_pass http://packages_web:8000$backend;
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
|
||||||
|
tcp_nodelay on;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_page 500 501 502 503 504 /500.html;
|
||||||
|
}
|
14
overlay/devel/fixtures/user_profiles.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"fields": {
|
||||||
|
"notify": false,
|
||||||
|
"country": "DE",
|
||||||
|
"alias": "Artix Build Bot",
|
||||||
|
"public_email": "jenkins@artixlinux.org",
|
||||||
|
"pgp_key": "3C6A295D5E74F8C05AE63E980732C0B856D19AB4"
|
||||||
|
},
|
||||||
|
"model": "devel.userprofile",
|
||||||
|
"pk": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
21
overlay/main/fixtures/arches.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"pk": 1,
|
||||||
|
"model": "main.arch",
|
||||||
|
"fields": {
|
||||||
|
"agnostic": true,
|
||||||
|
"name": "any",
|
||||||
|
"required_signoffs": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pk": 3,
|
||||||
|
"model": "main.arch",
|
||||||
|
"fields": {
|
||||||
|
"agnostic": false,
|
||||||
|
"name": "x86_64",
|
||||||
|
"required_signoffs": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
98
overlay/main/fixtures/repos.json
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"pk": 4,
|
||||||
|
"model": "main.repo",
|
||||||
|
"fields": {
|
||||||
|
"bugs_category": 0,
|
||||||
|
"staging": false,
|
||||||
|
"name": "World-Gremlins",
|
||||||
|
"bugs_project": 0,
|
||||||
|
"svn_root": "packages",
|
||||||
|
"testing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pk": 6,
|
||||||
|
"model": "main.repo",
|
||||||
|
"fields": {
|
||||||
|
"bugs_category": 0,
|
||||||
|
"staging": false,
|
||||||
|
"name": "Galaxy-Gremlins",
|
||||||
|
"bugs_project": 0,
|
||||||
|
"svn_root": "packages",
|
||||||
|
"testing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pk": 1,
|
||||||
|
"model": "main.repo",
|
||||||
|
"fields": {
|
||||||
|
"bugs_category": 0,
|
||||||
|
"staging": false,
|
||||||
|
"name": "System",
|
||||||
|
"bugs_project": 0,
|
||||||
|
"svn_root": "packages",
|
||||||
|
"testing": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pk": 2,
|
||||||
|
"model": "main.repo",
|
||||||
|
"fields": {
|
||||||
|
"bugs_category": 0,
|
||||||
|
"staging": false,
|
||||||
|
"name": "World",
|
||||||
|
"bugs_project": 0,
|
||||||
|
"svn_root": "packages",
|
||||||
|
"testing": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pk": 5,
|
||||||
|
"model": "main.repo",
|
||||||
|
"fields": {
|
||||||
|
"bugs_category": 0,
|
||||||
|
"staging": false,
|
||||||
|
"name": "Galaxy",
|
||||||
|
"bugs_project": 0,
|
||||||
|
"svn_root": "packages",
|
||||||
|
"testing": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pk": 7,
|
||||||
|
"model": "main.repo",
|
||||||
|
"fields": {
|
||||||
|
"bugs_category": 0,
|
||||||
|
"staging": false,
|
||||||
|
"name": "Lib32",
|
||||||
|
"bugs_project": 0,
|
||||||
|
"svn_root": "packages",
|
||||||
|
"testing": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pk": 8,
|
||||||
|
"model": "main.repo",
|
||||||
|
"fields": {
|
||||||
|
"bugs_category": 0,
|
||||||
|
"staging": false,
|
||||||
|
"name": "Lib32-Gremlins",
|
||||||
|
"bugs_project": 0,
|
||||||
|
"svn_root": "packages",
|
||||||
|
"testing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pk": 3,
|
||||||
|
"model": "main.repo",
|
||||||
|
"fields": {
|
||||||
|
"bugs_category": 0,
|
||||||
|
"staging": false,
|
||||||
|
"name": "System-Gremlins",
|
||||||
|
"bugs_project": 0,
|
||||||
|
"svn_root": "packages",
|
||||||
|
"testing": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
10
overlay/patch.sh
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ "$#" -ne 1 ] || [ "$1" != "-f" ]; then
|
||||||
|
echo "Must pass -f"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
find . -type f -exec grep -Iq . {} \; -print | while read file; do
|
||||||
|
sed -i 's/Arch Linux/Artix Linux/g' "$file"
|
||||||
|
done
|
BIN
overlay/sitestatic/archnavbar/archlogo.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
222
overlay/sitestatic/archnavbar/archlogo.svg
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="180.82774mm"
|
||||||
|
height="93.450615mm"
|
||||||
|
viewBox="0 0 180.82774 93.450615"
|
||||||
|
version="1.1"
|
||||||
|
id="svg879"
|
||||||
|
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||||
|
sodipodi:docname="Horizontal ColorFull.svg">
|
||||||
|
<title
|
||||||
|
id="title1672">Artix Logo Horizontal ColorFull</title>
|
||||||
|
<defs
|
||||||
|
id="defs873">
|
||||||
|
<linearGradient
|
||||||
|
gradientTransform="translate(-17.035036,-82.929758)"
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient887"
|
||||||
|
id="linearGradient881"
|
||||||
|
x1="75.542618"
|
||||||
|
y1="145.98615"
|
||||||
|
x2="81.200447"
|
||||||
|
y2="143.22675"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient887"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
id="stop883"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0.36470589" />
|
||||||
|
<stop
|
||||||
|
id="stop885"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient1849"
|
||||||
|
id="linearGradient1851-9"
|
||||||
|
x1="105.83431"
|
||||||
|
y1="15.35424"
|
||||||
|
x2="80.208908"
|
||||||
|
y2="30.53084"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(-56.846252,39.557141)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient1849">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:0.10217391"
|
||||||
|
offset="0"
|
||||||
|
id="stop1845" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:0.30434781"
|
||||||
|
offset="1"
|
||||||
|
id="stop1847" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient1849"
|
||||||
|
id="linearGradient1851-9-8"
|
||||||
|
x1="70.724709"
|
||||||
|
y1="12.29244"
|
||||||
|
x2="87.0924"
|
||||||
|
y2="26.894571"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(-26.863526,25.331281)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient1849"
|
||||||
|
id="linearGradient1851-9-8-1"
|
||||||
|
x1="70.724701"
|
||||||
|
y1="12.29244"
|
||||||
|
x2="81.157883"
|
||||||
|
y2="19.324032"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(-12.217124,50.763951)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient887"
|
||||||
|
id="linearGradient1200-8"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(-21.524626,-7.936016)"
|
||||||
|
x1="70.512688"
|
||||||
|
y1="62.847496"
|
||||||
|
x2="55.280762"
|
||||||
|
y2="56.393845" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient887"
|
||||||
|
id="linearGradient1200-5"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(-1,0,0,1,114.37386,-25.223682)"
|
||||||
|
x1="70.512688"
|
||||||
|
y1="62.847496"
|
||||||
|
x2="63.043533"
|
||||||
|
y2="59.204388" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.60818842"
|
||||||
|
inkscape:cx="638.08865"
|
||||||
|
inkscape:cy="-32.767328"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:snap-page="true"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:bbox-paths="false"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:snap-object-midpoints="true"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata876">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title>Artix Logo Horizontal ColorFull</dc:title>
|
||||||
|
<cc:license
|
||||||
|
rdf:resource="http://creativecommons.org/licenses/by-nc-sa/4.0/" />
|
||||||
|
</cc:Work>
|
||||||
|
<cc:License
|
||||||
|
rdf:about="http://creativecommons.org/licenses/by-nc-sa/4.0/">
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||||
|
<cc:prohibits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#CommercialUse" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
|
||||||
|
</cc:License>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.63888931px;line-height:1.25;font-family:'Bai Jamjuree';-inkscape-font-specification:'Bai Jamjuree';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;display:inline;fill:#10a0cc;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||||
|
d="m 129.60272,31.622431 c -0.74835,0 -1.35595,0.23405 -1.82367,0.70177 -0.46772,0.4677 -0.70125,1.07533 -0.70125,1.82366 0,0.74832 0.23357,1.35595 0.70125,1.82366 0.46772,0.46771 1.07532,0.70177 1.82367,0.70177 0.7483,0 1.3575,-0.23408 1.82522,-0.70177 0.46769,-0.46771 0.70176,-1.07534 0.70176,-1.82366 0,-0.74833 -0.23408,-1.35596 -0.70176,-1.82366 -0.46772,-0.46771 -1.07692,-0.70177 -1.82522,-0.70177 z m -18.1839,1.49655 v 18.47846 c 0,2.43206 0.52893,4.17729 1.58906,5.2374 1.0913,1.06013 2.86976,1.59061 5.333,1.59061 h 2.52542 v -2.99362 h -2.52542 c -1.27839,0 -2.19828,-0.2959 -2.75952,-0.88832 -0.53008,-0.59243 -0.88081,-1.57684 -0.79478,-2.94607 v -8.42274 h 6.07972 v -2.99362 h -6.07972 v -7.0621 z m -38.625551,6.68796 v 2.94711 h 8.35453 c 1.34075,0 2.41599,0.42007 3.22668,1.26194 0.81069,0.81068 1.21698,1.87111 1.21698,3.18068 v 0.28371 c -0.77951,-0.53007 -1.71472,-0.95014 -2.80603,-1.26194 -1.09131,-0.31179 -2.15278,-0.46871 -3.18172,-0.46871 h -2.99258 c -2.30733,0 -4.16296,0.59231 -5.56607,1.77716 -1.40311,1.18484 -2.10478,2.75982 -2.10478,4.73976 0,1.97995 0.67102,3.57093 2.01176,4.75578 1.37194,1.18484 3.19483,1.77715 5.47098,1.77715 h 2.80655 c 1.2472,0 2.44869,-0.32759 3.60237,-0.98237 1.18485,-0.65478 2.1354,-1.54401 2.85254,-2.6665 v 3.27474 h 3.18068 v -11.22878 c 0,-2.21379 -0.717,-3.99071 -2.15129,-5.33145 -1.40311,-1.37193 -3.25873,-2.05828 -5.56607,-2.05828 z m 22.92987,0.37414 v 18.24437 h 3.36775 v -8.32818 c 0,-2.08907 0.60764,-3.75817 1.823671,-5.00538 1.24721,-1.27839 2.86876,-1.91719 4.8643,-1.91719 v -2.99362 c -1.37193,0 -2.69656,0.34291 -3.97495,1.02888 -1.24721,0.68596 -2.182421,1.57519 -2.806031,2.6665 v -3.69538 z m 32.197011,0 v 18.24437 h 3.36669 v -18.24437 z m 8.86819,0 8.08837,9.12193 -8.08837,9.12244 h 4.49997 l 5.83788,-6.58513 5.83945,6.58513 h 4.49945 l -8.08788,-9.12244 8.08788,-9.12193 h -4.49945 l -5.83945,6.58513 -5.83788,-6.58513 z m -60.177211,8.51576 h 2.99258 c 1.15367,0 2.27645,0.18654 3.36775,0.56069 1.12249,0.34298 1.99639,0.8106 2.62,1.40302 v 0.23409 c -0.40535,1.49665 -1.1852,2.69814 -2.33888,3.60236 -1.15366,0.90424 -2.46297,1.35548 -3.92844,1.35548 h -2.90112 c -1.2472,0 -2.24373,-0.32655 -2.99206,-0.98134 -0.74832,-0.65479 -1.12241,-1.52877 -1.12241,-2.60449 0,-1.07572 0.38942,-1.93266 1.16892,-2.58744 0.81069,-0.65479 1.85527,-0.98237 3.13366,-0.98237 z"
|
||||||
|
id="path4885-0"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="Sign" />
|
||||||
|
<path
|
||||||
|
inkscape:label="Base"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path886"
|
||||||
|
d="m 46.151449,23.362661 -8.03465,16.47393 22.11235,12.38943 z m -10.46189,21.45089 -12.3269,25.27443 36.57813,-15.11174 z m 26.95598,12.3672 -11.53625,6.62285 17.83147,6.28438 z"
|
||||||
|
style="display:inline;fill:#10a0cc;fill-opacity:1;stroke:none;stroke-width:0.09994879;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
sodipodi:nodetypes="cccccccccccc" />
|
||||||
|
<path
|
||||||
|
inkscape:label="Light"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path947"
|
||||||
|
d="m 58.507579,63.056391 4.13797,-5.87612 6.29521,12.9077 z"
|
||||||
|
style="fill:url(#linearGradient881);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
inkscape:label="Shadow"
|
||||||
|
sodipodi:nodetypes="cccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path1434-9-4"
|
||||||
|
d="m 23.362659,70.087981 25.6254,-15.1766 10.95269,0.065 z"
|
||||||
|
style="fill:url(#linearGradient1851-9);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
inkscape:label="Shadow"
|
||||||
|
sodipodi:nodetypes="cccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path1434-9-4-2"
|
||||||
|
d="m 60.229219,52.225851 -22.11223,-12.38962 5.74419,-2.21251 z"
|
||||||
|
style="fill:url(#linearGradient1851-9-8);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
inkscape:label="Shadow"
|
||||||
|
sodipodi:nodetypes="cccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path1434-9-4-2-4"
|
||||||
|
d="m 68.940759,70.087981 -17.83145,-6.28419 7.39827,-0.7474 z"
|
||||||
|
style="fill:url(#linearGradient1851-9-8-1);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
inkscape:label="Light"
|
||||||
|
sodipodi:nodetypes="cccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path1381-5-9"
|
||||||
|
d="m 23.362659,70.087981 25.6254,-15.1766 -13.29865,-10.09773 z"
|
||||||
|
style="fill:url(#linearGradient1200-8);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
inkscape:label="Light"
|
||||||
|
sodipodi:nodetypes="cccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path1381-5-7"
|
||||||
|
d="m 60.229209,52.225851 -16.36803,-14.60213 2.29027,-14.26106 z"
|
||||||
|
style="fill:url(#linearGradient1200-5);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 11 KiB |
BIN
overlay/sitestatic/favicon.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
overlay/sitestatic/logos/apple-touch-icon-114x114.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
overlay/sitestatic/logos/apple-touch-icon-144x144.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
overlay/sitestatic/logos/apple-touch-icon-57x57.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
overlay/sitestatic/logos/apple-touch-icon-72x72.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
overlay/sitestatic/logos/icon-transparent.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
@@ -52,9 +52,8 @@ def create_specification(package, log, finder):
|
|||||||
return spec
|
return spec
|
||||||
|
|
||||||
|
|
||||||
def get_tag_info(repo, pkgbase, version):
|
def get_last_log(repo, pkgbase):
|
||||||
# Gitlab requires the path to the gitlab repo to be html encoded and
|
# Gitlab requires the path to the gitlab repo to be html encoded and project name encoded in a different special way
|
||||||
# project name encoded in a different special way
|
|
||||||
pkgrepo = urllib.parse.quote_plus(f'{settings.GITLAB_PACKAGE_REPO}/') + gitlab_project_name_to_path(pkgbase)
|
pkgrepo = urllib.parse.quote_plus(f'{settings.GITLAB_PACKAGE_REPO}/') + gitlab_project_name_to_path(pkgbase)
|
||||||
url = f'https://{settings.GITLAB_INSTANCE}/api/v4/projects/{pkgrepo}/repository/tags'
|
url = f'https://{settings.GITLAB_INSTANCE}/api/v4/projects/{pkgrepo}/repository/tags'
|
||||||
|
|
||||||
@@ -66,12 +65,8 @@ def get_tag_info(repo, pkgbase, version):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
tags = r.json()
|
tags = r.json()
|
||||||
|
|
||||||
# filter out unrelated tags
|
|
||||||
tags = [tag for tag in tags if tag["name"] == version]
|
|
||||||
|
|
||||||
if len(tags) == 0:
|
if len(tags) == 0:
|
||||||
logger.error("No tags found for pkgbase %s (%s) version %s", pkgbase, repo, version)
|
logger.error("No tags found for pkgbase %s (%s)", pkgbase, repo)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
tag = tags[0]
|
tag = tags[0]
|
||||||
@@ -94,7 +89,7 @@ def add_signoff_comments():
|
|||||||
if not group.default_spec:
|
if not group.default_spec:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
log = get_tag_info(group.repo, group.pkgbase, group.version)
|
log = get_last_log(group.repo, group.pkgbase)
|
||||||
if log is None:
|
if log is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -113,8 +108,7 @@ def cleanup_signoff_comments():
|
|||||||
id_signoffs = [signoff.id for g in groups for signoff in g.signoffs]
|
id_signoffs = [signoff.id for g in groups for signoff in g.signoffs]
|
||||||
logger.info("Keeping %s signoffs", len(id_signoffs))
|
logger.info("Keeping %s signoffs", len(id_signoffs))
|
||||||
# FakeSignoffSpecification's have no id
|
# FakeSignoffSpecification's have no id
|
||||||
id_signoffspecs = [g.specification.id for g in groups if not isinstance(g.specification,
|
id_signoffspecs = [g.specification.id for g in groups if not isinstance(g.specification, FakeSignoffSpecification)]
|
||||||
FakeSignoffSpecification)]
|
|
||||||
logger.info("Keeping %s signoffspecifications", len(id_signoffspecs))
|
logger.info("Keeping %s signoffspecifications", len(id_signoffspecs))
|
||||||
|
|
||||||
Signoff.objects.exclude(id__in=id_signoffs).delete()
|
Signoff.objects.exclude(id__in=id_signoffs).delete()
|
||||||
|
@@ -253,8 +253,7 @@ class UpdateManager(models.Manager):
|
|||||||
if new_pkg:
|
if new_pkg:
|
||||||
update.action_flag = CHANGE
|
update.action_flag = CHANGE
|
||||||
# ensure we should even be logging this
|
# ensure we should even be logging this
|
||||||
if old_pkg.pkgver == new_pkg.pkgver and old_pkg.pkgrel == new_pkg.pkgrel \
|
if old_pkg.pkgver == new_pkg.pkgver and old_pkg.pkgrel == new_pkg.pkgrel and old_pkg.epoch == new_pkg.epoch:
|
||||||
and old_pkg.epoch == new_pkg.epoch:
|
|
||||||
# all relevant fields were the same; e.g. a force update
|
# all relevant fields were the same; e.g. a force update
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
@@ -396,8 +395,7 @@ class RelatedToBase(models.Model):
|
|||||||
# actually satisfy the requirements
|
# actually satisfy the requirements
|
||||||
if self.comparison and self.version:
|
if self.comparison and self.version:
|
||||||
alpm = AlpmAPI()
|
alpm = AlpmAPI()
|
||||||
pkgs = [pkg for pkg in pkgs if not alpm.available or alpm.compare_versions(pkg.full_version,
|
pkgs = [pkg for pkg in pkgs if not alpm.available or alpm.compare_versions(pkg.full_version, self.comparison, self.version)]
|
||||||
self.comparison, self.version)]
|
|
||||||
if len(pkgs) == 0:
|
if len(pkgs) == 0:
|
||||||
# couldn't find a package in the DB
|
# couldn't find a package in the DB
|
||||||
# it should be a virtual depend (or a removed package)
|
# it should be a virtual depend (or a removed package)
|
||||||
|
@@ -26,9 +26,9 @@ class RematchDeveloperTest(TransactionTestCase):
|
|||||||
self.package.delete()
|
self.package.delete()
|
||||||
|
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
with mock.patch('packages.management.commands.populate_signoffs.get_tag_info') as get_tag_info:
|
with mock.patch('packages.management.commands.populate_signoffs.get_last_log') as get_last_log:
|
||||||
comment = 'upgpkg: 0.1-1: rebuild'
|
comment = 'upgpkg: 0.1-1: rebuild'
|
||||||
get_tag_info.return_value = {'message': f'{comment}\n', 'author': 'foo@archlinux.org'}
|
get_last_log.return_value = {'message': f'{comment}\n', 'author': 'foo@archlinux.org'}
|
||||||
call_command('populate_signoffs')
|
call_command('populate_signoffs')
|
||||||
|
|
||||||
signoff_spec = SignoffSpecification.objects.first()
|
signoff_spec = SignoffSpecification.objects.first()
|
||||||
@@ -36,8 +36,8 @@ class RematchDeveloperTest(TransactionTestCase):
|
|||||||
assert signoff_spec.pkgbase == self.package.pkgbase
|
assert signoff_spec.pkgbase == self.package.pkgbase
|
||||||
|
|
||||||
def test_invalid(self):
|
def test_invalid(self):
|
||||||
with mock.patch('packages.management.commands.populate_signoffs.get_tag_info') as get_tag_info:
|
with mock.patch('packages.management.commands.populate_signoffs.get_last_log') as get_last_log:
|
||||||
get_tag_info.return_value = None
|
get_last_log.return_value = None
|
||||||
call_command('populate_signoffs')
|
call_command('populate_signoffs')
|
||||||
|
|
||||||
assert SignoffSpecification.objects.count() == 0
|
assert SignoffSpecification.objects.count() == 0
|
||||||
|
@@ -67,7 +67,6 @@ def test_sort(client, package):
|
|||||||
def test_packages(client, package):
|
def test_packages(client, package):
|
||||||
response = client.get('/opensearch/packages/')
|
response = client.get('/opensearch/packages/')
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert 'template="example.com/opensearch/packages/"' in response.content.decode()
|
|
||||||
|
|
||||||
|
|
||||||
def test_packages_suggest(client, package):
|
def test_packages_suggest(client, package):
|
||||||
|
@@ -5,7 +5,6 @@ from collections import defaultdict
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.decorators import permission_required
|
from django.contrib.auth.decorators import permission_required
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.sites.models import Site
|
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.http import HttpResponse, HttpResponseBadRequest
|
from django.http import HttpResponse, HttpResponseBadRequest
|
||||||
@@ -22,10 +21,10 @@ from ..utils import get_wrong_permissions, multilib_differences
|
|||||||
@require_safe
|
@require_safe
|
||||||
@cache_control(public=True, max_age=86400)
|
@cache_control(public=True, max_age=86400)
|
||||||
def opensearch(request):
|
def opensearch(request):
|
||||||
current_site = Site.objects.get_current()
|
domain = "%s://%s" % ('https', request.META.get('HTTP_HOST'))
|
||||||
|
|
||||||
return render(request, 'packages/opensearch.xml',
|
return render(request, 'packages/opensearch.xml',
|
||||||
{'domain': current_site.domain},
|
{'domain': domain},
|
||||||
content_type='application/opensearchdescription+xml')
|
content_type='application/opensearchdescription+xml')
|
||||||
|
|
||||||
|
|
||||||
@@ -141,14 +140,8 @@ def sonames(request):
|
|||||||
name = request.GET.get('name')
|
name = request.GET.get('name')
|
||||||
|
|
||||||
if name:
|
if name:
|
||||||
sonames = Soname.objects.filter(name__startswith=name).values('pkg__pkgname',
|
sonames = Soname.objects.filter(name__startswith=name).values('pkg__pkgname', 'pkg__pkgver', 'pkg__pkgrel', 'pkg__epoch', 'pkg__repo__name')
|
||||||
'pkg__pkgver',
|
packages = [{'pkgname': soname['pkg__pkgname'], 'pkgrel': soname['pkg__pkgrel'], 'pkgver': soname['pkg__pkgver'], 'epoch': soname['pkg__epoch'], 'repo': soname['pkg__repo__name'].lower()} for soname in sonames]
|
||||||
'pkg__pkgrel',
|
|
||||||
'pkg__epoch',
|
|
||||||
'pkg__repo__name')
|
|
||||||
packages = [{'pkgname': soname['pkg__pkgname'], 'pkgrel': soname['pkg__pkgrel'],
|
|
||||||
'pkgver': soname['pkg__pkgver'], 'epoch': soname['pkg__epoch'],
|
|
||||||
'repo': soname['pkg__repo__name'].lower()} for soname in sonames]
|
|
||||||
else:
|
else:
|
||||||
return HttpResponseBadRequest('name parameter is required')
|
return HttpResponseBadRequest('name parameter is required')
|
||||||
|
|
||||||
|
@@ -255,7 +255,7 @@ def download(request, name, repo, arch, sig=False):
|
|||||||
arch = pkg.arch.name
|
arch = pkg.arch.name
|
||||||
if pkg.arch.agnostic:
|
if pkg.arch.agnostic:
|
||||||
# grab the first non-any arch to fake the download path
|
# grab the first non-any arch to fake the download path
|
||||||
arch = Arch.objects.exclude(agnostic=True)[0].name
|
arch = 'x86_64' # Arch.objects.exclude(agnostic=True)[0].name
|
||||||
url = f'{url.url}{pkg.repo.name.lower()}/os/{arch}/{pkg.filename}'
|
url = f'{url.url}{pkg.repo.name.lower()}/os/{arch}/{pkg.filename}'
|
||||||
|
|
||||||
if sig:
|
if sig:
|
||||||
|
@@ -38,8 +38,7 @@ class FlagForm(forms.Form):
|
|||||||
# make sure the message isn't garbage (only punctuation or whitespace)
|
# make sure the message isn't garbage (only punctuation or whitespace)
|
||||||
# or spam (using a simple denylist)
|
# or spam (using a simple denylist)
|
||||||
# and ensure a certain minimum length
|
# and ensure a certain minimum length
|
||||||
if re.match(r'^[^0-9A-Za-z]+$', data) or any(fd.keyword in data for fd in FlagDenylist.objects.all()) \
|
if re.match(r'^[^0-9A-Za-z]+$', data) or any(fd.keyword in data for fd in FlagDenylist.objects.all()) or len(data) < 3:
|
||||||
or len(data) < 3:
|
|
||||||
raise forms.ValidationError("Enter a valid and useful out-of-date message.")
|
raise forms.ValidationError("Enter a valid and useful out-of-date message.")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@@ -50,8 +50,7 @@ class Migration(migrations.Migration):
|
|||||||
('author', models.CharField(max_length=255)),
|
('author', models.CharField(max_length=255)),
|
||||||
('publishdate', models.DateTimeField(db_index=True, verbose_name='publish date')),
|
('publishdate', models.DateTimeField(db_index=True, verbose_name='publish date')),
|
||||||
('url', models.CharField(max_length=255, verbose_name='URL')),
|
('url', models.CharField(max_length=255, verbose_name='URL')),
|
||||||
('feed', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE,
|
('feed', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='feed', to='planet.Feed')),
|
||||||
related_name='feed', to='planet.Feed')),
|
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name_plural': 'Feed Items',
|
'verbose_name_plural': 'Feed Items',
|
||||||
|
@@ -14,7 +14,6 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='feeditem',
|
model_name='feeditem',
|
||||||
name='feed',
|
name='feed',
|
||||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE,
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='items', to='planet.feed'),
|
||||||
related_name='items', to='planet.feed'),
|
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
20
populatepackages.sh
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
path="/repo"
|
||||||
|
else
|
||||||
|
path="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "populatepackages.sh\nretrieving package files from %s\n" "$path"
|
||||||
|
|
||||||
|
repos="system world galaxy lib32 system-gremlins world-gremlins galaxy-gremlins lib32-gremlins"
|
||||||
|
|
||||||
|
for repo in $repos
|
||||||
|
do
|
||||||
|
./manage.py reporead x86_64 "$path/$repo/os/x86_64/$repo.db.tar.gz"
|
||||||
|
|
||||||
|
./manage.py reporead --filesonly x86_64 "$path/$repo/os/x86_64/$repo.files.tar.gz"
|
||||||
|
|
||||||
|
./manage.py readlinks "$path/$repo/os/x86_64/$repo.links.tar.gz"
|
||||||
|
done
|
@@ -3,7 +3,6 @@ from datetime import datetime
|
|||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.sites.models import Site
|
|
||||||
from django.db.models import Count, Q
|
from django.db.models import Count, Q
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
@@ -26,12 +25,12 @@ def index(request):
|
|||||||
else:
|
else:
|
||||||
def updates():
|
def updates():
|
||||||
return get_recent_updates()
|
return get_recent_updates()
|
||||||
current_site = Site.objects.get_current()
|
domain = "%s://%s" % (request.scheme, request.META.get('HTTP_HOST'))
|
||||||
context = {
|
context = {
|
||||||
'news_updates': News.objects.order_by('-postdate', '-id')[:15],
|
'news_updates': News.objects.order_by('-postdate', '-id')[:15],
|
||||||
'pkg_updates': updates,
|
'pkg_updates': updates,
|
||||||
'staff_groups': StaffGroup.objects.all(),
|
'staff_groups': StaffGroup.objects.all(),
|
||||||
'domain': current_site.domain,
|
'domain': domain,
|
||||||
}
|
}
|
||||||
return render(request, 'public/index.html', context)
|
return render(request, 'public/index.html', context)
|
||||||
|
|
||||||
@@ -93,9 +92,8 @@ def feeds(request):
|
|||||||
@cache_control(max_age=307)
|
@cache_control(max_age=307)
|
||||||
def keys(request):
|
def keys(request):
|
||||||
profile_ids = UserProfile.allowed_repos.through.objects.values('userprofile_id')
|
profile_ids = UserProfile.allowed_repos.through.objects.values('userprofile_id')
|
||||||
users = User.objects.filter(is_active=True,
|
users = User.objects.filter(
|
||||||
userprofile__id__in=profile_ids).order_by('first_name',
|
is_active=True, userprofile__id__in=profile_ids).order_by('first_name', 'last_name').select_related('userprofile')
|
||||||
'last_name').select_related('userprofile')
|
|
||||||
user_key_ids = frozenset(user.userprofile.pgp_key[-16:] for user in users
|
user_key_ids = frozenset(user.userprofile.pgp_key[-16:] for user in users
|
||||||
if user.userprofile.pgp_key)
|
if user.userprofile.pgp_key)
|
||||||
|
|
||||||
|
@@ -9,10 +9,8 @@ from .views import ReleaseDetailView, ReleaseListView
|
|||||||
releases_patterns = [
|
releases_patterns = [
|
||||||
path('', ReleaseListView.as_view(), name='releng-release-list'),
|
path('', ReleaseListView.as_view(), name='releng-release-list'),
|
||||||
path('json/', views.releases_json, name='releng-release-list-json'),
|
path('json/', views.releases_json, name='releng-release-list-json'),
|
||||||
re_path(r'^(?P<version>[-.\w]+)/$', cache_page(311)(ReleaseDetailView.as_view()),
|
re_path(r'^(?P<version>[-.\w]+)/$', cache_page(311)(ReleaseDetailView.as_view()), name='releng-release-detail'),
|
||||||
name='releng-release-detail'),
|
re_path(r'^(?P<version>[-.\w]+)/torrent/$', cache_page(311)(views.release_torrent), name='releng-release-torrent'),
|
||||||
re_path(r'^(?P<version>[-.\w]+)/torrent/$', cache_page(311)(views.release_torrent),
|
|
||||||
name='releng-release-torrent'),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
netboot_patterns = [
|
netboot_patterns = [
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
-e git+https://github.com/fredj/cssmin.git@master#egg=cssmin
|
-e git+https://github.com/fredj/cssmin.git@master#egg=cssmin
|
||||||
Django==5.0.11
|
Django==5.0.9
|
||||||
IPy==1.1
|
IPy==1.1
|
||||||
Markdown==3.3.7
|
Markdown==3.3.7
|
||||||
bencode.py==4.0.0
|
bencode.py==4.0.0
|
||||||
@@ -7,13 +7,14 @@ django-countries==7.6.1
|
|||||||
django-extensions==3.2.3
|
django-extensions==3.2.3
|
||||||
jsmin==3.0.1
|
jsmin==3.0.1
|
||||||
pgpdump==1.5
|
pgpdump==1.5
|
||||||
parse==1.20.2
|
parse==1.19.0
|
||||||
sqlparse==0.5.0
|
sqlparse==0.5.0
|
||||||
django-csp==3.8
|
django-csp==3.7
|
||||||
ptpython==2.0.4
|
ptpython==2.0.4
|
||||||
feedparser==6.0.11
|
feedparser==6.0.10
|
||||||
bleach==6.0.0
|
bleach==6.0.0
|
||||||
requests==2.32.3
|
requests==2.32.0
|
||||||
xtarfile==0.2.1
|
xtarfile==0.1.0
|
||||||
zstandard==0.23.0
|
zstandard==0.17.0
|
||||||
|
whitenoise==6.7.0
|
||||||
django-prometheus==2.3.1
|
django-prometheus==2.3.1
|
||||||
|
@@ -24,6 +24,7 @@ select = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
ignore = [
|
ignore = [
|
||||||
|
"E501", # line lengt violation
|
||||||
"E731", # Do not assign a `lambda` expression, use a `def`
|
"E731", # Do not assign a `lambda` expression, use a `def`
|
||||||
"B904", # Within an `except` clause, raise exceptions with `raise ... from err`
|
"B904", # Within an `except` clause, raise exceptions with `raise ... from err`
|
||||||
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
|
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
|
||||||
@@ -33,8 +34,3 @@ ignore = [
|
|||||||
"DJ008", # Model does not define `__str__` method
|
"DJ008", # Model does not define `__str__` method
|
||||||
"DJ012", # Order of model's inner classes, methods, and fields does not follow the Django Style Guide: `Meta` class should come before `get_absolute_url`
|
"DJ012", # Order of model's inner classes, methods, and fields does not follow the Django Style Guide: `Meta` class should come before `get_absolute_url`
|
||||||
]
|
]
|
||||||
|
|
||||||
exclude = [
|
|
||||||
"*/migrations/*.py", # Ignore Django migrations
|
|
||||||
"src/cssmin/*" # cssmin, not our code
|
|
||||||
]
|
|
||||||
|
@@ -56,6 +56,7 @@ MIDDLEWARE = (
|
|||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
'whitenoise.middleware.WhiteNoiseMiddleware',
|
||||||
'django.middleware.http.ConditionalGetMiddleware',
|
'django.middleware.http.ConditionalGetMiddleware',
|
||||||
'csp.middleware.CSPMiddleware',
|
'csp.middleware.CSPMiddleware',
|
||||||
)
|
)
|
||||||
@@ -266,9 +267,7 @@ if DEBUG_TOOLBAR:
|
|||||||
INSTALLED_APPS = [*list(INSTALLED_APPS), 'debug_toolbar']
|
INSTALLED_APPS = [*list(INSTALLED_APPS), 'debug_toolbar']
|
||||||
|
|
||||||
if PROMETHEUS_METRICS:
|
if PROMETHEUS_METRICS:
|
||||||
MIDDLEWARE = ['django_prometheus.middleware.PrometheusBeforeMiddleware',
|
MIDDLEWARE = ['django_prometheus.middleware.PrometheusBeforeMiddleware', *list(MIDDLEWARE), 'django_prometheus.middleware.PrometheusAfterMiddleware']
|
||||||
*list(MIDDLEWARE),
|
|
||||||
'django_prometheus.middleware.PrometheusAfterMiddleware']
|
|
||||||
|
|
||||||
INSTALLED_APPS = [*list(INSTALLED_APPS), 'django_prometheus']
|
INSTALLED_APPS = [*list(INSTALLED_APPS), 'django_prometheus']
|
||||||
|
|
||||||
|
@@ -754,10 +754,6 @@ table.results {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results [hidden] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pkglist: layout */
|
/* pkglist: layout */
|
||||||
#pkglist-about {
|
#pkglist-about {
|
||||||
margin-top: 1.5em;
|
margin-top: 1.5em;
|
||||||
@@ -1060,12 +1056,12 @@ table td.country {
|
|||||||
background: #ffd;
|
background: #ffd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results tr:nth-child(even of :not([hidden])),
|
.results tr:nth-child(even),
|
||||||
#article-list tr:nth-child(even) {
|
#article-list tr:nth-child(even) {
|
||||||
background: #e4eeff;
|
background: #e4eeff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results tr:nth-child(odd of :not([hidden])),
|
.results tr:nth-child(odd),
|
||||||
#article-list tr:nth-child(odd) {
|
#article-list tr:nth-child(odd) {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
@@ -212,14 +212,8 @@ function filter_pkgs_list(filter_ele, tbody_ele) {
|
|||||||
rows = rows.has('.incomplete');
|
rows = rows.has('.incomplete');
|
||||||
}
|
}
|
||||||
/* hide all rows, then show the set we care about */
|
/* hide all rows, then show the set we care about */
|
||||||
// note that we don't use .hide() from jQuery because it adds display:none
|
all_rows.hide();
|
||||||
// which is very expensive to query in CSS ([style*="display: none"])
|
rows.show();
|
||||||
all_rows.each(function() {
|
|
||||||
$(this).attr('hidden', true);
|
|
||||||
});
|
|
||||||
rows.each(function() {
|
|
||||||
$(this).removeAttr('hidden');
|
|
||||||
});
|
|
||||||
$('#filter-count').text(rows.length);
|
$('#filter-count').text(rows.length);
|
||||||
/* make sure we update the odd/even styling from sorting */
|
/* make sure we update the odd/even styling from sorting */
|
||||||
$('.results').trigger('applyWidgets', [false]);
|
$('.results').trigger('applyWidgets', [false]);
|
||||||
@@ -336,14 +330,8 @@ function filter_signoffs() {
|
|||||||
rows = rows.has('td.signoff-no');
|
rows = rows.has('td.signoff-no');
|
||||||
}
|
}
|
||||||
/* hide all rows, then show the set we care about */
|
/* hide all rows, then show the set we care about */
|
||||||
// note that we don't use .hide() from jQuery because it adds display:none
|
all_rows.hide();
|
||||||
// which is very expensive to query in CSS ([style*="display: none"])
|
rows.show();
|
||||||
all_rows.each(function() {
|
|
||||||
$(this).attr('hidden', true);
|
|
||||||
});
|
|
||||||
rows.each(function() {
|
|
||||||
$(this).removeAttr('hidden');
|
|
||||||
});
|
|
||||||
$('#filter-count').text(rows.length);
|
$('#filter-count').text(rows.length);
|
||||||
/* make sure we update the odd/even styling from sorting */
|
/* make sure we update the odd/even styling from sorting */
|
||||||
$('.results').trigger('applyWidgets', [false]);
|
$('.results').trigger('applyWidgets', [false]);
|
||||||
|
190
sitestatic/artixweb.css
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
html body {
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:link,
|
||||||
|
a:visited,
|
||||||
|
th a:visited {
|
||||||
|
color: #0a6682;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover,
|
||||||
|
a:focus,
|
||||||
|
a:visited:hover {
|
||||||
|
color: #1696bd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#archnavbarlogo {
|
||||||
|
width: 120px !important;
|
||||||
|
background-size: contain !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#archnavbar#archnavbar {
|
||||||
|
border-bottom: 5px #0a6682 solid !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
white-space: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.results.results {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results.results td,
|
||||||
|
.results.results th {
|
||||||
|
text-align: left;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results th {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
select {
|
||||||
|
vertical-align: middle;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #858585;
|
||||||
|
padding: .25em;
|
||||||
|
max-width: 85vw;
|
||||||
|
max-width: calc(92vw - 16px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pkglist-results-form {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr :nth-child(7) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 750px) {
|
||||||
|
tr :nth-child(5) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 700px) {
|
||||||
|
tr :nth-child(6) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#archnavbarlogo {
|
||||||
|
float: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#archnavbarlist {
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 520px) {
|
||||||
|
tr :nth-child(4) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pkglist-results .pkglist-nav {
|
||||||
|
float: none;
|
||||||
|
margin-top: initial;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pkgdetails #detailslinks {
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pkgdetails #pkgdeps,
|
||||||
|
#pkgdetails #pkgreqs {
|
||||||
|
float: none;
|
||||||
|
width: initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media not all and (prefers-color-scheme: light) {
|
||||||
|
html body {
|
||||||
|
background: #1a1a1a;
|
||||||
|
color: #d9d9d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:link,
|
||||||
|
a:visited,
|
||||||
|
th a:visited {
|
||||||
|
color: #53bffc;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover,
|
||||||
|
a:focus,
|
||||||
|
a:visited:hover {
|
||||||
|
color: #92D7FC;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pkgdetails #pkginfo .recent {
|
||||||
|
color: #B39DDB;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.box.box {
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
border: 1px solid #858585;
|
||||||
|
}
|
||||||
|
|
||||||
|
table th.tablesorter-header {
|
||||||
|
background-image: url(data:image/gif;base64,R0lGODlhFQAJAPABAOTu/wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFAgABACwAAAAAFQAJAAACF4yPgMsJ2mJ4VDKKrd4GVz5lYPeMiVUAADs=);
|
||||||
|
}
|
||||||
|
|
||||||
|
table thead th.tablesorter-headerAsc {
|
||||||
|
background-color: #173f59;
|
||||||
|
background-image: url(data:image/gif;base64,R0lGODlhFQAEAPABAOTu/wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFAgABACwAAAAAFQAEAAACDYyPAcmtsJyDVDKKWQEAOw==);
|
||||||
|
}
|
||||||
|
|
||||||
|
table thead th.tablesorter-headerDesc {
|
||||||
|
background-color: #173f59;
|
||||||
|
background-image: url(data:image/gif;base64,R0lGODlhFQAEAPABAOTu/wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFAgABACwAAAAAFQAEAAACDYwfoAvoz9qbZ9FrJC0AOw==);
|
||||||
|
}
|
||||||
|
|
||||||
|
.results.results td,
|
||||||
|
.results.results th {
|
||||||
|
border: 1px solid #858585;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results.results tr:nth-child(2n+1) {
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results.results tr:nth-child(even) {
|
||||||
|
background-color: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results th {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #0f3147;
|
||||||
|
border: 1px solid #0A6682;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pkglist-results .results tr:hover {
|
||||||
|
background: #0d0d0d;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pkgdetails #detailslinks>div {
|
||||||
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
select {
|
||||||
|
background: #1a1a1a;
|
||||||
|
color: #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
select option:checked {
|
||||||
|
background: linear-gradient(#0A6682, #0A6682);
|
||||||
|
background-color: #0A6682;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pkgfilelist li.d {
|
||||||
|
color: #92929a;
|
||||||
|
}
|
||||||
|
}
|
@@ -4,8 +4,10 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="theme-color" content="#08C" />
|
<meta name="theme-color" content="#08C" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{% block title %}Arch Linux{% endblock %}</title>
|
<title>{% block title %}Arch Linux{% endblock %}</title>
|
||||||
<link rel="stylesheet" type="text/css" href="{% static "archweb.css" %}" media="screen" />
|
<link rel="stylesheet" type="text/css" href="{% static "archweb.css" %}" media="screen" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static "artixweb.css" %}" media="screen" />
|
||||||
<link rel="icon" type="image/png" href="{% static "favicon.png" %}" />
|
<link rel="icon" type="image/png" href="{% static "favicon.png" %}" />
|
||||||
<link rel="shortcut icon" type="image/png" href="{% static "favicon.png" %}" />
|
<link rel="shortcut icon" type="image/png" href="{% static "favicon.png" %}" />
|
||||||
<link rel="apple-touch-icon" href="{% static "logos/apple-touch-icon-57x57.png" %}" />
|
<link rel="apple-touch-icon" href="{% static "logos/apple-touch-icon-57x57.png" %}" />
|
||||||
@@ -20,14 +22,16 @@
|
|||||||
<div id="archnavbarlogo"><h1><a href="/" title="Return to the main page">Arch Linux</a></h1></div>
|
<div id="archnavbarlogo"><h1><a href="/" title="Return to the main page">Arch Linux</a></h1></div>
|
||||||
<div id="archnavbarmenu">
|
<div id="archnavbarmenu">
|
||||||
<ul id="archnavbarlist">
|
<ul id="archnavbarlist">
|
||||||
<li id="anb-home"><a href="/" title="Arch news, packages, projects and more">Home</a></li>
|
<li id="anb-home"><a href="https://artixlinux.org/" title="Artix Linux home">Home</a></li>
|
||||||
<li id="anb-packages"><a href="/packages/" title="Arch Package Database">Packages</a></li>
|
<li id="anb-packages"><a href="/packages/" title="Arch Package Database">Packages</a></li>
|
||||||
<li id="anb-forums"><a href="https://bbs.archlinux.org/" title="Community forums">Forums</a></li>
|
<li id="anb-forums"><a href="https://forum.artixlinux.org/" title="Community forums">Forums</a></li>
|
||||||
<li id="anb-wiki"><a href="https://wiki.archlinux.org/" title="Community documentation">Wiki</a></li>
|
<li id="anb-wiki"><a href="https://wiki.artixlinux.org/" title="Community documentation">Wiki</a></li>
|
||||||
<li id="anb-gitlab"><a href="https://gitlab.archlinux.org/archlinux" title="GitLab">GitLab</a></li>
|
<li id="anb-gitlab"><a href="https://gitea.artixlinux.org/explore/repos" title="Artix Sources">Sources</a></li>
|
||||||
|
<!--
|
||||||
<li id="anb-security"><a href="https://security.archlinux.org/" title="Arch Linux Security Tracker">Security</a></li>
|
<li id="anb-security"><a href="https://security.archlinux.org/" title="Arch Linux Security Tracker">Security</a></li>
|
||||||
|
-->
|
||||||
<li id="anb-aur"><a href="https://aur.archlinux.org/" title="Arch Linux User Repository">AUR</a></li>
|
<li id="anb-aur"><a href="https://aur.archlinux.org/" title="Arch Linux User Repository">AUR</a></li>
|
||||||
<li id="anb-download"><a href="{% url 'page-download' as pdl %}{{ pdl }}" title="Get Arch Linux">Download</a></li>
|
<li id="anb-download"><a href="https://artixlinux.org/download.php" title="Get Arch Linux">Download</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -81,17 +85,12 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
<div id="footer">
|
<div id="footer">
|
||||||
<p>Copyright © 2002-{% now "Y" %} <a href="mailto:jvinet@zeroflux.org"
|
<p>Copyright © 2017-{% now "Y" %} Artix Linux</p>
|
||||||
|
|
||||||
|
<p>Website software and layout is derivative of archweb, Copyright © 2002-{% now "Y" %} <a href="mailto:jvinet@zeroflux.org"
|
||||||
title="Contact Judd Vinet">Judd Vinet</a>, <a href="mailto:aaron@archlinux.org"
|
title="Contact Judd Vinet">Judd Vinet</a>, <a href="mailto:aaron@archlinux.org"
|
||||||
title="Contact Aaron Griffin">Aaron Griffin</a> and
|
title="Contact Aaron Griffin">Aaron Griffin</a> and
|
||||||
<a href="mailto:anthraxx@archlinux.org" title="Contact Levente Polyák">Levente Polyák</a>.</p>
|
<a href="mailto:anthraxx@archlinux.org" title="Contact Levente Polyák">Levente Polyák</a>.</p>
|
||||||
|
|
||||||
<p>The Arch Linux name and logo are recognized
|
|
||||||
<a href="https://terms.archlinux.org/docs/trademark-policy/"
|
|
||||||
title="Arch Linux Trademark Policy">trademarks</a>. Some rights reserved.</p>
|
|
||||||
|
|
||||||
<p>The registered trademark Linux® is used pursuant to a sublicense from LMI,
|
|
||||||
the exclusive licensee of Linus Torvalds, owner of the mark on a world-wide basis.</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="application/ld+json">
|
<script type="application/ld+json">
|
||||||
|
@@ -36,8 +36,8 @@
|
|||||||
{% endif %}{% endwith %}</td>
|
{% endif %}{% endwith %}</td>
|
||||||
<td>{{ pkg.repo.name }}</td>
|
<td>{{ pkg.repo.name }}</td>
|
||||||
<td>{{ pkg.arch.name }}</td>
|
<td>{{ pkg.arch.name }}</td>
|
||||||
<td>{{ pkg.flag_date|date:"Y-m-d" }}</td>
|
<td>{{ pkg.flag_date|date }}</td>
|
||||||
<td>{{ pkg.last_update|date:"Y-m-d" }}</td>
|
<td>{{ pkg.last_update|date }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr class="empty"><td colspan="7"><em>No flagged packages to display</em></td></tr>
|
<tr class="empty"><td colspan="7"><em>No flagged packages to display</em></td></tr>
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
<td>{{ group.version }}</td>
|
<td>{{ group.version }}</td>
|
||||||
<td>{{ group.arch.name }}</td>
|
<td>{{ group.arch.name }}</td>
|
||||||
<td>{{ group.target_repo }}</td>
|
<td>{{ group.target_repo }}</td>
|
||||||
<td>{{ group.last_update|date:"Y-m-d" }}</td>
|
<td>{{ group.last_update|date }}</td>
|
||||||
{% if group.specification.known_bad %}
|
{% if group.specification.known_bad %}
|
||||||
<td class="approval signoff-bad">Bad</td>
|
<td class="approval signoff-bad">Bad</td>
|
||||||
{% else %}
|
{% else %}
|
||||||
@@ -138,7 +138,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="wrap"><a href="{{ todo.get_absolute_url }}"
|
<td class="wrap"><a href="{{ todo.get_absolute_url }}"
|
||||||
title="View todo list: {{ todo.name }}">{{ todo.name }}</a></td>
|
title="View todo list: {{ todo.name }}">{{ todo.name }}</a></td>
|
||||||
<td>{{ todo.created|date:"Y-m-d" }}</td>
|
<td>{{ todo.created|date }}</td>
|
||||||
<td>{{ todo.creator.get_full_name }}</td>
|
<td>{{ todo.creator.get_full_name }}</td>
|
||||||
<td>{{ todo.pkg_count }}</td>
|
<td>{{ todo.pkg_count }}</td>
|
||||||
<td>{{ todo.incomplete_count }}</td>
|
<td>{{ todo.incomplete_count }}</td>
|
||||||
|
@@ -60,9 +60,9 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<td>{{ pkg.full_version }}</td>
|
<td>{{ pkg.full_version }}</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td>{{ pkg.last_update|date:"Y-m-d" }}</td>
|
<td>{{ pkg.last_update|date }}</td>
|
||||||
<td>{{ pkg.build_date|date:"Y-m-d" }}</td>
|
<td>{{ pkg.build_date|date }}</td>
|
||||||
<td>{{ pkg.flag_date|date:"Y-m-d" }}</td>
|
<td>{{ pkg.flag_date|date }}</td>
|
||||||
{% for attr in column_attrs %}
|
{% for attr in column_attrs %}
|
||||||
<td>{{ pkg|attribute:attr }}</td>
|
<td>{{ pkg|attribute:attr }}</td>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@@ -33,7 +33,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for item in news_list %}
|
{% for item in news_list %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ item.postdate|date:"Y-m-d" }}</td>
|
<td>{{ item.postdate|date }}</td>
|
||||||
<td class="wrap"><a href="{{ item.get_absolute_url }}"
|
<td class="wrap"><a href="{{ item.get_absolute_url }}"
|
||||||
title="View: {{ item.title }}">{{ item.title }}</a></td>
|
title="View: {{ item.title }}">{{ item.title }}</a></td>
|
||||||
<td>{{ item.author.get_full_name }}</td>
|
<td>{{ item.author.get_full_name }}</td>
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<p class="article-info">{{ news.postdate|date:"Y-m-d" }} - {{ news.author.get_full_name }}</p>
|
<p class="article-info">{{ news.postdate|date }} - {{ news.author.get_full_name }}</p>
|
||||||
|
|
||||||
<div class="article-content" itemprop="articleBody">{{ news.html }}</div>
|
<div class="article-content" itemprop="articleBody">{{ news.html }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -29,8 +29,8 @@
|
|||||||
<td><span{% if pkg2.flag_date %} class="flagged"{% endif %}>{{ pkg2.full_version }}</span></td>
|
<td><span{% if pkg2.flag_date %} class="flagged"{% endif %}>{{ pkg2.full_version }}</span></td>
|
||||||
<td>{% pkg_details_link pkg2 %}</td>
|
<td>{% pkg_details_link pkg2 %}</td>
|
||||||
<td>{{ pkg2.repo }}</td>
|
<td>{{ pkg2.repo }}</td>
|
||||||
<td>{{ pkg1.last_update|date:"Y-m-d" }}</td>
|
<td>{{ pkg1.last_update|date }}</td>
|
||||||
<td>{{ pkg2.last_update|date:"Y-m-d" }}</td>
|
<td>{{ pkg2.last_update|date }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
<td><a href="/groups/{{ grp.arch }}/{{ grp.name }}/"
|
<td><a href="/groups/{{ grp.arch }}/{{ grp.name }}/"
|
||||||
title="Group details for {{ grp.name }}">{{ grp.name }}</a></td>
|
title="Group details for {{ grp.name }}">{{ grp.name }}</a></td>
|
||||||
<td>{{ grp.count }}</td>
|
<td>{{ grp.count }}</td>
|
||||||
<td>{{ grp.last_update|date:"Y-m-d" }}</td>
|
<td>{{ grp.last_update|date }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
{% load static %}<?xml version="1.0" encoding="UTF-8"?>
|
{% load static %}<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
|
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
|
||||||
<ShortName>Arch Packages</ShortName>
|
<ShortName>Artix Packages</ShortName>
|
||||||
<LongName>Arch Linux Package Repository Search</LongName>
|
<LongName>Artix Linux Package Repository Search</LongName>
|
||||||
<Description>Search the Arch Linux package repositories by keyword in package names and descriptions.</Description>
|
<Description>Search the Artix Linux package repositories by keyword in package names and descriptions.</Description>
|
||||||
<Tags>linux archlinux package software</Tags>
|
<Tags>linux artixlinux package software</Tags>
|
||||||
<Image height="16" width="16" type="image/png">{{ domain }}{% static "favicon.png" %}</Image>
|
<Image height="16" width="16" type="image/png">{{ domain }}{% static "favicon.png" %}</Image>
|
||||||
<Image height="64" width="64" type="image/png">{{ domain }}{% static "logos/icon-transparent-64x64.png" %}</Image>
|
<Image height="64" width="64" type="image/png">{{ domain }}{% static "logos/icon-transparent-64x64.png" %}</Image>
|
||||||
<Language>en-us</Language>
|
<Language>en-us</Language>
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
<a href="{% scm_link pkg 'tree' %}" title="View source files for {{ pkg.pkgname }}">Source Files</a> /
|
<a href="{% scm_link pkg 'tree' %}" title="View source files for {{ pkg.pkgname }}">Source Files</a> /
|
||||||
<a href="{% scm_link pkg 'commits' %}" title="View changes for {{ pkg.pkgname }}">View Changes</a>
|
<a href="{% scm_link pkg 'commits' %}" title="View changes for {{ pkg.pkgname }}">View Changes</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% comment %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{% bugs_list pkg %}" title="View existing bug tickets for {{ pkg.pkgname }}">Bug Reports</a> /
|
<a href="{% bugs_list pkg %}" title="View existing bug tickets for {{ pkg.pkgname }}">Bug Reports</a> /
|
||||||
<a href="{% bug_report pkg %}" title="Report new bug for {{ pkg.pkgname }}">Add New Bug</a>
|
<a href="{% bug_report pkg %}" title="Report new bug for {{ pkg.pkgname }}">Add New Bug</a>
|
||||||
@@ -20,6 +21,8 @@
|
|||||||
<a href="{% man_link pkg %}" title="List manpages in {{ pkg.pkgname }}">Manual Pages</a>
|
<a href="{% man_link pkg %}" title="List manpages in {{ pkg.pkgname }}">Manual Pages</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="{% sec_link pkg %}" title="View security issues for {{ pkg.pkgname }}">Security Issues</a></li>
|
<li><a href="{% sec_link pkg %}" title="View security issues for {{ pkg.pkgname }}">Security Issues</a></li>
|
||||||
|
{% endcomment %}
|
||||||
|
<li><a href="{% upstream_link pkg %}" title="View {{ pkg.pkgname }} in Arch's repos">View Upstream</a></li>
|
||||||
{% if user.is_authenticated and notreproducible %}<tr>
|
{% if user.is_authenticated and notreproducible %}<tr>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% rebuilderd_buildlog_link rbstatus %}" title="View build log for {{ pkg.pkgname }}">Build log</a> /
|
<a href="{% rebuilderd_buildlog_link rbstatus %}" title="View build log for {{ pkg.pkgname }}">Build log</a> /
|
||||||
@@ -27,7 +30,7 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if pkg.flag_date %}
|
{% if pkg.flag_date %}
|
||||||
<li><span class="flagged">Flagged out-of-date on {{ pkg.flag_date|date:"Y-m-d" }}</span></li>
|
<li><span class="flagged">Flagged out-of-date on {{ pkg.flag_date|date }}</span></li>
|
||||||
{% with tp=pkg.in_testing %}{% if tp %}
|
{% with tp=pkg.in_testing %}{% if tp %}
|
||||||
<li><span class="flagged">Version
|
<li><span class="flagged">Version
|
||||||
<a href="{{ tp.get_absolute_url }}"
|
<a href="{{ tp.get_absolute_url }}"
|
||||||
@@ -41,11 +44,13 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
{% comment %}
|
||||||
<li><a href="flag/" title="Flag {{ pkg.pkgname }} as out-of-date">Flag Package Out-of-Date</a>
|
<li><a href="flag/" title="Flag {{ pkg.pkgname }} as out-of-date">Flag Package Out-of-Date</a>
|
||||||
<a href="/packages/flaghelp/"
|
<a href="/packages/flaghelp/"
|
||||||
title="Get help on package flagging"
|
title="Get help on package flagging"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>(?)</a></li>
|
>(?)</a></li>
|
||||||
|
{% endcomment %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><a href="download/" rel="nofollow" title="Download {{ pkg.pkgname }} from mirror">Download From Mirror</a></li>
|
<li><a href="download/" rel="nofollow" title="Download {{ pkg.pkgname }} from mirror">Download From Mirror</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -118,7 +123,7 @@
|
|||||||
<th>Description:</th>
|
<th>Description:</th>
|
||||||
<td class="wrap" itemprop="description">{{ pkg.pkgdesc|default:"" }}</td>
|
<td class="wrap" itemprop="description">{{ pkg.pkgdesc|default:"" }}</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<th>Upstream URL:</th>
|
<th>Homepage:</th>
|
||||||
<td>{% if pkg.url %}<a itemprop="url" href="{{ pkg.url }}"
|
<td>{% if pkg.url %}<a itemprop="url" href="{{ pkg.url }}"
|
||||||
title="Visit the website for {{ pkg.pkgname }}">{{ pkg.url|url_unquote }}</a>{% endif %}</td>
|
title="Visit the website for {{ pkg.pkgname }}">{{ pkg.url|url_unquote }}</a>{% endif %}</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
@@ -159,6 +164,7 @@
|
|||||||
<span class="related">{% details_link conflict %}{% if not forloop.last %}, {% endif %}</span>{% endfor %}</td>
|
<span class="related">{% details_link conflict %}{% if not forloop.last %}, {% endif %}</span>{% endfor %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}{% endwith %}
|
{% endif %}{% endwith %}
|
||||||
|
{% if pkg.maintainers %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Maintainers:</th>
|
<th>Maintainers:</th>
|
||||||
{% with maints=pkg.maintainers %}
|
{% with maints=pkg.maintainers %}
|
||||||
@@ -168,7 +174,7 @@
|
|||||||
{% endfor %}{% else %}Orphan{% endif %}
|
{% endfor %}{% else %}Orphan{% endif %}
|
||||||
</td>
|
</td>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</tr><tr>
|
</tr>{% endif %}<tr>
|
||||||
<th>Package Size:</th>
|
<th>Package Size:</th>
|
||||||
<td>{{ pkg.compressed_size|filesizeformat }}</td>
|
<td>{{ pkg.compressed_size|filesizeformat }}</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
@@ -207,7 +213,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.is_authenticated %}{% with flag_request=pkg.flag_request %}{% if flag_request %}<tr>
|
{% if user.is_authenticated %}{% with flag_request=pkg.flag_request %}{% if flag_request %}<tr>
|
||||||
<th>Last Flag Request:</th>
|
<th>Last Flag Request:</th>
|
||||||
<td class="wrap">From {{ flag_request.who }} on {{ flag_request.created|date:"Y-m-d" }}:<br/>
|
<td class="wrap">From {{ flag_request.who }} on {{ flag_request.created|date }}:<br/>
|
||||||
<div class="userdata">{{ flag_request.message|linebreaksbr|default:"{no message}" }}</div></td>
|
<div class="userdata">{{ flag_request.message|linebreaksbr|default:"{no message}" }}</div></td>
|
||||||
</tr>{% endif %}{% endwith %}{% endif %}
|
</tr>{% endif %}{% endwith %}{% endif %}
|
||||||
</table>
|
</table>
|
||||||
|
@@ -33,8 +33,8 @@
|
|||||||
<td>{{ pkg.full_version }}</td>
|
<td>{{ pkg.full_version }}</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td class="wrap">{{ pkg.pkgdesc }}</td>
|
<td class="wrap">{{ pkg.pkgdesc }}</td>
|
||||||
<td>{{ pkg.last_update|date:"Y-m-d" }}</td>
|
<td>{{ pkg.last_update|date }}</td>
|
||||||
<td>{{ pkg.flag_date|date:"Y-m-d" }}</td>
|
<td>{{ pkg.flag_date|date }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -27,12 +27,14 @@
|
|||||||
<div>{{ search_form.q.errors }}
|
<div>{{ search_form.q.errors }}
|
||||||
<label for="id_q" title="Enter keywords as desired (provides are also supported e.g. 'java-environment=7')">
|
<label for="id_q" title="Enter keywords as desired (provides are also supported e.g. 'java-environment=7')">
|
||||||
Keywords</label>{{ search_form.q }}</div>
|
Keywords</label>{{ search_form.q }}</div>
|
||||||
|
{% comment %}
|
||||||
<div>{{ search_form.maintainer.errors }}
|
<div>{{ search_form.maintainer.errors }}
|
||||||
<label for="id_maintainer" title="Limit results to a specific maintainer">
|
<label for="id_maintainer" title="Limit results to a specific maintainer">
|
||||||
Maintainer</label>{{ search_form.maintainer}}</div>
|
Maintainer</label>{{ search_form.maintainer}}</div>
|
||||||
<div>{{ search_form.flagged.errors }}
|
<div>{{ search_form.flagged.errors }}
|
||||||
<label for="id_flagged" title="Limit results based on out-of-date status">
|
<label for="id_flagged" title="Limit results based on out-of-date status">
|
||||||
Flagged</label>{{ search_form.flagged }}</div>
|
Flagged</label>{{ search_form.flagged }}</div>
|
||||||
|
{% endcomment %}
|
||||||
<div><label> </label><input title="Search for packages using this criteria"
|
<div><label> </label><input title="Search for packages using this criteria"
|
||||||
type="submit" value="Search" /></div>
|
type="submit" value="Search" /></div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -68,8 +70,8 @@
|
|||||||
<td>{{ pkg.full_version }}</td>
|
<td>{{ pkg.full_version }}</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td class="wrap">{{ pkg.pkgdesc }}</td>
|
<td class="wrap">{{ pkg.pkgdesc }}</td>
|
||||||
<td>{{ pkg.last_update|date:"Y-m-d" }}</td>
|
<td>{{ pkg.last_update|date }}</td>
|
||||||
<td>{{ pkg.flag_date|date:"Y-m-d" }}</td>
|
<td>{{ pkg.flag_date|date }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -115,8 +117,8 @@
|
|||||||
<td>{{ pkg.full_version }}</td>
|
<td>{{ pkg.full_version }}</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td class="wrap">{{ pkg.pkgdesc }}</td>
|
<td class="wrap">{{ pkg.pkgdesc }}</td>
|
||||||
<td>{{ pkg.last_update|date:"Y-m-d" }}</td>
|
<td>{{ pkg.last_update|date }}</td>
|
||||||
<td>{{ pkg.flag_date|date:"Y-m-d" }}</td>
|
<td>{{ pkg.flag_date|date }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr class="empty"><td colspan="{% if perms.main.change_package %}8{% else %}7{% endif %}"><em>No matching packages found</em></td></tr>
|
<tr class="empty"><td colspan="{% if perms.main.change_package %}8{% else %}7{% endif %}"><em>No matching packages found</em></td></tr>
|
||||||
|
@@ -56,7 +56,7 @@
|
|||||||
<td>{{ group.target_repo }}</td>
|
<td>{{ group.target_repo }}</td>
|
||||||
<td>{{ group.packager|default:"Unknown" }}</td>
|
<td>{{ group.packager|default:"Unknown" }}</td>
|
||||||
<td>{{ group.packages|length }}</td>
|
<td>{{ group.packages|length }}</td>
|
||||||
<td class="epoch-{{ group.last_update|date:'U' }}">{{ group.last_update|date:"Y-m-d" }}</td>
|
<td class="epoch-{{ group.last_update|date:'U' }}">{{ group.last_update|date }}</td>
|
||||||
{% if group.specification.known_bad %}
|
{% if group.specification.known_bad %}
|
||||||
<td class="approval signoff-bad">Bad</td>
|
<td class="approval signoff-bad">Bad</td>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
<a href="{{ entry.url }}"
|
<a href="{{ entry.url }}"
|
||||||
title="View full article: {{ entry.title }}">{{ entry.title }}</a>
|
title="View full article: {{ entry.title }}">{{ entry.title }}</a>
|
||||||
</h4>
|
</h4>
|
||||||
<p class="timestamp">{{ entry.publishdate|date:"Y-m-d" }}</p>
|
<p class="timestamp">{{ entry.publishdate|date }}</p>
|
||||||
<div class="article-content">
|
<div class="article-content">
|
||||||
{{ entry.summary |safe }}
|
{{ entry.summary |safe }}
|
||||||
</div>
|
</div>
|
||||||
|
@@ -50,7 +50,7 @@
|
|||||||
<a href="{{ news.get_absolute_url }}"
|
<a href="{{ news.get_absolute_url }}"
|
||||||
title="View full article: {{ news.title }}">{{ news.title }}</a>
|
title="View full article: {{ news.title }}">{{ news.title }}</a>
|
||||||
</h4>
|
</h4>
|
||||||
<p class="timestamp">{{ news.postdate|date:"Y-m-d" }}</p>
|
<p class="timestamp">{{ news.postdate|date }}</p>
|
||||||
<div class="article-content">
|
<div class="article-content">
|
||||||
{% if forloop.counter0 == 0 %}{{ news.html|truncatewords_html:300 }}
|
{% if forloop.counter0 == 0 %}{{ news.html|truncatewords_html:300 }}
|
||||||
{% else %}{{ news.html|truncatewords_html:100 }}{% endif %}
|
{% else %}{{ news.html|truncatewords_html:100 }}{% endif %}
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
</h3>
|
</h3>
|
||||||
<dl class="newslist">
|
<dl class="newslist">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<dt>{{ news.postdate|date:"Y-m-d" }}</dt>
|
<dt>{{ news.postdate|date }}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="{{ news.get_absolute_url }}"
|
<a href="{{ news.get_absolute_url }}"
|
||||||
title="View full article: {{ news.title }}">{{ news.title }}</a>
|
title="View full article: {{ news.title }}">{{ news.title }}</a>
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
<h2>{{ release.version }}</h2>
|
<h2>{{ release.version }}</h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Release Date:</strong> {{ release.release_date|date:"Y-m-d" }}</li>
|
<li><strong>Release Date:</strong> {{ release.release_date|date }}</li>
|
||||||
{% if release.kernel_version %}<li><strong>Kernel Version:</strong> {{ release.kernel_version }}</li>{% endif %}
|
{% if release.kernel_version %}<li><strong>Kernel Version:</strong> {{ release.kernel_version }}</li>{% endif %}
|
||||||
<li><strong>Available:</strong> {{ release.available|yesno|capfirst }}</li>
|
<li><strong>Available:</strong> {{ release.available|yesno|capfirst }}</li>
|
||||||
{% if release.torrent_data %}
|
{% if release.torrent_data %}
|
||||||
|
@@ -42,7 +42,7 @@
|
|||||||
<a href="{{ item.magnet_uri }}"
|
<a href="{{ item.magnet_uri }}"
|
||||||
title="Get magnet link for {{ item.version }}"><img width="12" height="12" src="{% static "magnet.png" %}" alt="Magnet"/></a>
|
title="Get magnet link for {{ item.version }}"><img width="12" height="12" src="{% static "magnet.png" %}" alt="Magnet"/></a>
|
||||||
{% endif %}</td>
|
{% endif %}</td>
|
||||||
<td>{{ item.release_date|date:"Y-m-d" }}</td>
|
<td>{{ item.release_date|date }}</td>
|
||||||
<td><a href="{{ item.get_absolute_url }}" title="Release details for {{ item.version }}">{{ item.version }}</a></td>
|
<td><a href="{{ item.get_absolute_url }}" title="Release details for {{ item.version }}">{{ item.version }}</a></td>
|
||||||
<td>{{ item.kernel_version|default:"" }}</td>
|
<td>{{ item.kernel_version|default:"" }}</td>
|
||||||
<td class="available-{{ item.available|yesno }}">{{ item.available|yesno|capfirst }}</td>
|
<td class="available-{{ item.available|yesno }}">{{ item.available|yesno|capfirst }}</td>
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="wrap"><a href="{{ list.get_absolute_url }}"
|
<td class="wrap"><a href="{{ list.get_absolute_url }}"
|
||||||
title="View todo list: {{ list.name }}">{{ list.name }}</a></td>
|
title="View todo list: {{ list.name }}">{{ list.name }}</a></td>
|
||||||
<td>{{ list.created|date:"Y-m-d" }}</td>
|
<td>{{ list.created|date }}</td>
|
||||||
<td>{{ list.creator.get_full_name }}</td>
|
<td>{{ list.creator.get_full_name }}</td>
|
||||||
<td>{{ list.pkg_count }}</td>
|
<td>{{ list.pkg_count }}</td>
|
||||||
<td>{{ list.incomplete_count }}</td>
|
<td>{{ list.incomplete_count }}</td>
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="todo-info">{{ list.created|date:"Y-m-d" }} - {{ list.creator.get_full_name }}</div>
|
<div class="todo-info">{{ list.created|date }} - {{ list.creator.get_full_name }}</div>
|
||||||
|
|
||||||
<div class="todo-description">
|
<div class="todo-description">
|
||||||
{{list.stripped_description|default:'(no description)'|urlize|linebreaks}}
|
{{list.stripped_description|default:'(no description)'|urlize|linebreaks}}
|
||||||
|
@@ -28,9 +28,7 @@ class Migration(migrations.Migration):
|
|||||||
('created', models.DateTimeField(db_index=True)),
|
('created', models.DateTimeField(db_index=True)),
|
||||||
('last_modified', models.DateTimeField(editable=False)),
|
('last_modified', models.DateTimeField(editable=False)),
|
||||||
('raw', models.TextField(blank=True)),
|
('raw', models.TextField(blank=True)),
|
||||||
('creator', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
|
('creator', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='created_todolists', to=settings.AUTH_USER_MODEL)),
|
||||||
related_name='created_todolists',
|
|
||||||
to=settings.AUTH_USER_MODEL)),
|
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'get_latest_by': 'created',
|
'get_latest_by': 'created',
|
||||||
@@ -45,16 +43,13 @@ class Migration(migrations.Migration):
|
|||||||
('created', models.DateTimeField(editable=False)),
|
('created', models.DateTimeField(editable=False)),
|
||||||
('last_modified', models.DateTimeField(editable=False)),
|
('last_modified', models.DateTimeField(editable=False)),
|
||||||
('removed', models.DateTimeField(blank=True, null=True)),
|
('removed', models.DateTimeField(blank=True, null=True)),
|
||||||
('status', models.SmallIntegerField(choices=[(0, 'Incomplete'), (1, 'Complete'), (2, 'In-progress')],
|
('status', models.SmallIntegerField(choices=[(0, 'Incomplete'), (1, 'Complete'), (2, 'In-progress')], default=0)),
|
||||||
default=0)),
|
|
||||||
('comments', models.TextField(blank=True, null=True)),
|
('comments', models.TextField(blank=True, null=True)),
|
||||||
('arch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.Arch')),
|
('arch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.Arch')),
|
||||||
('pkg', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL,
|
('pkg', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.Package')),
|
||||||
to='main.Package')),
|
|
||||||
('repo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.Repo')),
|
('repo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.Repo')),
|
||||||
('todolist', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='todolists.Todolist')),
|
('todolist', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='todolists.Todolist')),
|
||||||
('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL,
|
('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
|
||||||
to=settings.AUTH_USER_MODEL)),
|
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'get_latest_by': 'created',
|
'get_latest_by': 'created',
|
||||||
|
@@ -13,7 +13,6 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='todolist',
|
model_name='todolist',
|
||||||
name='kind',
|
name='kind',
|
||||||
field=models.SmallIntegerField(choices=[(0, 'Rebuild'), (1, 'Task')], default=0,
|
field=models.SmallIntegerField(choices=[(0, 'Rebuild'), (1, 'Task')], default=0, help_text='(Rebuild for soname bumps, Task for independent tasks)'),
|
||||||
help_text='(Rebuild for soname bumps, Task for independent tasks)'),
|
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
@@ -23,8 +23,7 @@ class Todolist(models.Model):
|
|||||||
description = models.TextField()
|
description = models.TextField()
|
||||||
creator = models.ForeignKey(User, on_delete=models.PROTECT, related_name="created_todolists")
|
creator = models.ForeignKey(User, on_delete=models.PROTECT, related_name="created_todolists")
|
||||||
created = models.DateTimeField(db_index=True)
|
created = models.DateTimeField(db_index=True)
|
||||||
kind = models.SmallIntegerField(default=REBUILD, choices=KIND_CHOICES,
|
kind = models.SmallIntegerField(default=REBUILD, choices=KIND_CHOICES, help_text='(Rebuild for soname bumps, Task for independent tasks)')
|
||||||
help_text='(Rebuild for soname bumps, Task for independent tasks)')
|
|
||||||
last_modified = models.DateTimeField(editable=False)
|
last_modified = models.DateTimeField(editable=False)
|
||||||
raw = models.TextField(blank=True)
|
raw = models.TextField(blank=True)
|
||||||
|
|
||||||
|