summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--releng/migrations/0007_auto__add_field_release_md5__add_field_release_sha1.py122
-rw-r--r--releng/models.py11
-rw-r--r--settings.py6
-rw-r--r--templates/public/download.html27
-rw-r--r--templates/releng/release_detail.html7
-rw-r--r--templates/releng/release_list.html2
6 files changed, 158 insertions, 17 deletions
diff --git a/releng/migrations/0007_auto__add_field_release_md5__add_field_release_sha1.py b/releng/migrations/0007_auto__add_field_release_md5__add_field_release_sha1.py
new file mode 100644
index 00000000..f76be3d7
--- /dev/null
+++ b/releng/migrations/0007_auto__add_field_release_md5__add_field_release_sha1.py
@@ -0,0 +1,122 @@
+# -*- coding: utf-8 -*-
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ db.add_column('releng_release', 'md5_sum',
+ self.gf('django.db.models.fields.CharField')(default='', max_length=32, blank=True),
+ keep_default=False)
+ db.add_column('releng_release', 'sha1_sum',
+ self.gf('django.db.models.fields.CharField')(default='', max_length=40, blank=True),
+ keep_default=False)
+ db.alter_column('releng_release', 'torrent_infohash', self.gf('django.db.models.fields.CharField')(max_length=40))
+
+ def backwards(self, orm):
+ db.delete_column('releng_release', 'md5_sum')
+ db.delete_column('releng_release', 'sha1_sum')
+ db.alter_column('releng_release', 'torrent_infohash', self.gf('django.db.models.fields.CharField')(max_length=64))
+
+ models = {
+ 'releng.architecture': {
+ 'Meta': {'object_name': 'Architecture'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+ },
+ 'releng.bootloader': {
+ 'Meta': {'object_name': 'Bootloader'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+ },
+ 'releng.boottype': {
+ 'Meta': {'object_name': 'BootType'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+ },
+ 'releng.clockchoice': {
+ 'Meta': {'object_name': 'ClockChoice'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+ },
+ 'releng.filesystem': {
+ 'Meta': {'object_name': 'Filesystem'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+ },
+ 'releng.hardwaretype': {
+ 'Meta': {'object_name': 'HardwareType'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+ },
+ 'releng.installtype': {
+ 'Meta': {'object_name': 'InstallType'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+ },
+ 'releng.iso': {
+ 'Meta': {'object_name': 'Iso'},
+ 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'created': ('django.db.models.fields.DateTimeField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'removed': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'})
+ },
+ 'releng.isotype': {
+ 'Meta': {'object_name': 'IsoType'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+ },
+ 'releng.module': {
+ 'Meta': {'object_name': 'Module'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+ },
+ 'releng.release': {
+ 'Meta': {'ordering': "('-release_date', '-version')", 'object_name': 'Release'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'created': ('django.db.models.fields.DateTimeField', [], {}),
+ 'file_size': ('main.fields.PositiveBigIntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'info': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'kernel_version': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
+ 'md5_sum': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
+ 'release_date': ('django.db.models.fields.DateField', [], {'db_index': 'True'}),
+ 'sha1_sum': ('django.db.models.fields.CharField', [], {'max_length': '40', 'blank': 'True'}),
+ 'torrent_data': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'torrent_infohash': ('django.db.models.fields.CharField', [], {'max_length': '40', 'blank': 'True'}),
+ 'version': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '50'})
+ },
+ 'releng.source': {
+ 'Meta': {'object_name': 'Source'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+ },
+ 'releng.test': {
+ 'Meta': {'object_name': 'Test'},
+ 'architecture': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['releng.Architecture']"}),
+ 'boot_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['releng.BootType']"}),
+ 'bootloader': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['releng.Bootloader']"}),
+ 'clock_choice': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['releng.ClockChoice']"}),
+ 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'created': ('django.db.models.fields.DateTimeField', [], {}),
+ 'filesystem': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['releng.Filesystem']"}),
+ 'hardware_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['releng.HardwareType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'install_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['releng.InstallType']"}),
+ 'ip_address': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}),
+ 'iso': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['releng.Iso']"}),
+ 'iso_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['releng.IsoType']"}),
+ 'modules': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['releng.Module']", 'null': 'True', 'blank': 'True'}),
+ 'rollback_filesystem': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'rollback_test_set'", 'null': 'True', 'to': "orm['releng.Filesystem']"}),
+ 'rollback_modules': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'rollback_test_set'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['releng.Module']"}),
+ 'source': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['releng.Source']"}),
+ 'success': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'user_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
+ 'user_name': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ }
+ }
+
+ complete_apps = ['releng']
diff --git a/releng/models.py b/releng/models.py
index a0dd57aa..b95f7d52 100644
--- a/releng/models.py
+++ b/releng/models.py
@@ -5,6 +5,7 @@ import hashlib
import markdown
from pytz import utc
+from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models.signals import pre_save
@@ -118,7 +119,9 @@ class Release(models.Model):
release_date = models.DateField(db_index=True)
version = models.CharField(max_length=50, unique=True)
kernel_version = models.CharField(max_length=50, blank=True)
- torrent_infohash = models.CharField(max_length=64, blank=True)
+ torrent_infohash = models.CharField(max_length=40, blank=True)
+ md5_sum = models.CharField('MD5 digest', max_length=32, blank=True)
+ sha1_sum = models.CharField('SHA1 digest', max_length=40, blank=True)
file_size = PositiveBigIntegerField(null=True, blank=True)
created = models.DateTimeField(editable=False)
available = models.BooleanField(default=True)
@@ -144,9 +147,9 @@ class Release(models.Model):
def magnet_uri(self):
query = [
('dn', "archlinux-%s-dual.iso" % self.version),
- ('tr', "udp://tracker.archlinux.org:6969"),
- ('tr', "http://tracker.archlinux.org:6969/announce"),
]
+ if settings.TORRENT_TRACKERS:
+ query.extend(('tr', uri) for uri in settings.TORRENT_TRACKERS)
if self.torrent_infohash:
query.insert(0, ('xt', "urn:btih:%s" % self.torrent_infohash))
return "magnet:?%s" % '&'.join(['%s=%s' % (k, v) for k, v in query])
@@ -160,6 +163,8 @@ class Release(models.Model):
data = b64decode(self.torrent_data)
except TypeError:
return None
+ if not data:
+ return None
data = bdecode(data)
# transform the data into a template-friendly dict
info = data.get('info', {})
diff --git a/settings.py b/settings.py
index dbc06159..c856bf57 100644
--- a/settings.py
+++ b/settings.py
@@ -164,6 +164,12 @@ PXEBOOT_URL = 'https://releng.archlinux.org/pxeboot/'
# community bit on the end, repo.svn_root is appended)
SVN_BASE_URL = 'svn://svn.archlinux.org/'
+# Trackers used for ISO download magnet links
+TORRENT_TRACKERS = (
+ 'udp://tracker.archlinux.org:6969',
+ 'http://tracker.archlinux.org:6969/announce',
+)
+
## Import local settings
from local_settings import *
diff --git a/templates/public/download.html b/templates/public/download.html
index 29490849..c68cf66b 100644
--- a/templates/public/download.html
+++ b/templates/public/download.html
@@ -28,6 +28,7 @@
<ul>
<li><strong>Current Release:</strong> {{ release.version }}</li>
{% if release.kernel_version %}<li><strong>Included Kernel:</strong> {{ release.kernel_version }}</li>{% endif %}
+ {% if release.file_size %}<li><strong>ISO Size:</strong> {{ release.file_size|filesizeformat }}</li>{% endif %}
<li><a href="https://wiki.archlinux.org/index.php/Installation_Guide">Installation Guide</a></li>
<li><strong>Resources:</strong>
<ul>
@@ -56,17 +57,21 @@
<p>If you can spare the bytes, please leave the client open after your
download is finished, so you can seed it back to others.
<em>A web-seed capable client is recommended for fastest download speeds.</em></p>
- <p><a href="https://www.archlinux.org/{{ release.iso_url }}.torrent"
- title="Download for both architectures">Download torrent for {{ release.version }}</a>
- (<a href="{{ release.magnet_uri }}">Magnet</a>)
- {% if release.file_size %}({{ release.file_size|filesizeformat }}){% endif %}
- </p>
+
+ <ul>
+ <li><a href="{{ release.magnet_uri }}"
+ title="Magnet link">Magnet link for {{ release.version }}</a></li>
+ <li><a href="{% url 'releng-release-torrent' release.version %}"
+ title="Download torrent">Torrent for {{ release.version }}</a></li>
+ </ul>
<h3>Netboot</h3>
<p>If you have a wired connection, you can boot the latest release directly over the network.</p>
- <p><a href="{{ releng_pxeboot_url }}"
- title="Arch Linux Netboot Live System">Arch Linux Netboot</a></p>
+ <ul>
+ <li><a href="{{ releng_pxeboot_url }}"
+ title="Arch Linux Netboot Live System">Arch Linux Netboot</a></li>
+ </ul>
<h3>HTTP Direct Downloads</h3>
@@ -81,11 +86,9 @@
<ul>
<li><a href="https://www.archlinux.org/{{ release.iso_url }}.sig"
- title="Get the latest PGP signature">PGP signature</a></li>
- <li><a href="https://www.archlinux.org/{{ release.dir_path }}sha1sums.txt"
- title="Get the latest SHA1 checksums">SHA1 checksums</a></li>
- <li><a href="https://www.archlinux.org/{{ release.dir_path }}md5sums.txt"
- title="Get the latest MD5 checksums">MD5 checksums</a></li>
+ title="PGP signature">PGP signature</a></li>
+ {% if release.md5_sum %}<li><strong>MD5:</strong> {{ release.md5_sum }}</li>{% endif %}
+ {% if release.sha1_sum %}<li><strong>SHA1:</strong> {{ release.sha1_sum }}</li>{% endif %}
</ul>
{% cache 600 download-mirrors %}
diff --git a/templates/releng/release_detail.html b/templates/releng/release_detail.html
index f4de9e52..01c0319e 100644
--- a/templates/releng/release_detail.html
+++ b/templates/releng/release_detail.html
@@ -1,4 +1,6 @@
{% extends "base.html" %}
+{% load url from future %}
+
{% block title %}Arch Linux - Release: {{ release.version }}{% endblock %}
{% block content %}
@@ -9,10 +11,13 @@
<li><strong>Release Date:</strong> {{ release.release_date|date }}</li>
{% if release.kernel_version %}<li><strong>Kernel Version:</strong> {{ release.kernel_version }}</li>{% endif %}
<li><strong>Available:</strong> {{ release.available|yesno }}</li>
- {% if release.available %}<li><strong>Download:</strong> <a href="https://www.archlinux.org/{{ release.iso_url }}.torrent"
+ {% if release.available %}<li><strong>Download:</strong> <a
+ href="{% url 'releng-release-torrent' release.version %}"
title="Download torrent for {{ release.version }}">Torrent</a>,
<a href="{{ release.magnet_uri }}">Magnet</a></li>{% endif %}
{% if release.torrent_infohash %}<li><strong>Torrent Info Hash:</strong> {{ release.torrent_infohash }}</li>{% endif %}
+ {% if release.md5_sum %}<li><strong>MD5:</strong> {{ release.md5_sum }}</li>{% endif %}
+ {% if release.sha1_sum %}<li><strong>SHA1:</strong> {{ release.sha1_sum }}</li>{% endif %}
<li><strong>Download Size:</strong> {% if release.file_size %}{{ release.file_size|filesizeformat }}{% else %}Unknown{% endif %}</li>
</ul>
diff --git a/templates/releng/release_list.html b/templates/releng/release_list.html
index 84008541..ef53a93d 100644
--- a/templates/releng/release_list.html
+++ b/templates/releng/release_list.html
@@ -31,7 +31,7 @@
<td><a href="{{ item.get_absolute_url }}" title="Release details for {{ item.version }}">{{ item.version }}</a></td>
<td>{{ item.kernel_version|default:"" }}</td>
<td class="available-{{ item.available|yesno }}">{{ item.available|yesno|capfirst }}</td>
- <td>{% if item.available %}<a href="https://www.archlinux.org/{{ item.iso_url }}.torrent"
+ <td>{% if item.available %}<a href="{% url 'releng-release-torrent' item.version %}"
title="Download torrent for {{ item.version }}">Torrent</a>{% endif %}</td>
<td>{% if item.available %}<a href="{{ item.magnet_uri }}">Magnet</a>{% endif %}</td>
<td>{% if item.file_size %}{{ item.file_size|filesizeformat }}{% endif %}</td>