scripts/export_kml.py
changeset 2967 676c0ca67e21
equal deleted inserted replaced
2966:9ae1ee28e438 2967:676c0ca67e21
       
     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:])