From fd5f402d955c38ba1e739b9bf98e918e336e2089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Sun, 4 Sep 2016 14:32:10 +0200 Subject: [PATCH] add package dependencies --- .../migrations/0002_package_depends.py | 20 +++++++++++++++++ src/c3nav/mapdata/models/package.py | 8 +++++++ src/c3nav/mapdata/packageio/utils.py | 22 +++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 src/c3nav/mapdata/migrations/0002_package_depends.py diff --git a/src/c3nav/mapdata/migrations/0002_package_depends.py b/src/c3nav/mapdata/migrations/0002_package_depends.py new file mode 100644 index 00000000..ffe5c02e --- /dev/null +++ b/src/c3nav/mapdata/migrations/0002_package_depends.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.9 on 2016-09-04 12:20 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mapdata', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='package', + name='depends', + field=models.ManyToManyField(to='mapdata.Package'), + ), + ] diff --git a/src/c3nav/mapdata/models/package.py b/src/c3nav/mapdata/models/package.py index 168780e8..c7543a30 100644 --- a/src/c3nav/mapdata/models/package.py +++ b/src/c3nav/mapdata/models/package.py @@ -10,6 +10,7 @@ class Package(models.Model): """ name = models.CharField(_('package identifier'), unique=True, max_length=50, help_text=_('e.g. de.c3nav.33c3.base')) + depends = models.ManyToManyField('Package') bottom = models.DecimalField(_('bottom coordinate'), null=True, max_digits=6, decimal_places=2) left = models.DecimalField(_('left coordinate'), null=True, max_digits=6, decimal_places=2) @@ -28,6 +29,11 @@ class Package(models.Model): raise ValueError('pkg.json: missing package name.') kwargs['name'] = data['name'] + depends = data.get('depends', []) + if not isinstance(depends, list): + raise TypeError('pkg.json: depends has to be a list') + kwargs['depends'] = depends + if 'bounds' in data: bounds = data['bounds'] if len(bounds) != 2 or len(bounds[0]) != 2 or len(bounds[1]) != 2: @@ -49,5 +55,7 @@ class Package(models.Model): data['name'] = self.name if self.bottom is not None: data['bounds'] = ((float(self.bottom), float(self.left)), (float(self.top), float(self.right))) + if self.depends.exists(): + data['depends'] = tuple(package.name for package in self.depends.all().order_by('name')) return data diff --git a/src/c3nav/mapdata/packageio/utils.py b/src/c3nav/mapdata/packageio/utils.py index c39cd0f5..10143050 100644 --- a/src/c3nav/mapdata/packageio/utils.py +++ b/src/c3nav/mapdata/packageio/utils.py @@ -39,7 +39,15 @@ class ObjectCollection: def apply_to_db(self): for name, package in tuple(self.packages.items()): + for depname in package['depends']: + if depname not in self.packages: + raise CommandError('Missing dependency: %s' % depname) + + for name, package in tuple(self.packages.items()): + package = package.copy() + orig_deps = package.pop('depends', []) package, created = Package.objects.update_or_create(name=name, defaults=package) + package.orig_deps = orig_deps self.packages[name] = package if created: print('- Created package: '+name) @@ -70,6 +78,20 @@ class ObjectCollection: print('- Deleted package: '+package.name) package.delete() + for name, package in tuple(self.packages.items()): + has_deps = [] + for dependency in tuple(package.depends.all()): + if dependency.name not in package.orig_deps: + package.depends.remove(dependency) + print('- Removed dependency: '+dependency.name) + else: + has_deps.append(dependency.name) + + for depname in package.orig_deps: + if depname not in has_deps: + package.depends.add(self.packages[depname]) + print('- Added dependency: '+depname) + def _preencode(data, magic_marker): if isinstance(data, dict):