From b94bcf3b02b95d156e3799f92e876d4ce466eb47 Mon Sep 17 00:00:00 2001 From: Tyrel Souza Date: Tue, 1 Sep 2015 00:47:56 -0400 Subject: [PATCH] Add more migrations, import working. --- requirements.txt | 2 +- tracking/management/commands/import_gpx.py | 70 ++++++++++++++-------- tracking/migrations/0003_track_user.py | 22 +++++++ tracking/migrations/0004_segment_number.py | 19 ++++++ tracking/migrations/0005_segment_time.py | 21 +++++++ tracking/models.py | 11 +++- 6 files changed, 117 insertions(+), 28 deletions(-) create mode 100644 tracking/migrations/0003_track_user.py create mode 100644 tracking/migrations/0004_segment_number.py create mode 100644 tracking/migrations/0005_segment_time.py diff --git a/requirements.txt b/requirements.txt index fce310e..48147f9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ Django==1.8.4 django-extensions coverage -gpxpy \ No newline at end of file +xmltodict \ No newline at end of file diff --git a/tracking/management/commands/import_gpx.py b/tracking/management/commands/import_gpx.py index 30dd9b5..649871d 100644 --- a/tracking/management/commands/import_gpx.py +++ b/tracking/management/commands/import_gpx.py @@ -2,7 +2,8 @@ __author__ = 'tyrel' from django.core.management.base import BaseCommand, CommandError from django.contrib.auth.models import User from tracking.models import Track, Segment, Point -import gpxpy +import xmltodict + import os @@ -14,43 +15,62 @@ class Command(BaseCommand): parser.add_argument('filepath', help="File or directory to import a gpx file.") def handle(self, *args, **options): - username = options['username'] + self.username = options['username'] filepath = options['filepath'] - try: - user = User.objects.get(username=username) - except User.DoesNotExist: - raise CommandError("User %s does not exist" % username) - self.stdout.write("Importing for user %s" % user.username) + try: + self.user = User.objects.get(username=self.username) + except User.DoesNotExist: + raise CommandError("User {0} does not exist".format(self.username)) if os.path.isdir(filepath): - self.import_directory(user, filepath) + self.import_directory(filepath) elif os.path.isfile(filepath): - self.import_file(user, filepath) + self.import_file(filepath) else: raise CommandError("{0} is neither an existing file, nor a path.".format(filepath)) - - def import_file(self, user, filename): - with open(filename, 'r') as f: - gpx = gpxpy.parse(f) - - for g_track in gpx.tracks: - for g_segment in g_track.segments: - for g_point in g_segment.points: - print 'Point at ({0},{1}) -> {2} -> {3}'.format(g_point.latitude, g_point.longitude, g_point.elevation) - - - - - def import_directory(self, user, directory): + def import_directory(self, directory): pass + def import_file(self, filename): + with open(filename) as fd: + obj = dict(xmltodict.parse(fd.read()))['gpx'] + + metadata = obj['metadata'] + tracks = obj['trk'] + + start_time = metadata['time'] + + name = tracks['name'] + segments = tracks['trkseg'] + if isinstance(segments, list): + raise NotImplemented( + "Haven't run across one that has multiple segments. " + "Contribute a patch if you have.") + elif isinstance(segments, dict): + track = Track.objects.create(user=self.user, + start=start_time, + name=name) + points = segments['trkpt'] + segment = Segment(track=track, time=points[0]['time']) + segment.save() + for pt in points: + Point.objects.create(segment=segment, + time=pt['time'], + elevation=pt['ele'], + latitude=pt['@lat'], + longitude=pt['@lon']) + print "created Track <{0}> start: {1}, stop: {2}".format( + track.name, + track.start, + track.finish + ) def etree_to_dict(t): - d = {t.tag : map(etree_to_dict, t.getchildren())} + d = {t.tag: map(etree_to_dict, t.getchildren())} d.update(('@' + k, v) for k, v in t.attrib.iteritems()) d['text'] = t.text - return d \ No newline at end of file + return d diff --git a/tracking/migrations/0003_track_user.py b/tracking/migrations/0003_track_user.py new file mode 100644 index 0000000..b5b9608 --- /dev/null +++ b/tracking/migrations/0003_track_user.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('tracking', '0002_auto_20150901_0355'), + ] + + operations = [ + migrations.AddField( + model_name='track', + name='user', + field=models.ForeignKey(default=None, to=settings.AUTH_USER_MODEL), + preserve_default=False, + ), + ] diff --git a/tracking/migrations/0004_segment_number.py b/tracking/migrations/0004_segment_number.py new file mode 100644 index 0000000..eb221d6 --- /dev/null +++ b/tracking/migrations/0004_segment_number.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('tracking', '0003_track_user'), + ] + + operations = [ + migrations.AddField( + model_name='segment', + name='number', + field=models.IntegerField(default=1), + ), + ] diff --git a/tracking/migrations/0005_segment_time.py b/tracking/migrations/0005_segment_time.py new file mode 100644 index 0000000..8984e35 --- /dev/null +++ b/tracking/migrations/0005_segment_time.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import datetime + + +class Migration(migrations.Migration): + + dependencies = [ + ('tracking', '0004_segment_number'), + ] + + operations = [ + migrations.AddField( + model_name='segment', + name='time', + field=models.DateTimeField(default=datetime.datetime(2015, 9, 1, 0, 43, 4, 754000)), + preserve_default=False, + ), + ] diff --git a/tracking/models.py b/tracking/models.py index c155196..eb24097 100644 --- a/tracking/models.py +++ b/tracking/models.py @@ -1,19 +1,26 @@ from django.db import models - # Create your models here. +from django.contrib.auth.models import User class Track(models.Model): + user = models.ForeignKey(User, blank=False) start = models.DateTimeField() name = models.CharField(max_length=1024, blank=False) description = models.TextField(blank=True) @property def finish(self): - return self.point_set.order_by("-time")[0].time + return self.segment_set.order_by("-time")[0].finish class Segment(models.Model): track = models.ForeignKey(Track) + time = models.DateTimeField() + number = models.IntegerField(default=1) + + @property + def finish(self): + return self.point_set.order_by("-time")[0].time class Point(models.Model): time = models.DateTimeField()