|
1 #!/usr/bin/python2.5 |
|
2 # |
|
3 # Copyright 2009 the Melange authors. |
|
4 # |
|
5 # Licensed under the Apache License, Version 2.0 (the "License"); |
|
6 # you may not use this file except in compliance with the License. |
|
7 # You may obtain a copy of the License at |
|
8 # |
|
9 # http://www.apache.org/licenses/LICENSE-2.0 |
|
10 # |
|
11 # Unless required by applicable law or agreed to in writing, software |
|
12 # distributed under the License is distributed on an "AS IS" BASIS, |
|
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
14 # See the License for the specific language governing permissions and |
|
15 # limitations under the License. |
|
16 |
|
17 """The script which generates KML file for Google Summer of Code 2009 program. |
|
18 """ |
|
19 |
|
20 __authors__ = [ |
|
21 '"Daniel Hans" <daniel.m.hans@gmail.com>', |
|
22 ] |
|
23 |
|
24 |
|
25 import sys |
|
26 import codecs |
|
27 import interactive |
|
28 |
|
29 |
|
30 from xml.dom.minidom import Document |
|
31 |
|
32 |
|
33 def _getMentoredProjects(mentor): |
|
34 """Returns a list of projects which are mentored by a given mentor. |
|
35 """ |
|
36 |
|
37 from soc.logic.models.student_project import logic as project_logic |
|
38 |
|
39 filter = { |
|
40 'mentor': mentor |
|
41 } |
|
42 |
|
43 return project_logic.getForFields(filter=filter) |
|
44 |
|
45 |
|
46 def _getAcceptedOrgs(): |
|
47 """Returns a list of organizations which got accepted. |
|
48 """ |
|
49 |
|
50 from soc.logic.models.organization import logic as org_logic |
|
51 |
|
52 filter = { |
|
53 'status': 'active' |
|
54 } |
|
55 |
|
56 entities = org_logic.getForFields(filter=filter) |
|
57 |
|
58 filter = { |
|
59 'status': 'new' |
|
60 } |
|
61 |
|
62 entities += org_logic.getForFields(filter=filter) |
|
63 |
|
64 return entities |
|
65 |
|
66 |
|
67 def _getStudentProject(entity): |
|
68 """Returns a project for a given student. |
|
69 """ |
|
70 |
|
71 from soc.logic.models.student_project import logic as project_logic |
|
72 |
|
73 filter = { |
|
74 'student': entity, |
|
75 'status': 'accepted', |
|
76 } |
|
77 |
|
78 return project_logic.getForFields(filter=filter, unique=True) |
|
79 |
|
80 |
|
81 def _getAllUsers(): |
|
82 """Returns a list of all valid users. |
|
83 """ |
|
84 |
|
85 from soc.models.user import User |
|
86 |
|
87 gen = lambda: User.all().filter('status =', 'valid') |
|
88 return interactive.deepFetch(gen) |
|
89 |
|
90 |
|
91 def _getAllOrgAdmins(): |
|
92 """Returns a generator of all active mentors. |
|
93 """ |
|
94 |
|
95 from soc.models.org_admin import OrgAdmin |
|
96 |
|
97 gen = lambda: OrgAdmin.all().filter('status = ', 'active') |
|
98 return interactive.deepFetch(gen) |
|
99 |
|
100 |
|
101 def _getAllMentors(): |
|
102 """Returns a generator of all active mentors. |
|
103 """ |
|
104 |
|
105 from soc.models.mentor import Mentor |
|
106 |
|
107 gen = lambda: Mentor.all().filter('status = ', 'active') |
|
108 return interactive.deepFetch(gen) |
|
109 |
|
110 |
|
111 def _getAllStudents(): |
|
112 """Returns a generator of all active students. |
|
113 """ |
|
114 |
|
115 from soc.models.student import Student |
|
116 |
|
117 gen = lambda: Student.all().filter('status = ', 'active') |
|
118 return interactive.deepFetch(gen) |
|
119 |
|
120 |
|
121 def _getPersonStyle(doc, type): |
|
122 """Returns <Style> element for a particular person. |
|
123 """ |
|
124 |
|
125 if type == 'org_admin': |
|
126 x_text, y_text = '0', '0' |
|
127 elif type == 'mentor': |
|
128 x_text, y_text = '128', '96' |
|
129 elif type == 'student': |
|
130 x_text, y_text = '64', '160' |
|
131 |
|
132 style = doc.createElement('Style') |
|
133 |
|
134 icon_style = doc.createElement('IconStyle') |
|
135 style.appendChild(icon_style) |
|
136 |
|
137 icon = doc.createElement('Icon') |
|
138 icon_style.appendChild(icon) |
|
139 |
|
140 href = doc.createElement('href') |
|
141 icon.appendChild(href) |
|
142 |
|
143 text = doc.createTextNode('root://icons/palette-5.png') |
|
144 href.appendChild(text) |
|
145 |
|
146 x = doc.createElement('x') |
|
147 icon.appendChild(x) |
|
148 |
|
149 text = doc.createTextNode(x_text) |
|
150 x.appendChild(text) |
|
151 |
|
152 y = doc.createElement('y') |
|
153 icon.appendChild(y) |
|
154 |
|
155 text = doc.createTextNode(y_text) |
|
156 y.appendChild(text) |
|
157 |
|
158 w = doc.createElement('w') |
|
159 icon.appendChild(w) |
|
160 |
|
161 text = doc.createTextNode('32') |
|
162 w.appendChild(text) |
|
163 |
|
164 h = doc.createElement('h') |
|
165 icon.appendChild(h) |
|
166 |
|
167 text = doc.createTextNode('32') |
|
168 h.appendChild(text) |
|
169 |
|
170 return style |
|
171 |
|
172 |
|
173 def _getLineStringStyle(doc): |
|
174 """Returns <Style> element for a line string placemark. |
|
175 """ |
|
176 |
|
177 style = doc.createElement('Style') |
|
178 |
|
179 line_style = doc.createElement('LineStyle') |
|
180 style.appendChild(line_style) |
|
181 |
|
182 color = doc.createElement('color') |
|
183 line_style.appendChild(color) |
|
184 |
|
185 text = doc.createTextNode('ff00ff00') |
|
186 color.appendChild(text) |
|
187 |
|
188 width = doc.createElement('width') |
|
189 line_style.appendChild(width) |
|
190 |
|
191 text = doc.createTextNode('1') |
|
192 width.appendChild(text) |
|
193 |
|
194 return style |
|
195 |
|
196 |
|
197 def _getDescriptionForStudent(doc, student, project): |
|
198 """Returns <description> element for a given student. |
|
199 """ |
|
200 |
|
201 description = doc.createElement('description') |
|
202 |
|
203 text = doc.createTextNode('Working on...') |
|
204 description.appendChild(text) |
|
205 |
|
206 description.appendChild(doc.createElement('br')) |
|
207 |
|
208 i = doc.createElement('i') |
|
209 description.appendChild(i) |
|
210 |
|
211 title = doc.createTextNode(project.title) |
|
212 i.appendChild(title) |
|
213 description.appendChild(doc.createElement('br')) |
|
214 |
|
215 mentor = doc.createTextNode( |
|
216 'mentored by ' + _getName(project.mentor)) |
|
217 description.appendChild(mentor) |
|
218 description.appendChild(doc.createElement('br')) |
|
219 |
|
220 org = doc.createTextNode(project.scope.name) |
|
221 description.appendChild(org) |
|
222 description.appendChild(doc.createElement('br')) |
|
223 description.appendChild(doc.createElement('br')) |
|
224 |
|
225 description = _appendHomePageAndBlogContent(doc, description, student) |
|
226 |
|
227 description = _appendStateAndCountryContnent(doc, description, student) |
|
228 |
|
229 return description |
|
230 |
|
231 |
|
232 def _appendStateAndCountryContnent(doc, description, state, country): |
|
233 """Appends state and country info to the description of a placemark. |
|
234 """ |
|
235 |
|
236 if state: |
|
237 description.appendChild(doc.createTextNode(state + ', ')) |
|
238 |
|
239 description.appendChild(doc.createTextNode(country)) |
|
240 |
|
241 return description |
|
242 |
|
243 |
|
244 def _appendHomePageAndBlogContent(doc, description, home_pages, blogs): |
|
245 """Appends home page and blog info to the description of a placemark. |
|
246 """ |
|
247 |
|
248 if home_pages: |
|
249 text = doc.createTextNode('Home page:') |
|
250 description.appendChild(text) |
|
251 description.appendChild(doc.createElement('br')) |
|
252 |
|
253 for home_page in home_pages: |
|
254 description.appendChild(doc.createTextNode(home_page)) |
|
255 description.appendChild(doc.createElement('br')) |
|
256 |
|
257 if home_pages: |
|
258 description.appendChild(doc.createElement('br')) |
|
259 |
|
260 if blogs: |
|
261 text = doc.createTextNode('Blog:') |
|
262 description.appendChild(text) |
|
263 description.appendChild(doc.createElement('br')) |
|
264 |
|
265 for blog in blogs: |
|
266 description.appendChild(doc.createTextNode(blog)) |
|
267 description.appendChild(doc.createElement('br')) |
|
268 |
|
269 if blogs: |
|
270 description.appendChild(doc.createElement('br')) |
|
271 |
|
272 return description |
|
273 |
|
274 |
|
275 def _getName(entity): |
|
276 """For a given entity returns a name to be displayed. |
|
277 """ |
|
278 |
|
279 return entity.name() |
|
280 |
|
281 |
|
282 def _getMentorDescription(doc, content): |
|
283 """Returns <description> element for a mentor / org admin based on content. |
|
284 """ |
|
285 |
|
286 description = doc.createElement('description') |
|
287 |
|
288 admin = content['admin'] |
|
289 if admin: |
|
290 text = doc.createTextNode('Organization admin for ' + admin) |
|
291 description.appendChild(text) |
|
292 description.appendChild(doc.createElement('br')) |
|
293 |
|
294 projects = content['projects'] |
|
295 if projects: |
|
296 text = doc.createTextNode('Mentoring...') |
|
297 description.appendChild(text) |
|
298 description.appendChild(doc.createElement('br')) |
|
299 |
|
300 for project in projects: |
|
301 i = doc.createElement('i') |
|
302 description.appendChild(i) |
|
303 |
|
304 title = doc.createTextNode(project['title']) |
|
305 i.appendChild(title) |
|
306 description.appendChild(doc.createElement('br')) |
|
307 |
|
308 student = doc.createTextNode('by ' + project['student']) |
|
309 description.appendChild(student) |
|
310 description.appendChild(doc.createElement('br')) |
|
311 |
|
312 organization = doc.createTextNode(project['org']) |
|
313 description.appendChild(organization) |
|
314 description.appendChild(doc.createElement('br')) |
|
315 |
|
316 consults = content['consults'] |
|
317 for consult in consults: |
|
318 text = doc.createTextNode(consult) |
|
319 description.appendChild(text) |
|
320 description.appendChild(doc.createElement('br')) |
|
321 |
|
322 description.appendChild(doc.createElement('br')) |
|
323 |
|
324 home_pages = content['home_pages'] |
|
325 blogs = content['blogs'] |
|
326 description = _appendHomePageAndBlogContent(doc, description, |
|
327 home_pages, blogs) |
|
328 |
|
329 state = content['state'] |
|
330 country = content['country'] |
|
331 description = _appendStateAndCountryContnent(doc, description, state, |
|
332 country) |
|
333 |
|
334 return description |
|
335 |
|
336 |
|
337 def _getStudentDescription(doc, content): |
|
338 """Returns <description> element for a student based on content. |
|
339 """ |
|
340 |
|
341 description = doc.createElement('description') |
|
342 |
|
343 text = doc.createTextNode('Working on...') |
|
344 description.appendChild(text) |
|
345 |
|
346 description.appendChild(doc.createElement('br')) |
|
347 |
|
348 project = content['project'] |
|
349 i = doc.createElement('i') |
|
350 description.appendChild(i) |
|
351 |
|
352 title = doc.createTextNode(project.title) |
|
353 i.appendChild(title) |
|
354 description.appendChild(doc.createElement('br')) |
|
355 |
|
356 mentor = doc.createTextNode('mentored by ' + project.mentor.name()) |
|
357 description.appendChild(mentor) |
|
358 description.appendChild(doc.createElement('br')) |
|
359 |
|
360 org = doc.createTextNode(project.scope.name) |
|
361 description.appendChild(org) |
|
362 description.appendChild(doc.createElement('br')) |
|
363 description.appendChild(doc.createElement('br')) |
|
364 |
|
365 home_pages = content['home_pages'] |
|
366 blogs = content['blogs'] |
|
367 description = _appendHomePageAndBlogContent(doc, description, |
|
368 home_pages, blogs) |
|
369 |
|
370 state = content['state'] |
|
371 country = content['country'] |
|
372 description = _appendStateAndCountryContnent(doc, description, state, |
|
373 country) |
|
374 |
|
375 return description |
|
376 |
|
377 |
|
378 def _createFolderForMentorsAndOrgAdmins(doc): |
|
379 """ |
|
380 """ |
|
381 |
|
382 folder = doc.createElement("Folder") |
|
383 |
|
384 name = doc.createElement("name") |
|
385 folder.appendChild(name) |
|
386 |
|
387 nametext = doc.createTextNode("Mentors") |
|
388 name.appendChild(nametext) |
|
389 |
|
390 return folder |
|
391 |
|
392 |
|
393 def _createLineString(doc, student, mentor): |
|
394 """Generates line string between a given student and mentor. |
|
395 """ |
|
396 |
|
397 line_string = doc.createElement('LineString') |
|
398 |
|
399 coordinates = doc.createElement('coordinates') |
|
400 line_string.appendChild(coordinates) |
|
401 |
|
402 text = doc.createTextNode(str(student[0]) + ',' + str(student[1]) + ' ' + |
|
403 str(mentor[0]) + ',' + str(mentor[1])) |
|
404 coordinates.appendChild(text) |
|
405 |
|
406 altitude_mode = doc.createElement('altitudeMode') |
|
407 line_string.appendChild(altitude_mode) |
|
408 |
|
409 text = doc.createTextNode('clampToGround') |
|
410 altitude_mode.appendChild(text) |
|
411 |
|
412 extrude = doc.createElement('extrude') |
|
413 line_string.appendChild(extrude) |
|
414 |
|
415 text = doc.createTextNode('1') |
|
416 extrude.appendChild(text) |
|
417 |
|
418 tessellate = doc.createElement('tessellate') |
|
419 line_string.appendChild(tessellate) |
|
420 |
|
421 text = doc.createTextNode('1') |
|
422 tessellate.appendChild(text) |
|
423 |
|
424 return line_string |
|
425 |
|
426 |
|
427 def _createPoint(doc, longitude, latitude): |
|
428 """Generates <Point> subtree with coordinates for a given entity. |
|
429 """ |
|
430 |
|
431 point = doc.createElement('Point') |
|
432 |
|
433 coordinates = doc.createElement('coordinates') |
|
434 point.appendChild(coordinates) |
|
435 |
|
436 text = doc.createTextNode(str(longitude) + ',' + str(latitude)) |
|
437 coordinates.appendChild(text) |
|
438 |
|
439 return point |
|
440 |
|
441 |
|
442 def _createStudentPlacemark(doc, coordinates, content): |
|
443 """Creates <Placemark> element for a student based on a given content. |
|
444 """ |
|
445 |
|
446 placemark = doc.createElement('Placemark') |
|
447 |
|
448 style = _getPersonStyle(doc, 'student') |
|
449 placemark.appendChild(style) |
|
450 |
|
451 name = doc.createElement('name') |
|
452 placemark.appendChild(name) |
|
453 |
|
454 text = doc.createTextNode(content['name']) |
|
455 name.appendChild(text) |
|
456 |
|
457 description = _getStudentDescription(doc, content) |
|
458 placemark.appendChild(description) |
|
459 |
|
460 point = _createPoint(doc, coordinates[0], coordinates[1]) |
|
461 placemark.appendChild(point) |
|
462 |
|
463 return placemark |
|
464 |
|
465 |
|
466 def _createMentorPlacemark(doc, coordinates, content): |
|
467 """Creates <Placemark> element for a mentor based on a given content. |
|
468 """ |
|
469 |
|
470 placemark = doc.createElement('Placemark') |
|
471 |
|
472 type = 'org_admin' if content['admin'] is not None else 'mentor' |
|
473 style = _getPersonStyle(doc, type) |
|
474 placemark.appendChild(style) |
|
475 |
|
476 name = doc.createElement('name') |
|
477 placemark.appendChild(name) |
|
478 |
|
479 text = doc.createTextNode(content['name']) |
|
480 name.appendChild(text) |
|
481 |
|
482 description = _getMentorDescription(doc, content) |
|
483 placemark.appendChild(description) |
|
484 |
|
485 point = _createPoint(doc, coordinates[0], coordinates[1]) |
|
486 placemark.appendChild(point) |
|
487 |
|
488 return placemark |
|
489 |
|
490 |
|
491 def _createLineStringPlacemark(doc, student_coordinates, mentor_coordinates): |
|
492 """Creates <Placemark> element for a line string between given student |
|
493 coordinates and mentor coordinates. |
|
494 """ |
|
495 |
|
496 placemark = doc.createElement('Placemark') |
|
497 |
|
498 line_string = _createLineString(doc, student_coordinates, mentor_coordinates) |
|
499 placemark.appendChild(line_string) |
|
500 |
|
501 style = _getLineStringStyle(doc) |
|
502 placemark.appendChild(style) |
|
503 |
|
504 return placemark |
|
505 |
|
506 |
|
507 def _processMentor(doc, org_admin, mentors, folder): |
|
508 """Processes a student and adds information to a folder. |
|
509 """ |
|
510 |
|
511 projects = [] |
|
512 placemarks = {} |
|
513 longitude = None |
|
514 latitude = None |
|
515 |
|
516 for entity in mentors: |
|
517 if not entity.publish_location: |
|
518 continue |
|
519 |
|
520 longitude, latitude = (entity.longitude, entity.latitude) |
|
521 |
|
522 if not placemarks.get((longitude, latitude)): |
|
523 placemarks[(longitude, latitude)] = { |
|
524 'admin': None, |
|
525 'projects': [], |
|
526 'consults': [], |
|
527 'name': entity.name(), |
|
528 'country': entity.res_country, |
|
529 'state': entity.res_state, |
|
530 'home_pages': set(), |
|
531 'blogs': set() |
|
532 } |
|
533 |
|
534 projects = _getMentoredProjects(entity) |
|
535 if not projects: |
|
536 placemarks[(longitude, latitude)]['consults'].append( |
|
537 'Mentor for ' + entity.scope.name) |
|
538 else: |
|
539 for project in projects: |
|
540 placemarks[(longitude, latitude)]['projects'].append({ |
|
541 'title': project.title, |
|
542 'org': project.scope.name, |
|
543 'student': project.student.name() |
|
544 }) |
|
545 |
|
546 if entity.home_page: |
|
547 placemarks[(longitude, latitude)]['home_pages'].add(entity.home_page) |
|
548 if entity.blog: |
|
549 placemarks[(longitude, latitude)]['blogs'].add(entity.blog) |
|
550 |
|
551 if org_admin and org_admin.publish_location: |
|
552 |
|
553 if not (longitude, latitude): |
|
554 longitude, latitude = (org_admin.longitude, org_admin.latitude) |
|
555 |
|
556 if not placemarks.get((longitude, latitude)): |
|
557 placemarks[(longitude, latitude)] = { |
|
558 'admin': None, |
|
559 'projects': [], |
|
560 'consults': [], |
|
561 'name': org_admin.name(), |
|
562 'country': org_admin.res_country, |
|
563 'state': org_admin.res_state, |
|
564 'home_pages': set(), |
|
565 'blogs': set() |
|
566 } |
|
567 |
|
568 placemarks[(longitude, latitude)]['admin'] = org_admin.scope.name |
|
569 |
|
570 if org_admin.home_page: |
|
571 placemarks[(longitude, latitude)]['home_pages'].add(org_admin.home_page) |
|
572 if org_admin.blog: |
|
573 placemarks[(longitude, latitude)]['blogs'].add(org_admin.blog) |
|
574 |
|
575 for coordinates, content in placemarks.iteritems(): |
|
576 placemark = _createMentorPlacemark(doc, coordinates, content) |
|
577 folder.appendChild(placemark) |
|
578 |
|
579 |
|
580 def _processStudent(doc, student, orgs_folder): |
|
581 """Processes a student and adds information to a folder. |
|
582 """ |
|
583 |
|
584 if not student.publish_location: |
|
585 return |
|
586 |
|
587 project = _getStudentProject(student) |
|
588 |
|
589 if not project: |
|
590 return |
|
591 |
|
592 folder = doc.createElement('Folder') |
|
593 |
|
594 name = doc.createElement('name') |
|
595 folder.appendChild(name) |
|
596 |
|
597 name.appendChild(doc.createTextNode(student.name())) |
|
598 |
|
599 content = { |
|
600 'name': student.name(), |
|
601 'project': project, |
|
602 'country': student.res_country, |
|
603 'state': student.res_state, |
|
604 'home_pages': [student.home_page] if student.home_page else [], |
|
605 'blogs': [student.blog] if student.blog else [] |
|
606 } |
|
607 |
|
608 coordinates = student.longitude, student.latitude |
|
609 |
|
610 placemark = _createStudentPlacemark(doc, coordinates, content) |
|
611 folder.appendChild(placemark) |
|
612 |
|
613 mentor = project.mentor |
|
614 |
|
615 if mentor.publish_location: |
|
616 mentor_coordinates = mentor.longitude, mentor.latitude |
|
617 line_string = _createLineStringPlacemark(doc, coordinates, |
|
618 mentor_coordinates) |
|
619 folder.appendChild(line_string) |
|
620 |
|
621 org = project.scope |
|
622 org_folder = orgs_folder[org.name] |
|
623 org_folder.appendChild(folder) |
|
624 |
|
625 |
|
626 def _processAllUsers(doc, mentors_folder, orgs_folder): |
|
627 """Processes all users and fills folders with information based on roles. |
|
628 """ |
|
629 |
|
630 from soc.logic.models.mentor import logic as mentor_logic |
|
631 from soc.logic.models.org_admin import logic as org_admin_logic |
|
632 from soc.logic.models.student import logic as student_logic |
|
633 |
|
634 it = _getAllOrgAdmins() |
|
635 org_admins = dict() |
|
636 for org_admin in it: |
|
637 org_admins[org_admin.link_id] = org_admin |
|
638 |
|
639 it = _getAllMentors() |
|
640 mentors = dict() |
|
641 for mentor in it: |
|
642 link_id = mentor.link_id |
|
643 if link_id not in mentors: |
|
644 mentors[link_id] = [] |
|
645 mentors[link_id].append(mentor) |
|
646 |
|
647 it = _getAllStudents() |
|
648 students = dict() |
|
649 for student in it: |
|
650 students[student.link_id] = student |
|
651 |
|
652 link_ids = set(mentors.keys() + org_admins.keys()) |
|
653 |
|
654 for link_id in link_ids: |
|
655 entity = org_admins.get(link_id) |
|
656 entities = mentors.get(link_id, []) |
|
657 |
|
658 if entity or entities: |
|
659 _processMentor(doc, entity, entities, mentors_folder) |
|
660 continue |
|
661 |
|
662 link_ids = students.keys() |
|
663 for link_id in link_ids: |
|
664 entity = students.get(link_id) |
|
665 if entity: |
|
666 _processStudent(doc, entity, orgs_folder) |
|
667 |
|
668 |
|
669 def _createFolderForStudentsAndOrgs(doc): |
|
670 """Creates <Folder> elements for all students and for all accepted |
|
671 organizations. |
|
672 |
|
673 Returns: |
|
674 A tuple whose first element is a folder for students and the second |
|
675 one is a dictionary mapping organization names with their folders. |
|
676 """ |
|
677 |
|
678 folder = doc.createElement('Folder') |
|
679 |
|
680 name = doc.createElement('name') |
|
681 folder.appendChild(name) |
|
682 |
|
683 text = doc.createTextNode('Students') |
|
684 name.appendChild(text) |
|
685 |
|
686 orgs = _getAcceptedOrgs() |
|
687 org_folders = {} |
|
688 |
|
689 for org in orgs: |
|
690 org_folder = doc.createElement('Folder') |
|
691 folder.appendChild(org_folder) |
|
692 |
|
693 name = doc.createElement('name') |
|
694 org_folder.appendChild(name) |
|
695 |
|
696 text = doc.createTextNode(org.name) |
|
697 name.appendChild(text) |
|
698 |
|
699 org_folders[org.name] = org_folder |
|
700 |
|
701 return folder, org_folders |
|
702 |
|
703 |
|
704 def generateCompleteKML(): |
|
705 """Generates complete KML file for Google Summer of Code 2009. |
|
706 """ |
|
707 |
|
708 doc = Document() |
|
709 |
|
710 kml = doc.createElement('kml') |
|
711 doc.appendChild(kml) |
|
712 |
|
713 document = doc.createElement('Document') |
|
714 kml.appendChild(document) |
|
715 |
|
716 mentor_folder = _createFolderForMentorsAndOrgAdmins(doc) |
|
717 document.appendChild(mentor_folder) |
|
718 |
|
719 student_folder, org_folders = _createFolderForStudentsAndOrgs(doc) |
|
720 document.appendChild(student_folder) |
|
721 |
|
722 _processAllUsers(doc, mentor_folder, org_folders) |
|
723 |
|
724 out = codecs.open('soc_map2009.kml', 'w', 'utf-8') |
|
725 out.write(doc.toprettyxml(indent=' ')) |
|
726 out.close() |
|
727 |
|
728 |
|
729 def main(args): |
|
730 |
|
731 context = { |
|
732 'export': generateCompleteKML, |
|
733 } |
|
734 interactive.setup() |
|
735 interactive.remote(args, context) |
|
736 |
|
737 |
|
738 if __name__ == '__main__': |
|
739 if len(sys.argv) < 2: |
|
740 print "Usage: %s app_id [host]" % (sys.argv[0],) |
|
741 sys.exit(1) |
|
742 |
|
743 main(sys.argv[1:]) |