Compare commits
40 Commits
Author | SHA1 | Date | |
---|---|---|---|
e024b881a5 | |||
![]() |
fb9b330535 | ||
![]() |
6bc1b49071 | ||
![]() |
0cf24055d5 | ||
52e9a1ae0e | |||
b386d89d6c
|
|||
![]() |
59229f280b | ||
![]() |
4c57725862 | ||
![]() |
8ded12a7cf | ||
![]() |
0180242d2a | ||
![]() |
bf29716008 | ||
9e36ad4e38 | |||
![]() |
2027adaaba | ||
![]() |
05abc7f386 | ||
![]() |
c1d70301c9 | ||
![]() |
323002ffe1 | ||
![]() |
a49a2cadc5 | ||
![]() |
a733efa173 | ||
![]() |
ce776a6297 | ||
![]() |
7126b7b006 | ||
![]() |
ba4eb27ae3 | ||
![]() |
375713717a | ||
93e59ab09b | |||
![]() |
5e33be47a7 | ||
![]() |
4473a9cdba | ||
49d616ef32 | |||
12f795bcf8 | |||
![]() |
24b21bffed | ||
![]() |
7f5d7e9082 | ||
![]() |
653b482ec5 | ||
![]() |
ecc4bdf0a7 | ||
![]() |
a45b88da4b | ||
![]() |
e460ba4727 | ||
![]() |
910e428baa | ||
8e6bc69713 | |||
![]() |
f624f5677b | ||
![]() |
2064099696 | ||
![]() |
67209075c5 | ||
![]() |
336d686ca2 | ||
![]() |
4f0e24f1f7 |
@@ -131,7 +131,7 @@ Archweb provides multiple management commands for importing various sorts of dat
|
||||
* reporead_inotify - Watches a templated patch for updates of *.files.tar.gz to update Arch databases with.
|
||||
* donor_import - Import a single donator from a mail passed to stdin
|
||||
* mirrorcheck - Poll every active mirror URLs to store the lastsnyc time and record network timing details.
|
||||
* mirrorresolv - Poll every active mirror URLs and determine wheteher they have IP4 and/or IPv6 addresses.
|
||||
* mirrorresolv - Poll every active mirror URLs and determine whether they have IP4 and/or IPv6 addresses.
|
||||
* populate_signoffs - retrieves the latest commit message of a signoff-eligible package.
|
||||
* update_planet - Import all feeds for users who have a valid website and website_rss in their user profile.
|
||||
* read_links - Reads a repo.links.db.tar.gz file and updates the Soname model.
|
||||
|
@@ -59,7 +59,7 @@ class Command(BaseCommand):
|
||||
arches = Arch.objects.filter(agnostic=False)
|
||||
repos = Repo.objects.all()
|
||||
|
||||
arch_path_map = {arch: None for arch in arches}
|
||||
arch_path_map = dict.fromkeys(arches)
|
||||
all_paths = set()
|
||||
total_paths = 0
|
||||
for arch in arches:
|
||||
|
@@ -72,7 +72,7 @@ class Command(BaseCommand):
|
||||
arches = Arch.objects.filter(agnostic=False)
|
||||
repos = Repo.objects.all()
|
||||
|
||||
arch_path_map = {arch: None for arch in arches}
|
||||
arch_path_map = dict.fromkeys(arches)
|
||||
all_paths = set()
|
||||
total_paths = 0
|
||||
for arch in arches:
|
||||
|
16
devel/migrations/0011_userprofile_social.py
Normal file
16
devel/migrations/0011_userprofile_social.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('devel', '0010_merge_20230312_1527'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userprofile',
|
||||
name='social',
|
||||
field=models.CharField(blank=True, max_length=200, null=True),
|
||||
),
|
||||
]
|
@@ -40,6 +40,9 @@ class UserProfile(models.Model):
|
||||
website = models.URLField(max_length=200, null=True, blank=True)
|
||||
website_rss = models.URLField(max_length=200, null=True, blank=True,
|
||||
help_text='RSS Feed of your website for planet.archlinux.org')
|
||||
social = models.URLField(max_length=200, null=True, blank=True,
|
||||
verbose_name="Social account URL",
|
||||
help_text="Mastodon or Fediverse account URL")
|
||||
yob = models.IntegerField("Year of birth", null=True, blank=True,
|
||||
validators=[MinValueValidator(1950), MaxValueValidator(2500)])
|
||||
country = CountryField(blank=True)
|
||||
|
@@ -1,20 +1,23 @@
|
||||
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
|
||||
# docker compose run --rm archweb_web python manage.py migrate
|
||||
# docker compose run --rm archweb_web python manage.py loaddata mirrors/fixtures/mirrorprotocols.json
|
||||
# docker compose run --rm archweb_web python manage.py loaddata main/fixtures/arches.json
|
||||
# docker compose run --rm archweb_web python manage.py loaddata main/fixtures/repos.json
|
||||
# docker compose run --rm archweb_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
|
||||
# docker compose run --rm archweb_web python manage.py generate_keyring pgp.surfnet.nl ./config/keyring
|
||||
# docker compose run --rm archweb_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
|
||||
## clone the mirrors repo
|
||||
# docker compose run --rm archweb_web python manage.py loaddata /mirrors/mirrors.fixture.json
|
||||
|
||||
|
||||
services:
|
||||
packages_web:
|
||||
archweb_web:
|
||||
container_name: artixweb-packages
|
||||
build:
|
||||
context: ./
|
||||
@@ -25,7 +28,7 @@ services:
|
||||
volumes:
|
||||
- ./config:/usr/src/web/config
|
||||
|
||||
packages_sync:
|
||||
archweb_sync:
|
||||
container_name: artixweb-sync
|
||||
build:
|
||||
context: ./
|
||||
@@ -35,7 +38,7 @@ services:
|
||||
- ./config:/usr/src/web/config
|
||||
command: ./downloadpackages.sh
|
||||
|
||||
packages_nginx:
|
||||
archweb_nginx:
|
||||
container_name: artixweb-nginx
|
||||
image: linuxserver/nginx:latest
|
||||
restart: "no"
|
||||
|
@@ -9,24 +9,24 @@ register = template.Library()
|
||||
@register.simple_tag
|
||||
def jquery():
|
||||
version = '3.6.0'
|
||||
filename = 'jquery-%s.min.js' % version
|
||||
filename = f'jquery-{version}.min.js'
|
||||
link = staticfiles_storage.url(filename)
|
||||
return mark_safe('<script type="text/javascript" src="%s"></script>' % link)
|
||||
return mark_safe(f'<script type="text/javascript" src="{link}"></script>')
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def jquery_tablesorter():
|
||||
version = '2.31.0'
|
||||
filename = 'jquery.tablesorter-%s.min.js' % version
|
||||
filename = f'jquery.tablesorter-{version}.min.js'
|
||||
link = staticfiles_storage.url(filename)
|
||||
return format_html('<script type="text/javascript" src="%s"></script>' % link)
|
||||
return format_html('<script type="text/javascript" src="{link}"></script>', link=link)
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def d3js():
|
||||
version = '3.5.0'
|
||||
filename = 'd3-%s.min.js' % version
|
||||
filename = f'd3-{version}.min.js'
|
||||
link = staticfiles_storage.url(filename)
|
||||
return format_html('<script type="text/javascript" src="%s"></script>' % link)
|
||||
return format_html('<script type="text/javascript" src="{link}"></script>', link=link)
|
||||
|
||||
# vim: set ts=4 sw=4 et:
|
||||
|
@@ -8,8 +8,11 @@ register = template.Library()
|
||||
def country_flag(country):
|
||||
if not country:
|
||||
return ''
|
||||
return format_html('<span class="fam-flag fam-flag-%s" title="%s"></span> ' % (
|
||||
str(country.code).lower(), str(country.name)))
|
||||
return format_html(
|
||||
'<span class="fam-flag fam-flag-{country_code}" title="{country_name}"></span> ',
|
||||
country_code=str(country.code).lower(),
|
||||
country_name=str(country.name),
|
||||
)
|
||||
|
||||
|
||||
# vim: set ts=4 sw=4 et:
|
||||
|
@@ -10,7 +10,7 @@ def format_key(key_id):
|
||||
if len(key_id) in (8, 20):
|
||||
return '0x%s' % key_id
|
||||
elif len(key_id) == 40:
|
||||
# normal display format is 5 groups of 4 hex chars seperated by spaces,
|
||||
# normal display format is 5 groups of 4 hex chars separated by spaces,
|
||||
# double space, then 5 more groups of 4 hex chars
|
||||
split = tuple(key_id[i:i + 4] for i in range(0, 40, 4))
|
||||
return '%s\u00a0 %s' % (' '.join(split[0:5]), ' '.join(split[5:10]))
|
||||
@@ -56,8 +56,10 @@ def pgp_key_link(key_id, link_text=None):
|
||||
key_id)
|
||||
if link_text is None:
|
||||
link_text = '0x%s' % key_id[-8:]
|
||||
values = (url, format_key(key_id), link_text)
|
||||
return format_html('<a href="%s" title="PGP key search for %s">%s</a>' % values)
|
||||
return format_html('<a href="{url}" title="PGP key search for {key}">{content}</a>',
|
||||
url=url,
|
||||
key=format_key(key_id),
|
||||
content=link_text)
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
|
@@ -25,5 +25,14 @@
|
||||
"default": false,
|
||||
"protocol": "https"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 9,
|
||||
"model": "mirrors.mirrorprotocol",
|
||||
"fields": {
|
||||
"is_download": false,
|
||||
"default": false,
|
||||
"protocol": "ftp"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@@ -184,12 +184,26 @@ def check_rsync_url(mirror_url, location, timeout):
|
||||
with open(os.devnull, 'w') as devnull:
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("rsync cmd: %s", ' '.join(rsync_cmd))
|
||||
|
||||
start = time.time()
|
||||
proc = subprocess.Popen(rsync_cmd, stdout=devnull, stderr=subprocess.PIPE)
|
||||
_, errdata = proc.communicate()
|
||||
end = time.time()
|
||||
log.duration = end - start
|
||||
if proc.returncode != 0:
|
||||
timeout_expired = False
|
||||
# add an arbitrary 5-second buffer to ensure the process completes and to catch actual rsync timeouts.
|
||||
rsync_subprocess_timeout = timeout + 5
|
||||
try:
|
||||
proc = subprocess.Popen(rsync_cmd, stdout=devnull, stderr=subprocess.PIPE)
|
||||
_, errdata = proc.communicate(timeout=rsync_subprocess_timeout)
|
||||
|
||||
end = time.time()
|
||||
log.duration = end - start
|
||||
except subprocess.TimeoutExpired:
|
||||
timeout_expired = True
|
||||
proc.kill()
|
||||
logger.debug("rsync command timeout error: %s, %s", url, errdata)
|
||||
log.is_success = False
|
||||
log.duration = None
|
||||
log.error = f"rsync subprocess killed after {rsync_subprocess_timeout} seconds"
|
||||
|
||||
if proc.returncode != 0 and not timeout_expired:
|
||||
logger.debug("error: %s, %s", url, errdata)
|
||||
log.is_success = False
|
||||
log.error = errdata.strip().decode('utf-8')
|
||||
@@ -197,7 +211,7 @@ def check_rsync_url(mirror_url, location, timeout):
|
||||
# don't record a duration as it is misleading
|
||||
if proc.returncode in (1, 30, 35):
|
||||
log.duration = None
|
||||
else:
|
||||
elif not timeout_expired:
|
||||
logger.debug("success: %s, %.2f", url, log.duration)
|
||||
if os.path.exists(lastsync_path):
|
||||
with open(lastsync_path, 'r') as lastsync:
|
||||
|
@@ -27,7 +27,7 @@ def test_mirrorurl_get_full_url(mirrorurl):
|
||||
|
||||
def test_mirror_url_clean(mirrorurl):
|
||||
mirrorurl.clean()
|
||||
# TOOD(jelle): this expects HOSTNAME to resolve, maybe mock
|
||||
# TODO(jelle): this expects HOSTNAME to resolve, maybe mock
|
||||
assert mirrorurl.has_ipv4
|
||||
# requires ipv6 on host... mock?
|
||||
# assert mirrorurl.has_ipv6 == True
|
||||
|
@@ -33,7 +33,7 @@ server {
|
||||
try_files "" @proxy;
|
||||
}
|
||||
|
||||
location ~ ^/(packages|groups|opensearch|feeds) {
|
||||
location ~ ^/(packages|groups|opensearch|feeds|mirrors|mirrorlist) {
|
||||
try_files "" @proxy;
|
||||
}
|
||||
|
||||
@@ -65,4 +65,4 @@ server {
|
||||
}
|
||||
|
||||
error_page 500 501 502 503 504 /500.html;
|
||||
}
|
||||
}
|
||||
|
@@ -43,8 +43,8 @@ def pkg_details_link(pkg, link_title=None, honor_flagged=False):
|
||||
link_content = link_title
|
||||
if honor_flagged and pkg.flag_date:
|
||||
link_content = '<span class="flagged">%s</span>' % link_title
|
||||
link = '<a href="%s" title="View package details for %s">%s</a>'
|
||||
return format_html(link % (pkg.get_absolute_url(), pkg.pkgname, link_content))
|
||||
link = '<a href="{link}" title="View package details for {pkgname}">{content}</a>'
|
||||
return format_html(link, link=pkg.get_absolute_url(), pkgname=pkg.pkgname, content=link_content)
|
||||
|
||||
|
||||
# vim: set ts=4 sw=4 et:
|
||||
|
@@ -67,7 +67,7 @@ def test_sort(client, package):
|
||||
def test_packages(client, package):
|
||||
response = client.get('/opensearch/packages/')
|
||||
assert response.status_code == 200
|
||||
assert 'template="example.com/opensearch/packages/"' in response.content.decode()
|
||||
assert 'template="http://example.com/opensearch/packages/"' in response.content.decode()
|
||||
|
||||
|
||||
def test_packages_suggest(client, package):
|
||||
|
@@ -25,7 +25,7 @@ def opensearch(request):
|
||||
current_site = Site.objects.get_current()
|
||||
|
||||
return render(request, 'packages/opensearch.xml',
|
||||
{'domain': current_site.domain},
|
||||
{'domain': f'{request.scheme}://{current_site.domain}'},
|
||||
content_type='application/opensearchdescription+xml')
|
||||
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from operator import attrgetter
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
@@ -31,7 +31,7 @@ def index(request):
|
||||
'news_updates': News.objects.order_by('-postdate', '-id')[:15],
|
||||
'pkg_updates': updates,
|
||||
'staff_groups': StaffGroup.objects.all(),
|
||||
'domain': current_site.domain,
|
||||
'domain': f'{request.scheme}://{current_site.domain}',
|
||||
}
|
||||
return render(request, 'public/index.html', context)
|
||||
|
||||
@@ -99,7 +99,7 @@ def keys(request):
|
||||
user_key_ids = frozenset(user.userprofile.pgp_key[-16:] for user in users
|
||||
if user.userprofile.pgp_key)
|
||||
|
||||
not_expired = Q(expires__gt=datetime.utcnow()) | Q(expires__isnull=True)
|
||||
not_expired = Q(expires__gt=datetime.now(timezone.utc)) | Q(expires__isnull=True)
|
||||
master_keys = MasterKey.objects.select_related('owner', 'revoker',
|
||||
'owner__userprofile', 'revoker__userprofile').filter(
|
||||
revoked__isnull=True)
|
||||
@@ -155,7 +155,7 @@ def keys_json(request):
|
||||
'group': 'master'
|
||||
} for key in master_keys)
|
||||
|
||||
not_expired = Q(expires__gt=datetime.utcnow()) | Q(expires__isnull=True)
|
||||
not_expired = Q(expires__gt=datetime.now(timezone.utc)) | Q(expires__isnull=True)
|
||||
signatures = PGPSignature.objects.filter(not_expired, revoked__isnull=True)
|
||||
edge_list = [{ 'signee': sig.signee, 'signer': sig.signer }
|
||||
for sig in signatures]
|
||||
|
@@ -1,5 +1,5 @@
|
||||
from base64 import b64encode
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import pytest
|
||||
from bencode import bencode
|
||||
@@ -24,7 +24,7 @@ def torrent_data():
|
||||
data = {
|
||||
'comment': 'comment',
|
||||
'created_by': 'Arch Linux',
|
||||
'creation date': int(datetime.utcnow().timestamp()),
|
||||
'creation date': int(datetime.now(timezone.utc).timestamp()),
|
||||
'info': {
|
||||
'name': 'arch.iso',
|
||||
'length': 1,
|
||||
|
@@ -1,19 +1,19 @@
|
||||
-e git+https://github.com/fredj/cssmin.git@master#egg=cssmin
|
||||
Django==5.0.11
|
||||
Django==5.1.10
|
||||
IPy==1.1
|
||||
Markdown==3.3.7
|
||||
bencode.py==4.0.0
|
||||
django-countries==7.6.1
|
||||
django-extensions==3.2.3
|
||||
django-extensions==4.1
|
||||
jsmin==3.0.1
|
||||
pgpdump==1.5
|
||||
parse==1.20.2
|
||||
sqlparse==0.5.0
|
||||
django-csp==3.8
|
||||
django-csp==4.0
|
||||
ptpython==2.0.4
|
||||
feedparser==6.0.11
|
||||
bleach==6.0.0
|
||||
requests==2.32.3
|
||||
requests==2.32.4
|
||||
xtarfile==0.2.1
|
||||
zstandard==0.23.0
|
||||
whitenoise==6.8.2
|
||||
|
@@ -273,4 +273,10 @@ if PROMETHEUS_METRICS:
|
||||
|
||||
INSTALLED_APPS = [*list(INSTALLED_APPS), 'django_prometheus']
|
||||
|
||||
# Assume all URLField will be HTTPS if not specified.
|
||||
# NOTE: this can be removed once we bump Django to 6.x
|
||||
# where `https` becomes the default.
|
||||
FORMS_URLFIELD_ASSUME_HTTPS = True
|
||||
|
||||
|
||||
# vim: set ts=4 sw=4 et:
|
||||
|
@@ -324,6 +324,10 @@ function filter_signoffs() {
|
||||
/* start with all rows, and then remove ones we shouldn't show */
|
||||
var rows = $('#tbody_signoffs').children(),
|
||||
all_rows = rows;
|
||||
/* apply the filters, cheaper ones first */
|
||||
if ($('#id_mine_only').is(':checked')) {
|
||||
rows = rows.filter('.mine');
|
||||
}
|
||||
/* apply arch and repo filters */
|
||||
$('#signoffs_filter .arch_filter').add(
|
||||
'#signoffs_filter .repo_filter').each(function() {
|
||||
@@ -352,6 +356,7 @@ function filter_signoffs() {
|
||||
function filter_signoffs_reset() {
|
||||
$('#signoffs_filter .arch_filter').prop('checked', true);
|
||||
$('#signoffs_filter .repo_filter').prop('checked', true);
|
||||
$('#id_mine_only').prop('checked', false);
|
||||
$('#id_pending').prop('checked', false);
|
||||
filter_signoffs();
|
||||
}
|
||||
|
@@ -145,6 +145,10 @@ tr :nth-child(7) {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhFQAEAPABAOTu/wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFAgABACwAAAAAFQAEAAACDYwfoAvoz9qbZ9FrJC0AOw==);
|
||||
}
|
||||
|
||||
code {
|
||||
background: #334450;
|
||||
}
|
||||
|
||||
.results.results td,
|
||||
.results.results th {
|
||||
border: 1px solid #858585;
|
||||
@@ -158,7 +162,7 @@ tr :nth-child(7) {
|
||||
background-color: #111;
|
||||
}
|
||||
|
||||
.results th {
|
||||
.results th, #pkgsearch {
|
||||
color: #fff;
|
||||
background-color: #0f3147;
|
||||
border: 1px solid #0A6682;
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 7.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 12 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.7 KiB |
@@ -7,7 +7,7 @@
|
||||
<div class="box">
|
||||
|
||||
<h2>Tier 0 Mirror usage information</h2>
|
||||
<p>Arch Linux Tier 0 mirror on <a href="https://repos.archlinux.org">repos.archlinux.org</a> which can be used if to obtain the absolute latest packages. The mirror is protected with a HTTP Basic Auth password unique per Staff member.</p>
|
||||
<p>Arch Linux Tier 0 mirror on <a href="https://repos.archlinux.org">repos.archlinux.org</a> which can be used if to obtain the absolute latest packages. The mirror is protected with an HTTP Basic Auth password unique per Staff member.</p>
|
||||
{% if mirror_url %}
|
||||
<code id="serverinfo">Server = {{ mirror_url }}</code> <button id="copybutton">Copy to clipboard</button>
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
<th>Multilib Version</th>
|
||||
<th>x86_64 Version</th>
|
||||
<th>x86_64 Name</th>
|
||||
<th>x864_ Repo</th>
|
||||
<th>x86_64 Repo</th>
|
||||
<th>Multilib Last Updated</th>
|
||||
<th>x86_64 Last Updated</th>
|
||||
</tr>
|
||||
|
@@ -26,6 +26,8 @@
|
||||
<div><label for="id_repo_{{ repo_name|lower }}" title="Target Repository {{ repo_name }}">[{{ repo_name|lower }}]</label>
|
||||
<input type="checkbox" name="repo_{{ repo_name|lower }}" id="id_repo_{{ repo_name|lower }}" class="repo_filter" value="{{ repo_name|lower }}" checked="checked"/></div>
|
||||
{% endfor %}
|
||||
<div><label for="id_mine_only" title="Show only packages packaged by me">Only Mine</label>
|
||||
<input type="checkbox" name="mine_only" id="id_mine_only" value="mine_only"/></div>
|
||||
<div><label for="id_pending" title="Packages with not enough signoffs">Only Pending Approval</label>
|
||||
<input type="checkbox" name="pending" id="id_pending" value="pending"/></div>
|
||||
<div><label> </label><input title="Reset search criteria" type="button" id="criteria_reset" value="Reset"/></div>
|
||||
@@ -50,7 +52,8 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody_signoffs">
|
||||
{% for group in signoff_groups %}<tr class="{{ group.arch.name }} {{ group.target_repo|lower }}">
|
||||
{% for group in signoff_groups %}
|
||||
<tr class="{% if user == group.packager %} mine{% endif %} {{ group.arch.name }} {{ group.target_repo|lower }}">
|
||||
<td>{% pkg_details_link group.package %} {{ group.version }}</td>
|
||||
<td>{{ group.arch.name }}</td>
|
||||
<td>{{ group.target_repo }}</td>
|
||||
|
@@ -49,6 +49,11 @@
|
||||
<td>{% if prof.website %}<a itemprop="url" href="{{ prof.website }}"
|
||||
title="Visit the website for {{ dev.get_full_name }}">
|
||||
{{ prof.website }}</a>{% endif %}</td>
|
||||
</tr><tr>
|
||||
<th>Social:</th>
|
||||
<td>{% if prof.social %}<a itemprop="url" href="{{ prof.social }}"
|
||||
title="Visit social account for {{ dev.get_full_name }}" rel="me">
|
||||
{{ prof.social }}</a>{% endif %}</td>
|
||||
</tr><tr>
|
||||
<th>Occupation:</th>
|
||||
<td>{{ prof.occupation }}</td>
|
||||
|
@@ -53,37 +53,10 @@
|
||||
<img src="{% static "nitrokey_logo.png" %}"
|
||||
class="sponsor-btn-nitrokey" title="" alt="Nitrokey logo"/></a>
|
||||
|
||||
<p>We would also like to thank <a href="https://www.privateinternetaccess.com/"
|
||||
title="Private Internet Access">Private Internet Access</a> for sponsoring
|
||||
dedicated servers across the globe. Private Internet Access is the leading
|
||||
VPN Service provider specializing in secure, encrypted VPN tunnels which
|
||||
create several layers of privacy and security providing users safety on the
|
||||
internet.</p>
|
||||
|
||||
<a href="https://www.privateinternetaccess.com/" title="Private Internet Access">
|
||||
<img src="{% static "pia_logo.png" %}"
|
||||
class="sponsor-btn-pia" title="" alt="Private Internet Access logo"/></a>
|
||||
|
||||
<p>We would also like to thank <a href="https://www.shells.com/"
|
||||
title="Shells">Shells.com</a> for their monetary donation.
|
||||
Shells provides you with a 1-click, powerful virtual desktop environment,
|
||||
driven by a cloud computer, without leaving your browser! It's your
|
||||
personal workspace in the cloud.</p>
|
||||
|
||||
<a href="https://www.shells.com/" title="Shells">
|
||||
<img src="{% static "shells_logo.png" %}"
|
||||
title="" alt="Shells logo"/></a>
|
||||
|
||||
<p>We would also like to thank <a href="https://uptimerobot.com/"
|
||||
title="UptimeRobot">UptimeRobot</a> for providing their monitoring service to us.
|
||||
UptimeRobot is a leading uptime monitoring service.</p>
|
||||
|
||||
<a href="https://uptimerobot.com/" title="UptimeRobot">
|
||||
<img src="{% static "uptimerobot_logo.png" %}"
|
||||
title="" alt="UptimeRobot logo"/></a>
|
||||
|
||||
<h3>Past donors</h3>
|
||||
|
||||
<p><a href="http://www.dotcom-monitor.com/" title="Dotcom-Monitor">Dotcom-Monitor</a> & <a href="https://www.loadview-testing.com/" title="LoadView">LoadView</a></p>
|
||||
|
||||
<div id="donor-list">
|
||||
<ul>
|
||||
{% for donor in donors %}
|
||||
|
@@ -77,13 +77,6 @@
|
||||
title="Arch Linux Netboot">Arch Linux Netboot</a></li>
|
||||
</ul>
|
||||
|
||||
<h3>Vagrant images</h3>
|
||||
|
||||
<p>Vagrant images for libvirt and virtualbox are available on the <a href="https://app.vagrantup.com/archlinux/boxes/archlinux">Vagrant Cloud</a>. You can bootstrap the image with the following commands:</p>
|
||||
<code>vagrant init archlinux/archlinux</code>
|
||||
<br/>
|
||||
<code>vagrant up</code>
|
||||
|
||||
<h3>Docker image</h3>
|
||||
|
||||
<p>The official Docker image is available on <a href="https://hub.docker.com/_/archlinux/">Docker Hub</a>. You can run the image with the following command:</p>
|
||||
@@ -93,6 +86,14 @@
|
||||
|
||||
<p>Official virtual machine images are available for download on our <a href="https://gitlab.archlinux.org/archlinux/arch-boxes/-/packages">GitLab instance</a>, more information is available in the <a href="https://gitlab.archlinux.org/archlinux/arch-boxes/">README</a>.</p>
|
||||
|
||||
<h3>WSL images</h3>
|
||||
|
||||
<p>The official WSL image can be installed with the following command (in a PowerShell prompt from a Windows system with WSL 2 installed):</p>
|
||||
<code>wsl --install archlinux</code>
|
||||
|
||||
<p>It is also available for download on <a href="https://geo.mirror.pkgbuild.com/wsl/latest">mirrors</a>.</p>
|
||||
<p>More information available in the <a href="https://wiki.archlinux.org/title/Install_Arch_Linux_on_WSL">Wiki</a>.</p>
|
||||
|
||||
<h3 id="http-downloads">HTTP Direct Downloads</h3>
|
||||
|
||||
<p>In addition to the BitTorrent links above, install images can also be
|
||||
@@ -132,15 +133,15 @@
|
||||
<pre><code>$ b2sum -c b2sums.txt</code></pre>
|
||||
|
||||
To verify the PGP signature using Sequoia, first download the release signing key from WKD:
|
||||
<pre><code>$ sq network wkd fetch {{ release.wkd_email }} -o release-key.pgp</code></pre>
|
||||
<pre><code>$ sq network wkd search {{ release.wkd_email }} --output release-key.pgp</code></pre>
|
||||
|
||||
With this signing key, verify the signature:
|
||||
<pre><code>$ sq verify --signer-file release-key.pgp --detached archlinux-{{ release.version }}-x86_64.iso.sig archlinux-{{ release.version }}-x86_64.iso</code></pre>
|
||||
<pre><code>$ sq verify --signer-file release-key.pgp --signature-file archlinux-{{ release.version }}-x86_64.iso.sig archlinux-{{ release.version }}-x86_64.iso</code></pre>
|
||||
|
||||
Alternatively, using GnuPG, download the signing key from WKD:
|
||||
<pre><code>$ gpg --auto-key-locate clear,wkd -v --locate-external-key {{ release.wkd_email }}</code></pre>
|
||||
Verify the signature:
|
||||
<pre><code>$ gpg --keyserver-options auto-key-retrieve --verify archlinux-{{ release.version }}-x86_64.iso.sig archlinux-{{ release.version }}-x86_64.iso</code></pre>
|
||||
<pre><code>$ gpg --verify archlinux-{{ release.version }}-x86_64.iso.sig archlinux-{{ release.version }}-x86_64.iso</code></pre>
|
||||
|
||||
{% cache 600 download-mirrors %}
|
||||
<div id="download-mirrors">
|
||||
|
@@ -133,8 +133,6 @@
|
||||
<h4>Support</h4>
|
||||
<ul>
|
||||
<li><a href="{% url 'page-donate' %}" title="Help support Arch Linux">Donate</a></li>
|
||||
<li><a href="https://www.unixstickers.com/tag/archlinux" title="Arch
|
||||
Linux stickers, t-shirts, hoodies, mugs, posters and pins">Products via Unixstickers</a></li>
|
||||
<li><a href="https://www.freewear.org/?page=list_items&org=Archlinux"
|
||||
title="T-shirts">T-shirts via Freewear</a></li>
|
||||
<li><a href="https://www.hellotux.com/arch"
|
||||
@@ -155,6 +153,7 @@
|
||||
<ul>
|
||||
<li><a href="https://wiki.archlinux.org/title/Getting_involved"
|
||||
title="Getting involved">Getting involved</a></li>
|
||||
<li><a href="https://devblog.archlinux.page" title="Dev Blog">Dev Blog</a></li>
|
||||
<li><a href="https://gitlab.archlinux.org/archlinux/"
|
||||
title="Official Arch projects (git)">Projects in Git</a></li>
|
||||
<li><a href="https://wiki.archlinux.org/title/DeveloperWiki"
|
||||
@@ -202,20 +201,10 @@
|
||||
title="" alt="Hetzner logo"/>
|
||||
</a>
|
||||
|
||||
<a href="https://www.privateinternetaccess.com/" title="Private Internet Access">
|
||||
<img src="{% static "pia_logo.png" %}"
|
||||
 title="" alt="Private Internet Access logo"/>
|
||||
</a>
|
||||
|
||||
<a href="https://icons8.com/" title="Icons8">
|
||||
<img src="{% static "icons8_logo.png" %}"
|
||||
title="" alt="Icons8 logo"/>
|
||||
</a>
|
||||
|
||||
<a href="https://www.shells.com" title="Shells.com">
|
||||
<img src="{% static "shells_logo.png" %}"
|
||||
title="" alt="Shells logo"/>
|
||||
</a>
|
||||
</div>
|
||||
{% endcache %}
|
||||
{% endblock %}
|
||||
|
@@ -2,6 +2,8 @@
|
||||
{% load static %}
|
||||
{% load package_extras %}
|
||||
{% load todolists %}
|
||||
{% load tz %}
|
||||
{% load humanize %}
|
||||
|
||||
{% block title %}Arch Linux - Todo: {{ list.name }}{% endblock %}
|
||||
|
||||
@@ -103,7 +105,15 @@
|
||||
<span class="{{ pkg.status_css_class }}">{{ pkg.get_status_display }}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ pkg.user|default:"" }}</td>
|
||||
<td>
|
||||
{% if pkg.user %}
|
||||
{% if user.is_authenticated %}
|
||||
{{ pkg.user }} <span title="{{ pkg.last_modified|timezone:user.userprofile.time_zone|date:"Y-m-d H:i T" }}">({{ pkg.last_modified|naturaltime }})</span>
|
||||
{% else %}
|
||||
{{ pkg.user }} <span title="{{ pkg.last_modified|date:"Y-m-d H:i T" }}">({{ pkg.last_modified|naturaltime }})</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@@ -13,8 +13,9 @@ def todopkg_details_link(todopkg):
|
||||
pkg = todopkg.pkg
|
||||
if not pkg:
|
||||
return todopkg.pkgname
|
||||
link = '<a href="%s" title="View package details for %s">%s</a>'
|
||||
link = '<a href={url}s" title="View package details for {pkgname}">{pkgname}</a>'
|
||||
url = pkg_absolute_url(todopkg.repo, todopkg.arch, pkg.pkgname)
|
||||
return format_html(link % (url, pkg.pkgname, pkg.pkgname))
|
||||
return format_html(link, url=url, pkgname=pkg.pkgname)
|
||||
|
||||
|
||||
# vim: set ts=4 sw=4 et:
|
||||
|
Reference in New Issue
Block a user