diff options
author | Luke Shumaker <LukeShu@sbcglobal.net> | 2012-11-15 01:12:12 -0500 |
---|---|---|
committer | Luke Shumaker <LukeShu@sbcglobal.net> | 2012-11-15 01:12:12 -0500 |
commit | 38f1b73179154c1fef676021acd6362e88837a89 (patch) | |
tree | 14b7789ccb23a7d0715dc9cfc75d3de0d3700dcf | |
parent | aa2836cb3859e05e9524def5ec37706e3299205c (diff) | |
parent | 03a0d27971898592698dbb0c5948b93c6a3a4741 (diff) |
Merge tag 'release_2012-02-18'
Defend against bogus URLs, mirrorlist no FTP by default
Conflicts:
templates/public/index.html
-rw-r--r-- | devel/views.py | 10 | ||||
-rw-r--r-- | mirrors/admin.py | 8 | ||||
-rw-r--r-- | mirrors/fixtures/mirrorprotocols.json | 5 | ||||
-rw-r--r-- | mirrors/migrations/0010_auto__add_field_mirrorprotocol_default.py | 66 | ||||
-rw-r--r-- | mirrors/migrations/0011_adjust_protocol_defaults.py | 67 | ||||
-rw-r--r-- | mirrors/models.py | 2 | ||||
-rw-r--r-- | mirrors/views.py | 6 | ||||
-rw-r--r-- | packages/templatetags/package_extras.py | 7 | ||||
-rw-r--r-- | packages/urls.py | 2 | ||||
-rw-r--r-- | packages/views/__init__.py | 2 | ||||
-rw-r--r-- | packages/views/flag.py | 6 | ||||
-rw-r--r-- | templates/public/index.html | 45 |
12 files changed, 187 insertions, 39 deletions
diff --git a/devel/views.py b/devel/views.py index dc2283ca..793d1520 100644 --- a/devel/views.py +++ b/devel/views.py @@ -209,8 +209,10 @@ def report(request, report_name, username=None): elif report_name == 'uncompressed-man': title = 'Packages with uncompressed manpages' # checking for all '.0'...'.9' + '.n' extensions - bad_files = PackageFile.objects.filter(directory__contains='/man/', - filename__regex=r'\.[0-9n]').exclude(filename__endswith='.gz') + bad_files = PackageFile.objects.filter(is_directory=False, + directory__contains='/man/', + filename__regex=r'\.[0-9n]').exclude( + filename__endswith='.gz').exclude(filename__endswith='.html') if username: pkg_ids = set(packages.values_list('id', flat=True)) bad_files = bad_files.filter(pkg__in=pkg_ids) @@ -220,8 +222,8 @@ def report(request, report_name, username=None): title = 'Packages with uncompressed infopages' # we don't worry about looking for '*.info-1', etc., given that an # uncompressed root page probably exists in the package anyway - bad_files = PackageFile.objects.filter(directory__endswith='/info/', - filename__endswith='.info') + bad_files = PackageFile.objects.filter(is_directory=False, + directory__endswith='/info/', filename__endswith='.info') if username: pkg_ids = set(packages.values_list('id', flat=True)) bad_files = bad_files.filter(pkg__in=pkg_ids) diff --git a/mirrors/admin.py b/mirrors/admin.py index 3786d8d2..a2b59b41 100644 --- a/mirrors/admin.py +++ b/mirrors/admin.py @@ -56,7 +56,9 @@ class MirrorRsyncInlineAdmin(admin.TabularInline): class MirrorAdminForm(forms.ModelForm): class Meta: model = Mirror - upstream = forms.ModelChoiceField(queryset=Mirror.objects.filter(tier__gte=0, tier__lte=1), required=False) + upstream = forms.ModelChoiceField( + queryset=Mirror.objects.filter(tier__gte=0, tier__lte=1), + required=False) class MirrorAdmin(admin.ModelAdmin): form = MirrorAdminForm @@ -70,8 +72,8 @@ class MirrorAdmin(admin.ModelAdmin): ] class MirrorProtocolAdmin(admin.ModelAdmin): - list_display = ('protocol', 'is_download',) - list_filter = ('is_download',) + list_display = ('protocol', 'is_download', 'default') + list_filter = ('is_download', 'default') admin.site.register(Mirror, MirrorAdmin) admin.site.register(MirrorProtocol, MirrorProtocolAdmin) diff --git a/mirrors/fixtures/mirrorprotocols.json b/mirrors/fixtures/mirrorprotocols.json index 35614b3a..72ed1a7f 100644 --- a/mirrors/fixtures/mirrorprotocols.json +++ b/mirrors/fixtures/mirrorprotocols.json @@ -4,6 +4,7 @@ "model": "mirrors.mirrorprotocol", "fields": { "is_download": true, + "default": true, "protocol": "http" } }, @@ -12,6 +13,7 @@ "model": "mirrors.mirrorprotocol", "fields": { "is_download": true, + "default": false, "protocol": "ftp" } }, @@ -20,7 +22,8 @@ "model": "mirrors.mirrorprotocol", "fields": { "is_download": false, + "default": false, "protocol": "rsync" } } -]
\ No newline at end of file +] diff --git a/mirrors/migrations/0010_auto__add_field_mirrorprotocol_default.py b/mirrors/migrations/0010_auto__add_field_mirrorprotocol_default.py new file mode 100644 index 00000000..6868cb25 --- /dev/null +++ b/mirrors/migrations/0010_auto__add_field_mirrorprotocol_default.py @@ -0,0 +1,66 @@ +# encoding: 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('mirrors_mirrorprotocol', 'default', self.gf('django.db.models.fields.BooleanField')(default=True), keep_default=False) + + def backwards(self, orm): + db.delete_column('mirrors_mirrorprotocol', 'default') + + + models = { + 'mirrors.mirror': { + 'Meta': {'ordering': "('country', 'name')", 'object_name': 'Mirror'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'admin_email': ('django.db.models.fields.EmailField', [], {'max_length': '255', 'blank': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'isos': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'rsync_password': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '50', 'blank': 'True'}), + 'rsync_user': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '50', 'blank': 'True'}), + 'tier': ('django.db.models.fields.SmallIntegerField', [], {'default': '2'}), + 'upstream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['mirrors.Mirror']", 'null': 'True'}) + }, + 'mirrors.mirrorlog': { + 'Meta': {'object_name': 'MirrorLog'}, + 'check_time': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'duration': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'error': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_success': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_sync': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'logs'", 'to': "orm['mirrors.MirrorUrl']"}) + }, + 'mirrors.mirrorprotocol': { + 'Meta': {'ordering': "('protocol',)", 'object_name': 'MirrorProtocol'}, + 'default': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_download': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'protocol': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '10'}) + }, + 'mirrors.mirrorrsync': { + 'Meta': {'object_name': 'MirrorRsync'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip': ('django.db.models.fields.CharField', [], {'max_length': '24'}), + 'mirror': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rsync_ips'", 'to': "orm['mirrors.Mirror']"}) + }, + 'mirrors.mirrorurl': { + 'Meta': {'object_name': 'MirrorUrl'}, + 'country': ('mirrors.models.NullCharField', [], {'db_index': 'True', 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'has_ipv4': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'has_ipv6': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mirror': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'urls'", 'to': "orm['mirrors.Mirror']"}), + 'protocol': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'urls'", 'to': "orm['mirrors.MirrorProtocol']"}), + 'url': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}) + } + } + + complete_apps = ['mirrors'] diff --git a/mirrors/migrations/0011_adjust_protocol_defaults.py b/mirrors/migrations/0011_adjust_protocol_defaults.py new file mode 100644 index 00000000..0118de67 --- /dev/null +++ b/mirrors/migrations/0011_adjust_protocol_defaults.py @@ -0,0 +1,67 @@ +# encoding: utf-8 +from south.db import db +from south.v2 import DataMigration +from django.db import models + +class Migration(DataMigration): + + def forwards(self, orm): + orm.MirrorProtocol.objects.all().update(default=False) + orm.MirrorProtocol.objects.filter(protocol='http').update(default=True) + + def backwards(self, orm): + pass + + + models = { + 'mirrors.mirror': { + 'Meta': {'ordering': "('country', 'name')", 'object_name': 'Mirror'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'admin_email': ('django.db.models.fields.EmailField', [], {'max_length': '255', 'blank': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'isos': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'rsync_password': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '50', 'blank': 'True'}), + 'rsync_user': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '50', 'blank': 'True'}), + 'tier': ('django.db.models.fields.SmallIntegerField', [], {'default': '2'}), + 'upstream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['mirrors.Mirror']", 'null': 'True'}) + }, + 'mirrors.mirrorlog': { + 'Meta': {'object_name': 'MirrorLog'}, + 'check_time': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'duration': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'error': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_success': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_sync': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'logs'", 'to': "orm['mirrors.MirrorUrl']"}) + }, + 'mirrors.mirrorprotocol': { + 'Meta': {'ordering': "('protocol',)", 'object_name': 'MirrorProtocol'}, + 'default': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_download': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'protocol': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '10'}) + }, + 'mirrors.mirrorrsync': { + 'Meta': {'object_name': 'MirrorRsync'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip': ('django.db.models.fields.CharField', [], {'max_length': '24'}), + 'mirror': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rsync_ips'", 'to': "orm['mirrors.Mirror']"}) + }, + 'mirrors.mirrorurl': { + 'Meta': {'object_name': 'MirrorUrl'}, + 'country': ('mirrors.models.NullCharField', [], {'db_index': 'True', 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'has_ipv4': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'has_ipv6': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mirror': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'urls'", 'to': "orm['mirrors.Mirror']"}), + 'protocol': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'urls'", 'to': "orm['mirrors.MirrorProtocol']"}), + 'url': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}) + } + } + + complete_apps = ['mirrors'] diff --git a/mirrors/models.py b/mirrors/models.py index 111654fd..86905eea 100644 --- a/mirrors/models.py +++ b/mirrors/models.py @@ -54,6 +54,8 @@ class MirrorProtocol(models.Model): protocol = models.CharField(max_length=10, unique=True) is_download = models.BooleanField(default=True, help_text="Is protocol useful for end-users, e.g. FTP/HTTP") + default = models.BooleanField(default=True, + help_text="Included by default when building mirror list?") def __unicode__(self): return self.protocol diff --git a/mirrors/views.py b/mirrors/views.py index 417e26ee..2ef8654d 100644 --- a/mirrors/views.py +++ b/mirrors/views.py @@ -29,8 +29,9 @@ class MirrorlistForm(forms.Form): self.fields['country'].initial = ['all'] protos = make_choice( MirrorProtocol.objects.filter(is_download=True)) + initial = MirrorProtocol.objects.filter(is_download=True, default=True) self.fields['protocol'].choices = protos - self.fields['protocol'].initial = [t[0] for t in protos] + self.fields['protocol'].initial = [p.protocol for p in initial] self.fields['ip_version'].initial = ['4'] @csrf_exempt @@ -48,7 +49,8 @@ def generate_mirrorlist(request): else: form = MirrorlistForm() - return direct_to_template(request, 'mirrors/index.html', {'mirrorlist_form': form}) + return direct_to_template(request, 'mirrors/index.html', + {'mirrorlist_form': form}) def find_mirrors(request, countries=None, protocols=None, use_status=False, ipv4_supported=True, ipv6_supported=True): diff --git a/packages/templatetags/package_extras.py b/packages/templatetags/package_extras.py index 71ff5ed8..2e68ef0c 100644 --- a/packages/templatetags/package_extras.py +++ b/packages/templatetags/package_extras.py @@ -9,8 +9,11 @@ from django.utils.html import escape register = template.Library() -def link_encode(url, query, doseq=False): - data = urlencode(query, doseq).replace('&', '&') +def link_encode(url, query): + # massage the data into all utf-8 encoded strings first, so urlencode + # doesn't barf at the data we pass it + query = dict((k, unicode(v).encode('utf-8')) for k, v in query.items()) + data = urlencode(query).replace('&', '&') return "%s?%s" % (url, data) @register.filter diff --git a/packages/urls.py b/packages/urls.py index 6c616297..52b09d2c 100644 --- a/packages/urls.py +++ b/packages/urls.py @@ -28,7 +28,7 @@ urlpatterns = patterns('packages.views', (r'^stale_relations/$', 'stale_relations'), (r'^stale_relations/update/$','stale_relations_update'), - (r'^(?P<name>[A-z0-9\-+.]+)/$', + (r'^(?P<name>[^ /]+)/$', 'details'), (r'^(?P<repo>[A-z0-9\-]+)/(?P<name>[^ /]+)/$', 'details'), diff --git a/packages/views/__init__.py b/packages/views/__init__.py index 9ca21407..08e0286c 100644 --- a/packages/views/__init__.py +++ b/packages/views/__init__.py @@ -142,7 +142,7 @@ def details(request, name='', repo='', arch=''): ('q', name), ] # only include non-blank values in the query we generate - pkg_data = [(x, y) for x, y in pkg_data if y] + pkg_data = [(x, y.encode('utf-8')) for x, y in pkg_data if y] return redirect("/packages/?%s" % urlencode(pkg_data)) def groups(request, arch=None): diff --git a/packages/views/flag.py b/packages/views/flag.py index ad1b04db..e87cef69 100644 --- a/packages/views/flag.py +++ b/packages/views/flag.py @@ -18,9 +18,9 @@ def flaghelp(request): return direct_to_template(request, 'packages/flaghelp.html') class FlagForm(forms.Form): - email = forms.EmailField(label='* E-mail Address') - message = forms.CharField(label='Message To Dev', - widget=forms.Textarea, required=False) + email = forms.EmailField(label='E-mail Address') + message = forms.CharField(label='Message To Developer', + widget=forms.Textarea) # The field below is used to filter out bots that blindly fill out all # input elements website = forms.CharField(label='', diff --git a/templates/public/index.html b/templates/public/index.html index 0d57e505..15db0719 100644 --- a/templates/public/index.html +++ b/templates/public/index.html @@ -25,7 +25,7 @@ <p>You can find us on IRC at <a href="irc://irc.freenode.net/#parabola">irc.freenode.net/#parabola</a>.</p> - + <p class="readmore"><a href="{% url page-about %}" title="Learn more about Parabola">Learn more...</a></p> @@ -39,7 +39,7 @@ </h3> <a href="/feeds/news/" title="Parabola News RSS Feed" - class="rss-icon"><img src="{{ STATIC_URL }}rss.png" alt="RSS Feed" /></a> + class="rss-icon"><img src="{% cdnprefix %}/media/rss.png" alt="RSS Feed" /></a> {% for news in news_updates %} {% if forloop.counter0 < 5 %} @@ -92,7 +92,7 @@ title="Browse all of the latest packages">more</a>)</span></h3> <a href="/feeds/packages/" title="Parabola Package Updates RSS Feed" - class="rss-icon"><img src="{{ STATIC_URL }}rss.png" alt="RSS Feed" /></a> + class="rss-icon"><img src="{% cdnprefix %}/media/rss.png" alt="RSS Feed" /></a> <table> {% for update in pkg_updates %} @@ -153,38 +153,31 @@ <h4>Development</h4> <ul> - <li><a href="{% url page-keys %}" - title="Package/Database signing master keys">Master Keys</a> - <img src="{% cdnprefix %}/media/new.png" alt="New"/></li> - <li><a href="/packages/" - title="View/search the package repository database">Packages</a></li> - <li><a href="/groups/" - title="View the available package groups">Package Groups</a></li> - <li><a href="{% url visualize-index %}" - title="View visualizations">Visualizations</a> - <img src="{% cdnprefix %}/media/new.png" alt="New"/></li> -{% comment %} - <li><a href="{% url page-svn %}" - title="View SVN entries for packages">SVN Repositories</a></li> -{% endcomment %} <li><a href="https://projects.parabolagnulinux.org" title="Official Parabola projects (git)">Projects in Git</a></li> {% comment %} + <li><a href="{% url page-svn %}" + title="View SVN entries for packages">SVN Repositories</a></li> <li><a href="https://wiki.archlinux.org/index.php/DeveloperWiki" - title="Developer Wiki articles">DeveloperWiki</a></li> + title="Developer Wiki articles">Developer Wiki</a></li> {% endcomment %} + <li><a href="/groups/" + title="View the available package groups">Package Groups</a></li> <li><a href="/todolists/" title="Hacker Todo Lists">Todo Lists</a></li> <li><a href="{% url releng-test-overview %}" title="Releng Testbuild Feedback">Releng Testbuild Feedback</a></li> + <li><a href="{% url visualize-index %}" + title="View visualizations">Visualizations</a> + <img src="{% cdnprefix %}/media/new.png" alt="New"/></li> </ul> - <h4>About</h4> + <h4>More Resources</h4> <ul> - <li><a href="{% url page-about %}" - title="Learn more about Parabola">About Parabola</a></li> - <li><a href="/download/" title="Get Parabola">Download Parabola</a></li> + <li><a href="{% url page-keys %}" + title="Package/Database signing master keys">Signing Master Keys</a> + <img src="{% cdnprefix %}/media/new.png" alt="New"/></li> <li><a href="https://wiki.parabolagnulinux.org/Media" title="Parabola in the media">Media Appearances</a></li> <li><a href="{% url page-art %}" title="Parabola logos and other artwork for promotional use">Logos & Artwork</a></li> @@ -196,7 +189,14 @@ </div><!-- #nav-sidebar --> +{% comment %} +<div id="home-donate-button" class="widget"> +donate button would go here +</div> +{% endcomment %} + <div id="arch-sponsors" class="widget"> + <a href="http://gnuchile.org"> <img src="{{ STATIC_URL }}gnuchile.png" alt="GNU Chile - Donates the .org domain" @@ -218,6 +218,7 @@ alt="Freedom Included - Donated Lemote Yeeloongs to port Parabola to the MIPS architecture" title="Freedom Included - Donated Lemote Yeeloongs to port Parabola to the MIPS architecture" /> </a> + </div> {% endcache %} {% endblock %} |