Skip to content

Commit

Permalink
Fixed merge issue with requirements. The git link appears broken, usi…
Browse files Browse the repository at this point in the history
…ng pypi instead
  • Loading branch information
Torxed committed Feb 17, 2023
2 parents ad3b182 + 2ff4375 commit 642b77d
Show file tree
Hide file tree
Showing 63 changed files with 1,561 additions and 770 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ collected_static/
testing/
env/
htmlcov
*.tar.gz

.mypy_cache/

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,6 @@ gpg --sender "User Name <[email protected]>" --detach-sign sitestatic/netboot/*.

# Production Installation

Arch Linux has an Ansible role for Archweb in their [infrastructure repo](https://git.archlinux.org/infrastructure.git/).
Arch Linux has an Ansible role for Archweb in their [infrastructure repo](https://gitlab.archlinux.org/archlinux/infrastructure).

vim: set syntax=markdown et:
7 changes: 7 additions & 0 deletions devel/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.contrib.sites.models import Site
from django.core.mail import send_mail
from django.template import loader
from django.forms.widgets import EmailInput, NumberInput, URLInput

from .models import UserProfile

Expand Down Expand Up @@ -41,6 +42,12 @@ def clean_pgp_key(self):
class Meta:
model = UserProfile
exclude = ('allowed_repos', 'user', 'repos_auth_token')
widgets = {
'yob': NumberInput(attrs={'min': 1950, 'max': 2500}),
'public_email': EmailInput(), # HACK: field definition should be fixed
'website': URLInput(),
'website_rss': URLInput(),
}


class NewUserForm(forms.ModelForm):
Expand Down
7 changes: 3 additions & 4 deletions devel/management/commands/pgp_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
"""

from collections import OrderedDict
from datetime import datetime
from datetime import datetime, timezone
import logging
from pytz import utc
import subprocess

from django.core.management.base import BaseCommand, CommandError
Expand Down Expand Up @@ -50,14 +49,14 @@ def get_date(epoch_string):
'''Convert a epoch string into a python 'date' object (not datetime).'''
if not epoch_string:
return None
return datetime.utcfromtimestamp(int(epoch_string)).date()
return datetime.fromtimestamp(int(epoch_string), tz=timezone.utc).date()


def get_datetime(epoch_string):
'''Convert a epoch string into a python 'datetime' object.'''
if not epoch_string:
return None
return datetime.utcfromtimestamp(int(epoch_string)).replace(tzinfo=utc)
return datetime.fromtimestamp(int(epoch_string), tz=timezone.utc)


def call_gpg(keyring, *args):
Expand Down
6 changes: 2 additions & 4 deletions devel/management/commands/reporead.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
import re
import xtarfile as tarfile
import logging
from datetime import datetime
from pytz import utc
from datetime import datetime, timezone

from django.core.management.base import BaseCommand, CommandError
from django.db import connections, router, transaction
Expand Down Expand Up @@ -120,8 +119,7 @@ def populate(self, values):
self.ver, self.rel, self.epoch = parse_version(v[0])
elif k == 'builddate':
try:
builddate = datetime.utcfromtimestamp(int(v[0]))
self.builddate = builddate.replace(tzinfo=utc)
self.builddate = datetime.fromtimestamp(int(v[0]), tz=timezone.utc)
except ValueError:
logger.warning(
'Package %s had unparsable build date %s',
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions devel/models.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
import pytz
import zoneinfo

from django.urls import reverse
from django.db import models
from django.db.models.signals import pre_save, post_save
from django.contrib.auth.models import User, Group
from django_countries.fields import CountryField
from django.core.validators import MinValueValidator, MaxValueValidator

from .fields import PGPKeyField
from main.utils import make_choice, set_created_field
Expand All @@ -22,7 +23,7 @@ class UserProfile(models.Model):
help_text="When enabled, send user 'flag out-of-date' notifications")
time_zone = models.CharField(
max_length=100,
choices=make_choice(pytz.common_timezones),
choices=make_choice(sorted(zoneinfo.available_timezones())), # sort as available_timezones output varies
default="UTC",
help_text="Used for developer clock page")
alias = models.CharField(
Expand All @@ -39,7 +40,8 @@ class UserProfile(models.Model):
website = models.CharField(max_length=200, null=True, blank=True)
website_rss = models.CharField(max_length=200, null=True, blank=True,
help_text='RSS Feed of your website for planet.archlinux.org')
yob = models.IntegerField("Year of birth", null=True, blank=True)
yob = models.IntegerField("Year of birth", null=True, blank=True,
validators=[MinValueValidator(1950), MaxValueValidator(2500)])
country = CountryField(blank=True)
location = models.CharField(max_length=50, null=True, blank=True)
languages = models.CharField(max_length=50, null=True, blank=True)
Expand Down
20 changes: 3 additions & 17 deletions devel/reports.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from collections import defaultdict
from datetime import timedelta
from datetime import timedelta, timezone

import pytz
from django.db.models import F
from django.template.defaultfilters import filesizeformat
from django.db import connection
Expand Down Expand Up @@ -171,7 +170,7 @@ def signature_time(packages):
'arch', 'repo', 'packager').filter(signature_bytes__isnull=False)
for package in packages:
sig = package.signature
sig_date = sig.creation_time.replace(tzinfo=pytz.utc)
sig_date = sig.creation_time.replace(tzinfo=timezone.utc)
package.sig_date = sig_date.date()
if sig_date > package.build_date + cutoff:
filtered.append(package)
Expand Down Expand Up @@ -244,11 +243,6 @@ def orphan_dependencies(packages):
return pkgs


def unused_python2_packages(packages):
required = Depend.objects.all().values('name')
return packages.filter(pkgname__startswith='python2').exclude(pkgname__in=required)


REPORT_OLD = DeveloperReport(
'old', 'Old', 'Packages last built more than two years ago', old)

Expand Down Expand Up @@ -328,13 +322,6 @@ def unused_python2_packages(packages):
['Orphan dependencies'],
['orphandeps'])

UNUSED_PYTHON2_PACKAGES = DeveloperReport(
'unused-python2',
'Unused Python2 packages',
'python2 modules which are not used required by any other packages in the repository',
unused_python2_packages,
personal=False)


def available_reports():
return (REPORT_OLD,
Expand All @@ -349,5 +336,4 @@ def available_reports():
REPORT_SIG_TIME,
NON_EXISTING_DEPENDENCIES,
REBUILDERD_PACKAGES,
ORPHAN_REBUILDERD_PACKAGES,
UNUSED_PYTHON2_PACKAGES)
ORPHAN_REBUILDERD_PACKAGES)
3 changes: 1 addition & 2 deletions devel/tests/test_reporead.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import tarfile
from unittest.mock import patch
from datetime import datetime
from datetime import datetime, timezone


from django.core.management import call_command
from django.core.management.base import CommandError
from django.test import TransactionTestCase
from django.utils import timezone


from main.models import Arch, Package, Repo
Expand Down
7 changes: 3 additions & 4 deletions feeds.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from datetime import datetime, time
from pytz import utc
from datetime import datetime, timezone, time

from django.core.exceptions import ObjectDoesNotExist
from django.contrib.admin.models import ADDITION, DELETION
Expand Down Expand Up @@ -363,7 +362,7 @@ def item_description(self, item):
return item.info_html()

def item_pubdate(self, item):
return datetime.combine(item.release_date, time()).replace(tzinfo=utc)
return datetime.combine(item.release_date, time()).replace(tzinfo=timezone.utc)

def item_updateddate(self, item):
return item.last_modified
Expand Down Expand Up @@ -416,7 +415,7 @@ def item_description(self, item):
return item.summary

def item_pubdate(self, item):
return datetime.combine(item.publishdate, time()).replace(tzinfo=utc)
return datetime.combine(item.publishdate, time()).replace(tzinfo=timezone.utc)

def item_updateddate(self, item):
return item.publishdate
Expand Down
5 changes: 5 additions & 0 deletions main/context_processors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.conf import settings


def mastodon_link(request):
return {'MASTODON_LINK': getattr(settings, "MASTODON_LINK", "")}
5 changes: 2 additions & 3 deletions main/log.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Derived from Django snippets: http://djangosnippets.org/snippets/2242/
from collections import OrderedDict
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from hashlib import md5
import traceback
from pytz import utc


class LimitedSizeDict(OrderedDict):
Expand Down Expand Up @@ -60,7 +59,7 @@ def filter(self, record):
duplicate = (cache.get(cache_key) == 1)
cache.set(cache_key, 1, self.rate)
else:
now = datetime.utcnow().replace(tzinfo=utc)
now = datetime.now(timezone.utc)
min_date = now - timedelta(seconds=self.rate)
duplicate = (key in self.errors and self.errors[key] >= min_date)
self.errors[key] = now
Expand Down
5 changes: 2 additions & 3 deletions main/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from itertools import groupby
from pgpdump import BinaryData
from pytz import utc
from datetime import datetime
from datetime import datetime, timezone

from django.db import models
from django.db.models import Q
Expand Down Expand Up @@ -141,7 +140,7 @@ def updated_mins_ago(self):
# package was actually pushed to any repo. We don't have that
# easily available without adding more fields and scripts.
# See: https://github.com/archlinux/archweb/pull/323
now = datetime.utcnow().replace(tzinfo=utc)
now = datetime.now(timezone.utc)
return int((now - self.last_update).total_seconds()) // 60

@property
Expand Down
130 changes: 63 additions & 67 deletions main/tests/test_donor_import.py
Original file line number Diff line number Diff line change
@@ -1,80 +1,76 @@
# -*- coding: utf-8 -*-

import sys
from email.header import Header
from email.message import Message
from io import StringIO
from tempfile import mkdtemp

from django.test import TransactionTestCase
import pytest

from django.core.management import call_command
from django.core.management.base import CommandError

from main.models import Donor
from main.management.commands.donor_import import Command


class DonorImportTest(TransactionTestCase):

def setUp(self):
self.command = Command()

def test_parse_subject(self):
self.assertIsNone(self.command.parse_subject('garbage'))

# Valid
valid = u'Receipt [$25.00] By: John Doe [[email protected]]'
output = self.command.parse_subject(valid)
self.assertEqual(output, u'John Doe')

def test_parse_name(self):
self.assertEqual(self.command.sanitize_name(u'1244'), u'')
self.assertEqual(self.command.sanitize_name(u'John Doe'), u'John Doe')
self.assertEqual(self.command.sanitize_name(u' John Doe '), u'John Doe')
self.assertEqual(self.command.sanitize_name(u'John Doe 23'), u'John Doe')

def test_decode_subject(self):
text = u'メイル'
subject = Header(text, 'utf-8')
self.assertEqual(self.command.decode_subject(subject), text)

def test_invalid_args(self):
stdin = sys.stdin
with self.assertRaises(CommandError) as e:
sys.stdin = StringIO('')
call_command('donor_import')
self.assertIn('Failed to read from STDIN', str(e.exception))
sys.stdin = stdin

def test_invalid_path(self):
with self.assertRaises(CommandError) as e:
call_command('donor_import', '/tmp/non-existant')
self.assertIn('argument input: can\'t open', str(e.exception))

def test_import(self):
tmpmail = mkdtemp('archweb') + "/mail"

msg = Message()
msg['subject'] = 'John Doe'
msg['to'] = 'John Doe <[email protected]>'
with open(tmpmail, 'wb') as fp:
fp.write(msg.as_bytes())

# Invalid
with self.assertRaises(SystemExit):
call_command('donor_import', tmpmail)
self.assertEqual(len(Donor.objects.all()), 0)

# Valid
msg = Message()
msg['subject'] = 'Receipt [$25.00] By: David Doe [[email protected]]'
msg['to'] = 'John Doe <[email protected]>'
with open(tmpmail, 'wb') as fp:
fp.write(msg.as_bytes())

call_command('donor_import', tmpmail)
self.assertEqual(len(Donor.objects.all()), 1)

# Re-running should result in no new donor
call_command('donor_import', tmpmail)
self.assertEqual(len(Donor.objects.all()), 1)
command = Command()


def test_parse_subject():
assert command.parse_subject('garbage') is None

# Valid
valid = 'Receipt [$25.00] By: John Doe [[email protected]]'
output = command.parse_subject(valid)
assert output == 'John Doe'


def test_parse_name():
assert command.sanitize_name('1244') == ''
assert command.sanitize_name('John Doe') == 'John Doe'
assert command.sanitize_name(' John Doe ') == 'John Doe'
assert command.sanitize_name('John Doe 23') == 'John Doe'


def test_decode_subject():
text = u'メイル'
subject = Header(text, 'utf-8')
assert command.decode_subject(subject) == text


def test_invalid_args(monkeypatch):
monkeypatch.setattr('sys.stdin', StringIO(''))
with pytest.raises(CommandError) as e:
call_command('donor_import')
assert 'Failed to read from STDIN' in str(e.value)


def test_invalid_path():
with pytest.raises(CommandError) as e:
call_command('donor_import', '/tmp/non-existant')
assert 'argument input: can\'t open' in str(e.value)


def test_maildir(db, monkeypatch):
msg = Message()
msg['subject'] = 'John Doe'
msg['to'] = 'John Doe <[email protected]>'

# Invalid
monkeypatch.setattr('sys.stdin', StringIO(msg.as_string()))
with pytest.raises(SystemExit):
call_command('donor_import')
assert len(Donor.objects.all()) == 0

# # Valid
msg = Message()
msg['subject'] = 'Receipt [$25.00] By: David Doe [[email protected]]'
msg['to'] = 'John Doe <[email protected]>'
monkeypatch.setattr('sys.stdin', StringIO(msg.as_string()))
call_command('donor_import')
assert len(Donor.objects.all()) == 1

# # Re-running should result in no new donor
monkeypatch.setattr('sys.stdin', StringIO(msg.as_string()))
call_command('donor_import')
assert len(Donor.objects.all()) == 1
Loading

0 comments on commit 642b77d

Please sign in to comment.