From b9c6451f88caa35ab39b6468a99b147d7d7f4937 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sun, 20 Mar 2011 15:51:02 -0500 Subject: Fix news preview with CSRF and AJAX in Django 1.2.5 Signed-off-by: Dan McGee --- media/archweb.js | 14 ++++++++------ templates/news/add.html | 8 ++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/media/archweb.js b/media/archweb.js index 52e817a4..03358fa9 100644 --- a/media/archweb.js +++ b/media/archweb.js @@ -71,16 +71,18 @@ if (typeof $.tablesorter !== 'undefined') { /* news/add.html */ function enablePreview() { - $('#previewbtn').click(function(event) { + $('#news-preview-button').click(function(event) { event.preventDefault(); - $.post('/news/preview/', - { data: $('#id_content').val() }, + $.post('/news/preview/', { + data: $('#id_content').val(), + csrfmiddlewaretoken: $('#newsform input[name=csrfmiddlewaretoken]').val() + }, function(data) { - $('#previewdata').html(data); - $('.news-article').show(); + $('#news-preview-data').html(data); + $('#news-preview').show(); } ); - $('#previewtitle').html($('#id_title').val()); + $('#news-preview-title').html($('#id_title').val()); }); } diff --git a/templates/news/add.html b/templates/news/add.html index f580e0d0..bb866dc4 100644 --- a/templates/news/add.html +++ b/templates/news/add.html @@ -23,14 +23,14 @@

- +

- -{% load cdn %}{% jquery %} - - -{% endblock %} diff --git a/templates/packages/packages_list.html b/templates/packages/packages_list.html new file mode 100644 index 00000000..c897aac5 --- /dev/null +++ b/templates/packages/packages_list.html @@ -0,0 +1,47 @@ +{% extends "base.html" %} +{% block title %}Arch Linux - {{ name }} ({{ arch.name }}) - {{ list_title }}{% endblock %} +{% block navbarclass %}anb-packages{% endblock %} + +{% block content %} +
+

{{ list_title }} - {{ name }} ({{ arch.name }})

+ + + + + + + + + + + + + + {% for pkg in packages %} + + + + + {% if pkg.flag_date %} + + {% else %} + + {% endif %} + + + + + {% endfor %} + +
ArchRepoNameVersionDescriptionLast UpdatedFlag Date
{{ pkg.arch.name }}{{ pkg.repo.name|capfirst }}{{ pkg.pkgname }}{{ pkg.full_version }}{{ pkg.full_version }}{{ pkg.pkgdesc }}{{ pkg.last_update|date }}{{ pkg.flag_date|date }}
+
+{% load cdn %}{% jquery %} + + +{% endblock %} -- cgit v1.2.3-2-g168b From a52ddb5c48dd2cb7856779f64611679aca7d660d Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 23 Mar 2011 12:47:26 -0500 Subject: Allow virtual base packages to display in web interface Repurpose the old group details page to show a listing of all packages built from a particular pkgbase value, even if this value is not an actual package. Signed-off-by: Dan McGee --- packages/views.py | 26 +++++++++++++++++++++++--- templates/packages/details.html | 3 ++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/packages/views.py b/packages/views.py index 374a1a20..263165fd 100644 --- a/packages/views.py +++ b/packages/views.py @@ -83,9 +83,29 @@ def update(request): def details(request, name='', repo='', arch=''): if all([name, repo, arch]): - pkg = get_object_or_404(Package, - pkgname=name, repo__name__iexact=repo, arch__name=arch) - return direct_to_template(request, 'packages/details.html', {'pkg': pkg, }) + try: + pkg = Package.objects.get(pkgname=name, + repo__name__iexact=repo, arch__name=arch) + return direct_to_template(request, 'packages/details.html', + {'pkg': pkg, }) + except Package.DoesNotExist: + arch = get_object_or_404(Arch, name=arch) + arches = [ arch ] + arches.extend(Arch.objects.filter(agnostic=True)) + repo = get_object_or_404(Repo, name__iexact=repo) + pkgs = Package.objects.filter(pkgbase=name, + repo__testing=repo.testing, arch__in=arches) + pkgs = pkgs.select_related('arch', 'repo').order_by('pkgname') + if len(pkgs) == 0: + raise Http404 + context = { + 'list_title': 'Split Package Details', + 'name': name, + 'arch': arch, + 'packages': pkgs, + } + return direct_to_template(request, 'packages/packages_list.html', + context) else: return redirect("/packages/?arch=%s&repo=%s&q=%s" % ( arch.lower(), repo.title(), name)) diff --git a/templates/packages/details.html b/templates/packages/details.html index 051726bd..4253f0b3 100644 --- a/templates/packages/details.html +++ b/templates/packages/details.html @@ -96,7 +96,8 @@ {{ pkg.pkgbase }} {% else %} - {{ pkg.pkgbase }} + {{ pkg.pkgbase }} {% endif %} {% endifequal %} -- cgit v1.2.3-2-g168b From 5f7fbcb7133b1c04824d1aa4ded7af8feef13c2e Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 23 Mar 2011 13:01:21 -0500 Subject: Add basic todo list admin site Signed-off-by: Dan McGee --- main/admin.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/main/admin.py b/main/admin.py index a2c5b2a9..45bc5ab2 100644 --- a/main/admin.py +++ b/main/admin.py @@ -1,7 +1,7 @@ from django.contrib import admin from django.contrib.auth.models import User from django.contrib.auth.admin import UserAdmin -from main.models import Arch, Donor, Package, Repo, UserProfile +from main.models import Arch, Donor, Package, Repo, Todolist, UserProfile class DonorAdmin(admin.ModelAdmin): list_display = ('name', 'visible') @@ -23,6 +23,10 @@ class PackageAdmin(admin.ModelAdmin): list_filter = ('repo', 'arch') search_fields = ('pkgname',) +class TodolistAdmin(admin.ModelAdmin): + list_display = ('name', 'date_added', 'creator', 'description') + search_fields = ('name', 'description') + admin.site.unregister(User) class UserProfileInline(admin.StackedInline): model = UserProfile @@ -40,4 +44,6 @@ admin.site.register(Package, PackageAdmin) admin.site.register(Arch, ArchAdmin) admin.site.register(Repo, RepoAdmin) +admin.site.register(Todolist, TodolistAdmin) + # vim: set ts=4 sw=4 et: -- cgit v1.2.3-2-g168b From 97437d27b7b3d01bfd2e2ae628e6612c149324b4 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 16 Feb 2011 18:09:46 -0600 Subject: Add new package parts models This allows us to store conflicts, provisions (provides), and replacements in the database, things we weren't capturing before. All can be multivalued, just like License and PackageGroup. Signed-off-by: Dan McGee --- ...add_provision__add_conflict__add_replacement.py | 167 +++++++++++++++++++++ packages/models.py | 44 ++++++ 2 files changed, 211 insertions(+) create mode 100644 packages/migrations/0006_auto__add_provision__add_conflict__add_replacement.py diff --git a/packages/migrations/0006_auto__add_provision__add_conflict__add_replacement.py b/packages/migrations/0006_auto__add_provision__add_conflict__add_replacement.py new file mode 100644 index 00000000..c764ce77 --- /dev/null +++ b/packages/migrations/0006_auto__add_provision__add_conflict__add_replacement.py @@ -0,0 +1,167 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'Provision' + db.create_table('packages_provision', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('pkg', self.gf('django.db.models.fields.related.ForeignKey')(related_name='provides', to=orm['main.Package'])), + ('name', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)), + ('version', self.gf('django.db.models.fields.CharField')(default='', max_length=255)), + )) + db.send_create_signal('packages', ['Provision']) + + # Adding model 'Conflict' + db.create_table('packages_conflict', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('pkg', self.gf('django.db.models.fields.related.ForeignKey')(related_name='conflicts', to=orm['main.Package'])), + ('name', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)), + ('comparison', self.gf('django.db.models.fields.CharField')(default='', max_length=255)), + ('version', self.gf('django.db.models.fields.CharField')(default='', max_length=255)), + )) + db.send_create_signal('packages', ['Conflict']) + + # Adding model 'Replacement' + db.create_table('packages_replacement', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('pkg', self.gf('django.db.models.fields.related.ForeignKey')(related_name='replaces', to=orm['main.Package'])), + ('name', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)), + ('comparison', self.gf('django.db.models.fields.CharField')(default='', max_length=255)), + ('version', self.gf('django.db.models.fields.CharField')(default='', max_length=255)), + )) + db.send_create_signal('packages', ['Replacement']) + + + def backwards(self, orm): + # Deleting model 'Provision' + db.delete_table('packages_provision') + # Deleting model 'Conflict' + db.delete_table('packages_conflict') + # Deleting model 'Replacement' + db.delete_table('packages_replacement') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + '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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + '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'}), + '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'}) + }, + 'main.arch': { + 'Meta': {'ordering': "['name']", 'object_name': 'Arch', 'db_table': "'arches'"}, + 'agnostic': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}) + }, + 'main.package': { + 'Meta': {'ordering': "('pkgname',)", 'object_name': 'Package', 'db_table': "'packages'"}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'to': "orm['main.Arch']"}), + 'build_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'compressed_size': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}), + 'epoch': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'files_last_update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'flag_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'installed_size': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}), + 'last_update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'packager': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}), + 'packager_str': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'pkgdesc': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'pkgrel': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgver': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'to': "orm['main.Repo']"}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}) + }, + 'main.repo': { + 'Meta': {'ordering': "['name']", 'object_name': 'Repo', 'db_table': "'repos'"}, + 'bugs_project': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}), + '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'}) + }, + 'packages.conflict': { + 'Meta': {'ordering': "['name']", 'object_name': 'Conflict'}, + 'comparison': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'conflicts'", 'to': "orm['main.Package']"}), + 'version': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}) + }, + 'packages.license': { + 'Meta': {'ordering': "['name']", 'object_name': 'License'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'licenses'", 'to': "orm['main.Package']"}) + }, + 'packages.packagegroup': { + 'Meta': {'object_name': 'PackageGroup'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'groups'", 'to': "orm['main.Package']"}) + }, + 'packages.packagerelation': { + 'Meta': {'unique_together': "(('pkgbase', 'user', 'type'),)", 'object_name': 'PackageRelation'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'type': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'package_relations'", 'to': "orm['auth.User']"}) + }, + 'packages.provision': { + 'Meta': {'ordering': "['name']", 'object_name': 'Provision'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'provides'", 'to': "orm['main.Package']"}), + 'version': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}) + }, + 'packages.replacement': { + 'Meta': {'ordering': "['name']", 'object_name': 'Replacement'}, + 'comparison': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'replaces'", 'to': "orm['main.Package']"}), + 'version': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}) + } + } + + complete_apps = ['packages'] diff --git a/packages/models.py b/packages/models.py index 5dbdea45..63a7255b 100644 --- a/packages/models.py +++ b/packages/models.py @@ -57,6 +57,50 @@ class License(models.Model): class Meta: ordering = ['name'] +class Conflict(models.Model): + pkg = models.ForeignKey('main.Package', related_name='conflicts') + name = models.CharField(max_length=255, db_index=True) + comparison = models.CharField(max_length=255, default='') + version = models.CharField(max_length=255, default='') + + def __unicode__(self): + if self.version: + return u'%s%s%s' % (self.name, self.comparison, self.version) + return self.name + + class Meta: + ordering = ['name'] + +class Provision(models.Model): + pkg = models.ForeignKey('main.Package', related_name='provides') + name = models.CharField(max_length=255, db_index=True) + # comparison must be '=' for provides + comparison = '=' + version = models.CharField(max_length=255, default='') + + def __unicode__(self): + if self.version: + return u'%s=%s' % (self.name, self.version) + return self.name + + class Meta: + ordering = ['name'] + +class Replacement(models.Model): + pkg = models.ForeignKey('main.Package', related_name='replaces') + name = models.CharField(max_length=255, db_index=True) + comparison = models.CharField(max_length=255, default='') + version = models.CharField(max_length=255, default='') + + def __unicode__(self): + if self.version: + return u'%s%s%s' % (self.name, self.comparison, self.version) + return self.name + + class Meta: + ordering = ['name'] + + def remove_inactive_maintainers(sender, instance, created, **kwargs): # instance is an auth.models.User; we want to remove any existing # maintainer relations if the user is no longer active -- cgit v1.2.3-2-g168b From 857cae2e96aa0d23b0702d5ad9db572787f657a9 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 16 Feb 2011 18:22:14 -0600 Subject: reporead: refactor multivalued attribute creation This will come in more handy with our new models, but we can adapt groups and licenses to use it first. Signed-off-by: Dan McGee --- devel/management/commands/reporead.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/devel/management/commands/reporead.py b/devel/management/commands/reporead.py index 231cad01..0c835555 100644 --- a/devel/management/commands/reporead.py +++ b/devel/management/commands/reporead.py @@ -188,6 +188,17 @@ def create_depend(package, dep_str, optional=False): depend.save(force_insert=True) return depend +def create_multivalued(dbpkg, repopkg, db_attr, repo_attr): + '''Populate the simplest of multivalued attributes. These are those that + only deal with a 'name' attribute, such as licenses, groups, etc. The input + and output objects and attribute names are specified, and everything is + done via hasattr()/getattr().''' + collection = getattr(dbpkg, db_attr) + collection.all().delete() + if hasattr(repopkg, repo_attr): + for name in getattr(repopkg, repo_attr): + collection.create(name=name) + def populate_pkg(dbpkg, repopkg, force=False, timestamp=None): if repopkg.base: dbpkg.pkgbase = repopkg.base @@ -229,15 +240,8 @@ def populate_pkg(dbpkg, repopkg, force=False, timestamp=None): for y in repopkg.optdepends: dep = create_depend(dbpkg, y, True) - dbpkg.groups.all().delete() - if hasattr(repopkg, 'groups'): - for y in repopkg.groups: - dbpkg.groups.create(name=y) - - dbpkg.licenses.all().delete() - if hasattr(repopkg, 'license'): - for y in repopkg.license: - dbpkg.licenses.create(name=y) + create_multivalued(dbpkg, repopkg, 'groups', 'groups') + create_multivalued(dbpkg, repopkg, 'licenses', 'license') def populate_files(dbpkg, repopkg, force=False): -- cgit v1.2.3-2-g168b From 1942a9da6c8165c10c0914bcab522a59d15a1cc5 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 23 Mar 2011 16:43:10 -0500 Subject: Fix package group unicode method --- packages/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/models.py b/packages/models.py index 63a7255b..79e8abca 100644 --- a/packages/models.py +++ b/packages/models.py @@ -45,7 +45,7 @@ class PackageGroup(models.Model): name = models.CharField(max_length=255) def __unicode__(self): - return "%s: %s" % (name, pkg) + return "%s: %s" % (self.name, self.pkg) class License(models.Model): pkg = models.ForeignKey('main.Package', related_name='licenses') -- cgit v1.2.3-2-g168b From 151eafb0192957c489fa5b8010c081eb6db5f925 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 23 Mar 2011 16:43:39 -0500 Subject: Remove need to import each individual logger constant Signed-off-by: Dan McGee --- devel/management/commands/reporead.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/devel/management/commands/reporead.py b/devel/management/commands/reporead.py index 0c835555..8ce6eab8 100644 --- a/devel/management/commands/reporead.py +++ b/devel/management/commands/reporead.py @@ -35,12 +35,10 @@ try: except ImportError: pass -from logging import ERROR, WARNING, INFO, DEBUG - from main.models import Arch, Package, PackageDepend, PackageFile, Repo logging.basicConfig( - level=WARNING, + level=logging.WARNING, format='%(asctime)s -> %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', stream=sys.stderr) @@ -69,11 +67,11 @@ class Command(BaseCommand): v = int(options.get('verbosity', 0)) if v == 0: - logger.level = ERROR + logger.level = logging.ERROR elif v == 1: - logger.level = INFO + logger.level = logging.INFO elif v == 2: - logger.level = DEBUG + logger.level = logging.DEBUG import signal, traceback handler = lambda sig, stack: traceback.print_stack(stack) -- cgit v1.2.3-2-g168b From d6b148779f3a1119e30fa75c63a2a0e46938098c Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 23 Mar 2011 16:44:17 -0500 Subject: reporead: read in provisions, conflicts, and replacements Signed-off-by: Dan McGee --- devel/management/commands/reporead.py | 45 ++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/devel/management/commands/reporead.py b/devel/management/commands/reporead.py index 8ce6eab8..708b8a59 100644 --- a/devel/management/commands/reporead.py +++ b/devel/management/commands/reporead.py @@ -36,6 +36,7 @@ except ImportError: pass from main.models import Arch, Package, PackageDepend, PackageFile, Repo +from packages.models import Conflict, Provision, Replacement logging.basicConfig( level=logging.WARNING, @@ -172,20 +173,48 @@ def find_user(userstring): # lookup more than strictly necessary. find_user.cache = {} +DEPEND_RE = re.compile(r"^(.+?)((>=|<=|=|>|<)(.*))?$") + def create_depend(package, dep_str, optional=False): depend = PackageDepend(pkg=package, optional=optional) # lop off any description first parts = dep_str.split(':', 1) if len(parts) > 1: depend.description = parts[1].strip() - match = re.match(r"^(.+?)((>=|<=|=|>|<)(.*))?$", parts[0].strip()) + match = DEPEND_RE.match(parts[0].strip()) if match: depend.depname = match.group(1) if match.group(2): depend.depvcmp = match.group(2) + else: + logger.warning('Package %s had unparsable depend string %s', + package.pkgname, dep_str) + return None depend.save(force_insert=True) return depend +def create_related(model, package, rel_str, equals_only=False): + related = model(pkg=package) + match = DEPEND_RE.match(rel_str) + if match: + related.name = match.group(1) + if match.group(3): + comp = match.group(3) + if not equals_only: + related.comparison = comp + elif comp != '=': + logger.warning( + 'Package %s had unexpected comparison operator %s for %s in %s', + package.pkgname, comp, model.__name__, rel_str) + if match.group(4): + related.version = match.group(4) + else: + logger.warning('Package %s had unparsable %s string %s', + package.pkgname, model.___name__, rel_str) + return None + related.save(force_insert=True) + return related + def create_multivalued(dbpkg, repopkg, db_attr, repo_attr): '''Populate the simplest of multivalued attributes. These are those that only deal with a 'name' attribute, such as licenses, groups, etc. The input @@ -233,10 +262,20 @@ def populate_pkg(dbpkg, repopkg, force=False, timestamp=None): dbpkg.packagedepend_set.all().delete() if hasattr(repopkg, 'depends'): for y in repopkg.depends: - dep = create_depend(dbpkg, y) + create_depend(dbpkg, y) if hasattr(repopkg, 'optdepends'): for y in repopkg.optdepends: - dep = create_depend(dbpkg, y, True) + create_depend(dbpkg, y, True) + + if hasattr(repopkg, 'conflicts'): + for y in repopkg.conflicts: + create_related(Conflict, dbpkg, y) + if hasattr(repopkg, 'provides'): + for y in repopkg.provides: + create_related(Provision, dbpkg, y, equals_only=True) + if hasattr(repopkg, 'replaces'): + for y in repopkg.replaces: + create_related(Replacement, dbpkg, y) create_multivalued(dbpkg, repopkg, 'groups', 'groups') create_multivalued(dbpkg, repopkg, 'licenses', 'license') -- cgit v1.2.3-2-g168b From dad2ca8b3e42cbf0ad5a67be7016426ec4835a19 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 23 Mar 2011 20:19:00 -0500 Subject: Clear out package relation sets before adding new values Signed-off-by: Dan McGee --- devel/management/commands/reporead.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/devel/management/commands/reporead.py b/devel/management/commands/reporead.py index 708b8a59..277196e2 100644 --- a/devel/management/commands/reporead.py +++ b/devel/management/commands/reporead.py @@ -267,12 +267,15 @@ def populate_pkg(dbpkg, repopkg, force=False, timestamp=None): for y in repopkg.optdepends: create_depend(dbpkg, y, True) + dbpkg.conflicts.all().delete() if hasattr(repopkg, 'conflicts'): for y in repopkg.conflicts: create_related(Conflict, dbpkg, y) + dbpkg.provides.all().delete() if hasattr(repopkg, 'provides'): for y in repopkg.provides: create_related(Provision, dbpkg, y, equals_only=True) + dbpkg.replaces.all().delete() if hasattr(repopkg, 'replaces'): for y in repopkg.replaces: create_related(Replacement, dbpkg, y) -- cgit v1.2.3-2-g168b From ca370499d863dc2ce86fbeb26cf810d3808239f6 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 23 Mar 2011 20:32:55 -0500 Subject: reporead: remove the need for hasattr() checks Ensure all our multivalued attributes already exist on the object beforehand, and add some special sauce to handle the difference between a package without files and a database without files entries. Signed-off-by: Dan McGee --- devel/management/commands/reporead.py | 51 ++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/devel/management/commands/reporead.py b/devel/management/commands/reporead.py index 277196e2..35bb7da3 100644 --- a/devel/management/commands/reporead.py +++ b/devel/management/commands/reporead.py @@ -87,6 +87,9 @@ class Pkg(object): bare = ( 'name', 'base', 'arch', 'desc', 'filename', 'md5sum', 'url', 'builddate', 'packager' ) number = ( 'csize', 'isize' ) + collections = ( 'depends', 'optdepends', 'conflicts', + 'replaces', 'groups', 'license', 'files' ) + version_re = re.compile(r'^((\d+):)?(.+)-([^-]+)$') def __init__(self, repo): @@ -96,6 +99,11 @@ class Pkg(object): self.epoch = 0 for k in self.bare + self.number: setattr(self, k, None) + for k in self.collections: + setattr(self, k, ()) + # So we can tell the diffence between a package with no files, and a DB + # without files entries + self.has_files = False def populate(self, values): for k, v in values.iteritems(): @@ -104,16 +112,17 @@ class Pkg(object): setattr(self, k, v[0][:254]) elif k in self.number: setattr(self, k, long(v[0])) - elif k == 'force': - setattr(self, k, True) elif k == 'version': match = self.version_re.match(v[0]) self.ver = match.group(3) self.rel = match.group(4) if match.group(2): self.epoch = int(match.group(2)) + elif k == 'files': + self.files = v + self.has_files = True else: - # files, depends, etc. + # anything left in collections setattr(self, k, v) @property @@ -219,12 +228,11 @@ def create_multivalued(dbpkg, repopkg, db_attr, repo_attr): '''Populate the simplest of multivalued attributes. These are those that only deal with a 'name' attribute, such as licenses, groups, etc. The input and output objects and attribute names are specified, and everything is - done via hasattr()/getattr().''' + done via getattr().''' collection = getattr(dbpkg, db_attr) collection.all().delete() - if hasattr(repopkg, repo_attr): - for name in getattr(repopkg, repo_attr): - collection.create(name=name) + for name in getattr(repopkg, repo_attr): + collection.create(name=name) def populate_pkg(dbpkg, repopkg, force=False, timestamp=None): if repopkg.base: @@ -260,25 +268,20 @@ def populate_pkg(dbpkg, repopkg, force=False, timestamp=None): populate_files(dbpkg, repopkg, force=force) dbpkg.packagedepend_set.all().delete() - if hasattr(repopkg, 'depends'): - for y in repopkg.depends: - create_depend(dbpkg, y) - if hasattr(repopkg, 'optdepends'): - for y in repopkg.optdepends: - create_depend(dbpkg, y, True) + for y in repopkg.depends: + create_depend(dbpkg, y) + for y in repopkg.optdepends: + create_depend(dbpkg, y, True) dbpkg.conflicts.all().delete() - if hasattr(repopkg, 'conflicts'): - for y in repopkg.conflicts: - create_related(Conflict, dbpkg, y) + for y in repopkg.conflicts: + create_related(Conflict, dbpkg, y) dbpkg.provides.all().delete() - if hasattr(repopkg, 'provides'): - for y in repopkg.provides: - create_related(Provision, dbpkg, y, equals_only=True) + for y in repopkg.provides: + create_related(Provision, dbpkg, y, equals_only=True) dbpkg.replaces.all().delete() - if hasattr(repopkg, 'replaces'): - for y in repopkg.replaces: - create_related(Replacement, dbpkg, y) + for y in repopkg.replaces: + create_related(Replacement, dbpkg, y) create_multivalued(dbpkg, repopkg, 'groups', 'groups') create_multivalued(dbpkg, repopkg, 'licenses', 'license') @@ -297,7 +300,7 @@ def populate_files(dbpkg, repopkg, force=False): elif dbpkg.files_last_update > dbpkg.last_update: return # only delete files if we are reading a DB that contains them - if hasattr(repopkg, 'files'): + if repopkg.has_files: dbpkg.packagefile_set.all().delete() logger.info("adding %d files for package %s", len(repopkg.files), dbpkg.pkgname) @@ -311,7 +314,7 @@ def populate_files(dbpkg, repopkg, force=False): is_directory=(filename is None), directory=dirname + '/', filename=filename) - pkgfile.save() + pkgfile.save(force_insert=True) dbpkg.files_last_update = datetime.now() dbpkg.save() -- cgit v1.2.3-2-g168b From 73ea5b8abe5de6457834c2981efaa70985dfa3e6 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 24 Mar 2011 00:43:15 -0500 Subject: Remove dead merchandise link Addresses FS#23399. Signed-off-by: Dan McGee --- templates/public/index.html | 2 -- 1 file changed, 2 deletions(-) diff --git a/templates/public/index.html b/templates/public/index.html index 91a8414c..1f4b2ce5 100644 --- a/templates/public/index.html +++ b/templates/public/index.html @@ -133,8 +133,6 @@ title="T-shirts, mugs, mouse pads, hoodies, posters, skateboards, shoes, etc.">Products via Zazzle
  • T-shirts via Freewear
  • -
  • Merchandise via ProstoPrint
  • Tools

    -- cgit v1.2.3-2-g168b From f6464da0e14047e9db803f4b40c18ba644e75f24 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 24 Mar 2011 00:47:23 -0500 Subject: Add provides to collections list Signed-off-by: Dan McGee --- devel/management/commands/reporead.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devel/management/commands/reporead.py b/devel/management/commands/reporead.py index 35bb7da3..e26bb800 100644 --- a/devel/management/commands/reporead.py +++ b/devel/management/commands/reporead.py @@ -88,7 +88,7 @@ class Pkg(object): 'md5sum', 'url', 'builddate', 'packager' ) number = ( 'csize', 'isize' ) collections = ( 'depends', 'optdepends', 'conflicts', - 'replaces', 'groups', 'license', 'files' ) + 'provides', 'replaces', 'groups', 'license', 'files' ) version_re = re.compile(r'^((\d+):)?(.+)-([^-]+)$') -- cgit v1.2.3-2-g168b