From 49bf4988794c39095a9513c32ea971d5bcf5d33d Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 1 Jun 2013 09:21:42 -0500 Subject: Ensure only active mirror URLs are listed This fixes things up on the download page as well as the individual mirror details page. Signed-off-by: Dan McGee --- mirrors/models.py | 1 + mirrors/views.py | 2 +- public/views.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mirrors/models.py b/mirrors/models.py index 975ead39..da3d8c0d 100644 --- a/mirrors/models.py +++ b/mirrors/models.py @@ -116,6 +116,7 @@ class MirrorRsync(models.Model): class Meta: verbose_name = 'mirror rsync IP' + ordering = ('ip',) class CheckLocation(models.Model): diff --git a/mirrors/views.py b/mirrors/views.py index 6f4ad838..ec056696 100644 --- a/mirrors/views.py +++ b/mirrors/views.py @@ -161,7 +161,7 @@ def mirror_details(request, name): status_info = get_mirror_statuses(mirror_id=mirror.id) checked_urls = {url for url in status_info['urls'] \ if url.mirror_id == mirror.id} - all_urls = set(mirror.urls.select_related('protocol')) + all_urls = set(mirror.urls.filter(active=True).select_related('protocol')) # Add dummy data for URLs that we haven't checked recently other_urls = all_urls.difference(checked_urls) for url in other_urls: diff --git a/public/views.py b/public/views.py index 39273396..24edd044 100644 --- a/public/views.py +++ b/public/views.py @@ -80,7 +80,7 @@ def _mirror_urls(): '''In order to ensure this is lazily evaluated since we can't do sorting at the database level, make it a callable.''' urls = MirrorUrl.objects.select_related('mirror').filter( - protocol__default=True, + active=True, protocol__default=True, mirror__public=True, mirror__active=True, mirror__isos=True) sort_by = attrgetter('country.name', 'mirror.name') return sorted(urls, key=sort_by) -- cgit v1.2.3-2-g168b From 80d323c39218d113d3002f5bf76bd464cddfcb95 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 1 Jun 2013 14:53:51 -0500 Subject: Guard logging operation to prevent needless text join Signed-off-by: Dan McGee --- mirrors/management/commands/mirrorcheck.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mirrors/management/commands/mirrorcheck.py b/mirrors/management/commands/mirrorcheck.py index 6faf294a..3f026c36 100644 --- a/mirrors/management/commands/mirrorcheck.py +++ b/mirrors/management/commands/mirrorcheck.py @@ -179,10 +179,11 @@ def check_rsync_url(mirror_url, location, timeout): rsync_cmd.append(lastsync_path) try: with open(os.devnull, 'w') as devnull: - logger.debug("rsync cmd: %s", ' '.join(rsync_cmd)) + 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) - start = time.time() _, errdata = proc.communicate() end = time.time() log.duration = end - start -- cgit v1.2.3-2-g168b From b9fab139ed9e5e24b853c0f77bcc78ffba8176b0 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Fri, 14 Jun 2013 12:13:02 -0500 Subject: Add PGP signature signer and signee indexes Signed-off-by: Dan McGee --- ...nature_signee__add_index_pgpsignature_signer.py | 119 +++++++++++++++++++++ devel/models.py | 10 +- 2 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 devel/migrations/0010_auto__add_index_pgpsignature_signee__add_index_pgpsignature_signer.py diff --git a/devel/migrations/0010_auto__add_index_pgpsignature_signee__add_index_pgpsignature_signer.py b/devel/migrations/0010_auto__add_index_pgpsignature_signee__add_index_pgpsignature_signer.py new file mode 100644 index 00000000..55f8c800 --- /dev/null +++ b/devel/migrations/0010_auto__add_index_pgpsignature_signee__add_index_pgpsignature_signer.py @@ -0,0 +1,119 @@ +# -*- 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.create_index(u'devel_pgpsignature', ['signee']) + db.create_index(u'devel_pgpsignature', ['signer']) + + def backwards(self, orm): + db.delete_index(u'devel_pgpsignature', ['signer']) + db.delete_index(u'devel_pgpsignature', ['signee']) + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'devel.developerkey': { + 'Meta': {'object_name': 'DeveloperKey'}, + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'key': ('devel.fields.PGPKeyField', [], {'unique': 'True', 'max_length': '40'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'all_keys'", 'null': 'True', 'to': u"orm['auth.User']"}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['devel.DeveloperKey']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'revoked': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + u'devel.masterkey': { + 'Meta': {'ordering': "('created',)", 'object_name': 'MasterKey'}, + 'created': ('django.db.models.fields.DateField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'masterkey_owner'", 'to': u"orm['auth.User']"}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40'}), + 'revoked': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'revoker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'masterkey_revoker'", 'to': u"orm['auth.User']"}) + }, + u'devel.pgpsignature': { + 'Meta': {'ordering': "('signer', 'signee')", 'object_name': 'PGPSignature'}, + 'created': ('django.db.models.fields.DateField', [], {}), + 'expires': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'signee': ('devel.fields.PGPKeyField', [], {'max_length': '40', 'db_index': 'True'}), + 'signer': ('devel.fields.PGPKeyField', [], {'max_length': '40', 'db_index': 'True'}), + 'valid': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + u'devel.userprofile': { + 'Meta': {'object_name': 'UserProfile', 'db_table': "'user_profiles'"}, + 'alias': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'allowed_repos': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['main.Repo']", 'symmetrical': 'False', 'blank': 'True'}), + 'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}), + 'favorite_distros': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'interests': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'languages': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {}), + 'latin_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'location': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'notify': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'occupation': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'other_contact': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'picture': ('django.db.models.fields.files.FileField', [], {'default': "'devs/silhouette.png'", 'max_length': '100'}), + 'public_email': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'roles': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'time_zone': ('django.db.models.fields.CharField', [], {'default': "'UTC'", 'max_length': '100'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'userprofile'", 'unique': 'True', 'to': u"orm['auth.User']"}), + 'website': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'yob': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) + }, + u'main.repo': { + 'Meta': {'ordering': "('name',)", 'object_name': 'Repo', 'db_table': "'repos'"}, + 'bugs_category': ('django.db.models.fields.SmallIntegerField', [], {'default': '2'}), + 'bugs_project': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'staging': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'svn_root': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'testing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + } + } + + complete_apps = ['devel'] diff --git a/devel/models.py b/devel/models.py index 4354e0f2..bf979338 100644 --- a/devel/models.py +++ b/devel/models.py @@ -88,9 +88,9 @@ class MasterKey(models.Model): class DeveloperKey(models.Model): owner = models.ForeignKey(User, related_name='all_keys', null=True, - help_text="The developer this key belongs to") + help_text="The developer this key belongs to") key = PGPKeyField(max_length=40, verbose_name="PGP key fingerprint", - unique=True) + unique=True) created = models.DateTimeField() expires = models.DateTimeField(null=True, blank=True) revoked = models.DateTimeField(null=True, blank=True) @@ -101,8 +101,10 @@ class DeveloperKey(models.Model): class PGPSignature(models.Model): - signer = PGPKeyField(max_length=40, verbose_name="Signer key fingerprint") - signee = PGPKeyField(max_length=40, verbose_name="Signee key fingerprint") + signer = PGPKeyField(max_length=40, verbose_name="Signer key fingerprint", + db_index=True) + signee = PGPKeyField(max_length=40, verbose_name="Signee key fingerprint", + db_index=True) created = models.DateField() expires = models.DateField(null=True, blank=True) valid = models.BooleanField(default=True) -- cgit v1.2.3-2-g168b From 0cac18ea4f3e56d1b7d1bdcb6729e22cbf3f5a44 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 20 Jun 2013 14:09:11 -0500 Subject: Add link to release listing page from public index We didn't link this page from anywhere so it was hard to find. Also add it to the sitemap so it gets indexed. Signed-off-by: Dan McGee --- sitemaps.py | 3 ++- templates/public/index.html | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sitemaps.py b/sitemaps.py index d206a1b6..42b08922 100644 --- a/sitemaps.py +++ b/sitemaps.py @@ -136,7 +136,8 @@ class BaseSitemap(Sitemap): 'mirror-status', 'mirrorlist', 'packages-differences', - 'releng-test-overview', + ('releng-test-overview', 0.3, 'monthly'), + 'releng-release-list', 'visualize-index', ) diff --git a/templates/public/index.html b/templates/public/index.html index 37d6decc..7e6daf8d 100644 --- a/templates/public/index.html +++ b/templates/public/index.html @@ -169,6 +169,8 @@ title="View the available package groups">Package Groups
  • Todo Lists
  • +
  • ISO Release List
  • Visualizations
  • -- cgit v1.2.3-2-g168b From 9e4a0939145505e7f606ee8b66ea1acd092abb85 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 20 Jun 2013 14:11:23 -0500 Subject: Re-enable caching for somewhat expensive mirror status query This should be a small enough chunk of data that it isn't super expensive to put into and pull out of memcached. Signed-off-by: Dan McGee --- mirrors/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mirrors/utils.py b/mirrors/utils.py index e98b5c9f..bba8e36b 100644 --- a/mirrors/utils.py +++ b/mirrors/utils.py @@ -21,7 +21,7 @@ def dictfetchall(cursor): for row in cursor.fetchall() ] - +@cache_function(178) def status_data(cutoff_time, mirror_id=None): if mirror_id is not None: params = [cutoff_time, mirror_id] -- cgit v1.2.3-2-g168b From 772a500534a508b5b9f88e2883c8dcb488c4b4d9 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 13 Jul 2013 09:50:45 -0500 Subject: Move simple feeds templates directly into feed classes No need to call out to the template engine to format... nothing at all. Just fetch the attribute directly and save the render step. Signed-off-by: Dan McGee --- feeds.py | 8 ++++++-- templates/feeds/news_title.html | 1 - templates/feeds/packages_description.html | 1 - 3 files changed, 6 insertions(+), 4 deletions(-) delete mode 100644 templates/feeds/news_title.html delete mode 100644 templates/feeds/packages_description.html diff --git a/feeds.py b/feeds.py index 9721f41c..678bebcf 100644 --- a/feeds.py +++ b/feeds.py @@ -49,7 +49,6 @@ class PackageFeed(Feed): link = '/packages/' title_template = 'feeds/packages_title.html' - description_template = 'feeds/packages_description.html' def __call__(self, request, *args, **kwargs): wrapper = condition(etag_func=package_etag, last_modified_func=package_last_modified) @@ -112,6 +111,9 @@ class PackageFeed(Feed): def item_pubdate(self, item): return item.last_update + def item_description(self, item): + return item.pkgdesc + def item_categories(self, item): return (item.repo.name, item.arch.name) @@ -133,7 +135,6 @@ class NewsFeed(Feed): link = '/news/' description = 'The latest and greatest news from the Arch Linux distribution.' subtitle = description - title_template = 'feeds/news_title.html' description_template = 'feeds/news_description.html' def __call__(self, request, *args, **kwargs): @@ -155,6 +156,9 @@ class NewsFeed(Feed): def item_author_name(self, item): return item.author.get_full_name() + def item_title(self, item): + return item.title + class ReleaseFeed(Feed): feed_type = GuidNotPermalinkFeed diff --git a/templates/feeds/news_title.html b/templates/feeds/news_title.html deleted file mode 100644 index 7899fce3..00000000 --- a/templates/feeds/news_title.html +++ /dev/null @@ -1 +0,0 @@ -{{ obj.title }} \ No newline at end of file diff --git a/templates/feeds/packages_description.html b/templates/feeds/packages_description.html deleted file mode 100644 index cfc42616..00000000 --- a/templates/feeds/packages_description.html +++ /dev/null @@ -1 +0,0 @@ -{{ obj.pkgdesc }} \ No newline at end of file -- cgit v1.2.3-2-g168b From 845769e156520708acf65c8f3ec2756476202cc7 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 13 Jul 2013 09:51:33 -0500 Subject: Show alternate email on mirror details page Signed-off-by: Dan McGee --- templates/mirrors/mirror_details.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/templates/mirrors/mirror_details.html b/templates/mirrors/mirror_details.html index ccd6eb57..1c7f5633 100644 --- a/templates/mirrors/mirror_details.html +++ b/templates/mirrors/mirror_details.html @@ -48,6 +48,10 @@ Admin Email: {% if mirror.admin_email %}{{ mirror.admin_email }}{% else %}None{% endif %} + + Alternate Email: + {% if mirror.alternate_email %}{{ mirror.alternate_email }}{% else %}None{% endif %} + Notes: {{ mirror.notes|linebreaks }} -- cgit v1.2.3-2-g168b From e4ba546a56d3cbfb4b76508a318ae77d88bff0c7 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 13 Jul 2013 09:56:12 -0500 Subject: Bump psycopg2 requirements version Signed-off-by: Dan McGee --- requirements_prod.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_prod.txt b/requirements_prod.txt index 1c331cf9..1daa9e85 100644 --- a/requirements_prod.txt +++ b/requirements_prod.txt @@ -7,7 +7,7 @@ bencode==1.0 django-countries==1.5 jsmin==2.0.3 pgpdump==1.4 -psycopg2==2.5 +psycopg2==2.5.1 pyinotify==0.9.4 python-memcached==1.51 pytz>=2013b -- cgit v1.2.3-2-g168b From fa647734a2d2f5e019285f1e0fee2cac2482f884 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 17 Jun 2013 13:33:36 -0500 Subject: Use the unicode char representation of   Signed-off-by: Dan McGee --- main/templatetags/pgp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/templatetags/pgp.py b/main/templatetags/pgp.py index afad9df2..e93e5bca 100644 --- a/main/templatetags/pgp.py +++ b/main/templatetags/pgp.py @@ -15,7 +15,7 @@ def format_key(key_id): # normal display format is 5 groups of 4 hex chars seperated 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 u'%s  %s' % (' '.join(split[0:5]), ' '.join(split[5:10])) + return u'%s\u00a0 %s' % (' '.join(split[0:5]), ' '.join(split[5:10])) return u'0x%s' % key_id @register.simple_tag -- cgit v1.2.3-2-g168b From ffaa2cfb254a238ba0eb704115b95360305d1ae7 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 20 Jun 2013 14:11:21 -0500 Subject: Update memcached version requirement Signed-off-by: Dan McGee --- requirements_prod.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_prod.txt b/requirements_prod.txt index 1daa9e85..425a6576 100644 --- a/requirements_prod.txt +++ b/requirements_prod.txt @@ -9,5 +9,5 @@ jsmin==2.0.3 pgpdump==1.4 psycopg2==2.5.1 pyinotify==0.9.4 -python-memcached==1.51 +python-memcached==1.53 pytz>=2013b -- cgit v1.2.3-2-g168b