Merge lp:~daker/loco-team-portal/fix.import-live-data into lp:loco-team-portal

Proposed by Adnane Belmadiaf
Status: Merged
Approved by: Adnane Belmadiaf
Approved revision: 571
Merged at revision: 573
Proposed branch: lp:~daker/loco-team-portal/fix.import-live-data
Merge into: lp:loco-team-portal
Diff against target: 259 lines (+130/-120)
2 files modified
loco_directory/common/management/commands/import-live-data.py (+130/-0)
loco_directory/teams/management/commands/import-live-data.py (+0/-120)
To merge this branch: bzr merge lp:~daker/loco-team-portal/fix.import-live-data
Reviewer Review Type Date Requested Status
LoCo Team Portal Developers Pending
Review via email: mp+138338@code.launchpad.net

Commit message

An improved version of the import-live-data command, props ronnie

To post a comment you must log in.
571. By Adnane Belmadiaf

Minor fix

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'loco_directory/common/management/commands/import-live-data.py'
2--- loco_directory/common/management/commands/import-live-data.py 1970-01-01 00:00:00 +0000
3+++ loco_directory/common/management/commands/import-live-data.py 2012-12-05 23:30:29 +0000
4@@ -0,0 +1,130 @@
5+#!/usr/bin/python
6+# -*- coding: utf-8 -*-
7+from django.core.management.base import NoArgsCommand
8+from django.contrib.auth.models import User, Group
9+from django.db.models.fields import DateTimeField, DateField
10+
11+from meetings.models import BaseMeeting, TeamMeeting, AgendaItem
12+from events.models import BaseEvent, GlobalEvent, TeamEvent, TeamEventComment, Attendee
13+from teams.models import Language, Continent, Country, Team
14+from venues.models import Venue
15+from userprofiles.models import UserProfile
16+
17+import urllib2
18+import json
19+import re
20+import os
21+import sys
22+import subprocess
23+import time
24+
25+ORDER = [('languages', Language),
26+ ('continents', Continent),
27+ ('countries', Country),
28+ ('venues', Venue),
29+ ('global', GlobalEvent),
30+ ('groups', Group),
31+ ('users', User),
32+ ('profiles', UserProfile),
33+ ('teams', Team),
34+ ('events', TeamEvent),
35+ ('comments', TeamEventComment),
36+ ('attendees', Attendee),
37+ ('meeting', TeamMeeting),
38+ ('agenda', AgendaItem),
39+ ]
40+
41+date_pattern1 = re.compile('^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$')
42+date_pattern2 = re.compile('^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d+$')
43+
44+
45+def get_field_data(model, model_data):
46+ fields = {}
47+ for field in model._meta.fields:
48+ field_value = model_data.get(field.name, None)
49+ if field_value:
50+ if isinstance(field, DateTimeField):
51+ if date_pattern1.match(field_value):
52+ fields[field.name] = field_value
53+ elif date_pattern2.match(field_value):
54+ fields[field.name] = field_value.split('.')[0]
55+ elif isinstance(field, DateField):
56+ if date_pattern1.match(field_value) or date_pattern2.match(field_value):
57+ fields[field.name] = field_value.split(' ')[0]
58+ else:
59+ fields[field.name] = field_value
60+ for field in model._meta.many_to_many:
61+ fields[field.name] = model_data.get(field.name, [])
62+ return fields
63+
64+
65+class Command(NoArgsCommand):
66+ help = "Copy the live data to the local instance"
67+
68+ def handle_noargs(self, **options):
69+ t1 = time.time()
70+ # Save the super user, so it can be restored later
71+ super_user = None
72+ try:
73+ super_user = User.objects.get(pk=1)
74+ except:
75+ pass
76+
77+ # Delete all old data, so the id's do not conflict when linking
78+ print "Removing local data from database."
79+
80+ for service, model in ORDER:
81+ model.objects.all().delete()
82+
83+ loaddata_json = []
84+ services_url = 'http://loco.ubuntu.com/services/'
85+
86+ for service, model in ORDER:
87+ # Get the json data from the server
88+ print "Getting %s." % service
89+ json_data = urllib2.urlopen("%s%s" % (services_url, service)).read()
90+
91+ for model_data in json.loads(json_data):
92+ loaddata_json.append({'pk': model_data['id'],
93+ 'model': str(model._meta),
94+ 'fields': get_field_data(model, model_data)})
95+
96+ # GlobalEvent, TeamEvent are a subclass of BaseEvent, so we need to create the BaseEvent also
97+ if model in [GlobalEvent, TeamEvent]:
98+ loaddata_json.append({'pk': model_data['id'],
99+ 'model': str(BaseEvent._meta),
100+ 'fields': get_field_data(BaseEvent, model_data)})
101+
102+ # TeamMeeting is a subclass of BaseMeeting, so we need to create the BaseMeeting also
103+ if model is TeamMeeting:
104+ loaddata_json.append({'pk': model_data['id'],
105+ 'model': str(BaseMeeting._meta),
106+ 'fields': get_field_data(BaseMeeting, model_data)})
107+
108+ print "Storing data into a json file."
109+ f = open('livedata.json', 'w')
110+ f.write(json.dumps(loaddata_json))
111+ f.close()
112+
113+ print "Loading data into database."
114+ p = subprocess.Popen([sys.executable, 'manage.py', 'loaddata', 'livedata.json'],
115+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
116+ log = p.stdout.read()
117+ p.communicate()
118+ print "%s" % log
119+
120+ os.remove('livedata.json')
121+
122+ # Restore the super user
123+ if super_user:
124+ print"Restoring the super user."
125+ old_su = super_user.__dict__
126+ del old_su['id']
127+ if old_su.__contains__('_state'):
128+ del old_su['_state']
129+ new_su, created = User.objects.get_or_create(username=old_su['username'])
130+ new_su.__dict__.update(old_su)
131+ new_su.save()
132+
133+ t2 = time.time()
134+ print "It took %0fsec to finish" % (t2 - t1)
135
136=== removed file 'loco_directory/teams/management/commands/import-live-data.py'
137--- loco_directory/teams/management/commands/import-live-data.py 2011-02-18 04:34:02 +0000
138+++ loco_directory/teams/management/commands/import-live-data.py 1970-01-01 00:00:00 +0000
139@@ -1,120 +0,0 @@
140-#!/usr/bin/python
141-
142-from django.core.management.base import NoArgsCommand
143-from django.contrib.auth.models import User, Group
144-from meetings.models import TeamMeeting, AgendaItem
145-from events.models import GlobalEvent, TeamEvent, TeamEventComment, Attendee
146-from teams.models import Language, Continent, Country, Team
147-from venues.models import Venue
148-from userprofiles.models import UserProfile
149-
150-import sys
151-import urllib2
152-import json
153-import datetime
154-import re
155-
156-ORDER = [('languages', Language),
157- ('continents', Continent),
158- ('countries', Country),
159- ('venues', Venue),
160- ('global', GlobalEvent),
161- ('groups', Group),
162- ('users', User),
163- ('profiles', UserProfile),
164- ('teams', Team),
165- ('events', TeamEvent),
166- ('comments', TeamEventComment),
167- ('attendees', Attendee),
168- ('meeting', TeamMeeting),
169- ('agenda', AgendaItem),
170- ]
171-
172-
173-class Command(NoArgsCommand):
174- help = "Copy the live data to the local instance"
175-
176- def handle_noargs(self, **options):
177- # Save the super user, so it can be restored later
178- super_user = None
179- try:
180- super_user = User.objects.get(pk=1)
181- except:
182- pass
183-
184- # Delete all old data, so the id's do not conflict when linking
185- print 'Removing local data from database...'
186- for service, Model in ORDER:
187- Model.objects.all().delete()
188-
189- services_url = 'http://loco.ubuntu.com/services/'
190- date_pattern1 = re.compile('^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$')
191- date_pattern2 = re.compile('^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d+$')
192-
193- for service, Model in ORDER:
194- # Get the json data from the server
195- print 'Getting', service, '...'
196- json_data = urllib2.urlopen(services_url+service).read()
197-
198- # Find out what fields are normal, and which many_to_many
199- local_fields = Model._meta.fields
200- many_to_many = Model._meta.many_to_many
201-
202- for entry in json.loads(json_data):
203- # Create the model without the many_to_many fields
204- params = {}
205- for field in local_fields:
206- if entry.has_key(field.name):
207- field_value = entry[field.name]
208- if field_value == None:
209- if field.null == True:
210- # If field on the server is None, but None is not allowed, get the default value
211- field_value = field.get_default()
212- else:
213- # If the field is a related, grab the object with that id
214- if field.rel:
215- rel_model = field.rel.to
216- try:
217- params[field.name] = rel_model.objects.get(pk=field_value)
218- except rel_model.DoesNotExist:
219- print '%(model)s with pk=%(pk)s does not exists' % ({'model':rel_model._meta.object_name, 'pk':field_value})
220- # Else if it is a date, create a date object
221- elif isinstance(field_value, unicode) and date_pattern1.match(field_value):
222- params[field.name] = datetime.datetime.strptime(field_value, '%Y-%m-%d %H:%M:%S')
223- elif isinstance(field_value, unicode) and date_pattern2.match(field_value):
224- params[field.name] = datetime.datetime.strptime(field_value, '%Y-%m-%d %H:%M:%S.%f')
225- # Else: copy the info
226- else:
227- params[field.name] = field_value
228-
229- model_instance = Model(**params)
230- model_instance.save()
231-
232- # Add the related object to the model
233- for field in many_to_many:
234- if entry.has_key(field.name):
235- for object_id in entry[field.name]:
236- many_related_manager = getattr(model_instance, field.name)
237- rel_model = many_related_manager.model
238- try:
239- related_object = rel_model.objects.get(pk=object_id)
240- except rel_model.DoesNotExist:
241- print '%(model)s with pk=%(pk)s does not exists' % ({'model':rel_model, 'pk':object_id})
242- else:
243- many_related_manager.add(related_object)
244-
245- # Save the model to the database, if changed by many to many fields
246- if many_to_many:
247- model_instance.save()
248-
249- # Restore the super user
250- if super_user:
251- old_su = super_user.__dict__
252- del old_su['id']
253- if old_su.__contains__('_state'):
254- del old_su['_state']
255- new_su, created = User.objects.get_or_create(username=old_su['username'])
256- new_su.__dict__.update(old_su)
257- new_su.save()
258-
259-

Subscribers

People subscribed via source and target branches