Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automate mirror submission #448

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ local_settings.py
archweb.db
archweb.db-*
database.db
/*.tar.gz
Torxed marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please drop this, this shouldn't be required anymore. It's also unrelated to the other changes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure it's "unrelated", but the fact remains that whenever you work from the project folder and follow some instructions about downloading a database or something similar you run the risk of pushing it globally.

If the project does not need .tar.gz files to be built or executed, there's really no risk of adding it to the ignore list. And I thought while I'm at it, I'll add it.

tags
collected_static/
testing/
Expand Down
1 change: 1 addition & 0 deletions mirrors/urls_mirrorlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

urlpatterns = [
path('', views.generate_mirrorlist, name='mirrorlist'),
path('submit/', views.submit_mirror, name='mirrorsubmit'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not linked anywhere on archlinux.org, maybe we should add a link with some text on https://archlinux.org/mirrors.

re_path(r'^all/$', views.find_mirrors, {'countries': ['all']}),
re_path(r'^all/(?P<protocol>[A-z]+)/$', views.find_mirrors_simple, name='mirrorlist_simple')
]
Expand Down
120 changes: 118 additions & 2 deletions mirrors/views/mirrorlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,104 @@

from django import forms
from django.db.models import Q
from django.forms.widgets import SelectMultiple, CheckboxSelectMultiple
from django.forms.widgets import (
Select,
SelectMultiple,
CheckboxSelectMultiple,
TextInput,
EmailInput
)
from django.shortcuts import get_object_or_404, redirect, render
from django.views.decorators.csrf import csrf_exempt
from django_countries import countries

from ..models import MirrorUrl, MirrorProtocol
from ..models import Mirror, MirrorUrl, MirrorProtocol
from ..utils import get_mirror_statuses

import random


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unneeded change

# This is populated later, and re-populated every refresh
# This was the only way to get 3 different examples without
# changing the models.py
url_examples = []


class MirrorRequestForm(forms.ModelForm):
upstream = forms.ModelChoiceField(
queryset=Mirror.objects.filter(tier__gte=0, tier__lte=1),
required=False)

class Meta:
model = Mirror
fields = ('name', 'tier', 'upstream', 'admin_email', 'alternate_email',
'isos', 'rsync_user', 'rsync_password', 'notes')

def __init__(self, *args, **kwargs):
super(MirrorRequestForm, self).__init__(*args, **kwargs)
fields = self.fields
fields['name'].widget.attrs.update({'placeholder': 'Ex: mirror.argentina.co'})
fields['rsync_user'].widget.attrs.update({'placeholder': 'Optional'})
fields['rsync_password'].widget.attrs.update({'placeholder': 'Optional'})
fields['notes'].widget.attrs.update({'placeholder': 'Ex: Hosted by ISP GreatISO.bg'})

def as_div(self):
"Returns this form rendered as HTML <divs>s."
return self._html_output(
normal_row=u'<div%(html_class_attr)s>%(label)s %(field)s%(help_text)s</div>',
error_row=u'%s',
row_ender='</div>',
help_text_html=u' <span class="helptext">%s</span>',
errors_on_separate_row=True)


class MirrorUrlForm(forms.ModelForm):
class Meta:
model = MirrorUrl
fields = ('url', 'country', 'bandwidth', 'active')

def __init__(self, *args, **kwargs):
global url_examples

super(MirrorUrlForm, self).__init__(*args, **kwargs)
fields = self.fields

if len(url_examples) == 0:
url_examples = [
'Ex: http://mirror.argentina.co/archlinux',
'Ex: https://mirror.argentina.co/archlinux',
'Ex: rsync://mirror.argentina.co/archlinux'
]

fields['url'].widget.attrs.update({'placeholder': url_examples.pop()})

def clean_url(self):
# is this a valid-looking URL?
url_parts = urlparse(self.cleaned_data["url"])
if not url_parts.scheme:
raise forms.ValidationError("No URL scheme (protocol) provided.")
if not url_parts.netloc:
raise forms.ValidationError("No URL host provided.")
if url_parts.params or url_parts.query or url_parts.fragment:
raise forms.ValidationError(
"URL parameters, query, and fragment elements are not supported.")
# ensure we always save the URL with a trailing slash
path = url_parts.path
if not path.endswith('/'):
path += '/'
url = urlunsplit((url_parts.scheme, url_parts.netloc, path, '', ''))
return url

def as_div(self):
"Returns this form rendered as HTML <divs>s."
return self._html_output(
normal_row=u'<div%(html_class_attr)s>%(label)s %(field)s%(help_text)s</div>',
error_row=u'%s',
row_ender='</div>',
help_text_html=u' <span class="helptext">%s</span>',
errors_on_separate_row=True)


class MirrorlistForm(forms.Form):
country = forms.MultipleChoiceField(required=False, widget=SelectMultiple(attrs={'size': '12'}))
protocol = forms.MultipleChoiceField(required=False, widget=CheckboxSelectMultiple)
Expand Down Expand Up @@ -127,4 +214,33 @@ def find_mirrors_simple(request, protocol):
proto = get_object_or_404(MirrorProtocol, protocol=protocol)
return find_mirrors(request, protocols=[proto])

def submit_mirror(request):
# if request.method == 'POST' or len(request.GET) > 0:
# data = request.POST if request.method == 'POST' else request.GET
# form1 = MirrorUrlForm(data=data)
# if form.is_valid():
# countries = form.cleaned_data['country']
# protocols = form.cleaned_data['protocol']
# use_status = form.cleaned_data['use_mirror_status']
# ipv4 = '4' in form.cleaned_data['ip_version']
# ipv6 = '6' in form.cleaned_data['ip_version']
# return find_mirrors(request, countries, protocols,
# use_status, ipv4, ipv6)
# else:
form1 = MirrorRequestForm()
url1 = MirrorUrlForm()
url2 = MirrorUrlForm()
url3 = MirrorUrlForm()

return render(
request,
'mirrors/mirror_submit.html',
{
'submission_form1': form1,
'url1': url1,
'url2': url2,
'url3': url3
}
)

# vim: set ts=4 sw=4 et:
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-e git+git://github.com/fredj/cssmin.git@master#egg=cssmin
cssmin==0.2.0
Torxed marked this conversation as resolved.
Show resolved Hide resolved
Django==4.0.1
IPy==1.1
Markdown==3.3.4
Expand Down
34 changes: 34 additions & 0 deletions templates/mirrors/mirror_submit.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{% extends "base.html" %}
{% load package_extras %}
{% block title %}Arch Linux - Pacman Mirrorlist Generator{% endblock %}

{% block content %}
<div id="mirrorlist-gen" class="box">

<h2>Mirror Request</h2>

<p>This page is meant as a replacement of the old way of registring as a Tier 1 or Tier 2 mirror. Previously this was done through <a href="https://bugs.archlinux.org/index.php?string=&project=1&search_name=&type%5B%5D=&sev%5B%5D=&pri%5B%5D=&due%5B%5D=&reported%5B%5D=&cat%5B%5D=43&status%5B%5D=open&percent%5B%5D=&opened=&dev=&closed=&duedatefrom=&duedateto=&changedfrom=&changedto=&openedfrom=&openedto=&closedfrom=&closedto=&do=index">https://bugs.archlinux.org</a> and would require manual intervention from the mirror maintainer(s). This process is now semi-automated and various checks against your mirror will be performed when submitting via the below form.</p>
Torxed marked this conversation as resolved.
Show resolved Hide resolved

<h3>Available mirrors</h3>

<p>Below are direct links to the two different tiers you will need to be acquainted with.<p>

<ul>
<li><a href="/mirrors/tier/1/">Tier 1 mirrors</a></li>
<li><a href="/mirrors/tier/2/">Tier 2 mirrors</a></li>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally this uses the url template tag

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, I'll learn how those work and see if I can get it working.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how to work around the fact that the tier url's use re_path(r'^tier/(?P<tier>\d+)/$', mirrors, name='mirror-list-tier'), with one common name (I assume that's how those links work after reading up).

</ul>

<h3>Mirror information</h3>

<p>Before you can submit a <b>Tier 1</b> request the mirror in question must first be a registered <b>Tier 2</b> for a certain amount of time with proven reliablity. Once the submitted information is verified the mirror will be visible under the appropriate tier list above. This process usually takes 5 minutes.</p>
Torxed marked this conversation as resolved.
Show resolved Hide resolved

<form id="list-generator" method="get">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A Form should never be a GET, but always a POST and should have:

    <form method="post">{% csrf_token %}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And just for reference, I took the method from this form:

{{ submission_form1.as_div }}
{{ url1.as_div }}
{{ url2.as_div }}
{{ url3.as_div }}
<p><label></label> <input type="submit" value="Submit Request" /></p>
</form>
</div>
{% endblock %}