GMaps related JS changed to use new google namespace.
Google is going to change permanently in the future the way to
load its services, so better stay safe.
Also this commit shows uses of the new melange.js module.
Fixes Issue 634.
#!/usr/bin/python2.5
#
# Copyright 2009 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The script which generates KML file for Google Summer of Code 2009 program.
"""
__authors__ = [
'"Daniel Hans" <daniel.m.hans@gmail.com>',
]
import sys
import codecs
import interactive
from xml.dom.minidom import Document
def _getMentoredProjects(mentor):
"""Returns a list of projects which are mentored by a given mentor.
"""
from soc.logic.models.student_project import logic as project_logic
filter = {
'mentor': mentor
}
return project_logic.getForFields(filter=filter)
def _getAcceptedOrgs():
"""Returns a list of organizations which got accepted.
"""
from soc.logic.models.organization import logic as org_logic
filter = {
'status': 'active'
}
entities = org_logic.getForFields(filter=filter)
filter = {
'status': 'new'
}
entities += org_logic.getForFields(filter=filter)
return entities
def _getStudentProject(entity):
"""Returns a project for a given student.
"""
from soc.logic.models.student_project import logic as project_logic
filter = {
'student': entity,
'status': 'accepted',
}
return project_logic.getForFields(filter=filter, unique=True)
def _getAllUsers():
"""Returns a list of all valid users.
"""
from soc.models.user import User
gen = lambda: User.all().filter('status =', 'valid')
return interactive.deepFetch(gen)
def _getAllOrgAdmins():
"""Returns a generator of all active mentors.
"""
from soc.models.org_admin import OrgAdmin
gen = lambda: OrgAdmin.all().filter('status = ', 'active')
return interactive.deepFetch(gen)
def _getAllMentors():
"""Returns a generator of all active mentors.
"""
from soc.models.mentor import Mentor
gen = lambda: Mentor.all().filter('status = ', 'active')
return interactive.deepFetch(gen)
def _getAllStudents():
"""Returns a generator of all active students.
"""
from soc.models.student import Student
gen = lambda: Student.all().filter('status = ', 'active')
return interactive.deepFetch(gen)
def _getPersonStyle(doc, type):
"""Returns <Style> element for a particular person.
"""
if type == 'org_admin':
x_text, y_text = '0', '0'
elif type == 'mentor':
x_text, y_text = '128', '96'
elif type == 'student':
x_text, y_text = '64', '160'
style = doc.createElement('Style')
icon_style = doc.createElement('IconStyle')
style.appendChild(icon_style)
icon = doc.createElement('Icon')
icon_style.appendChild(icon)
href = doc.createElement('href')
icon.appendChild(href)
text = doc.createTextNode('root://icons/palette-5.png')
href.appendChild(text)
x = doc.createElement('x')
icon.appendChild(x)
text = doc.createTextNode(x_text)
x.appendChild(text)
y = doc.createElement('y')
icon.appendChild(y)
text = doc.createTextNode(y_text)
y.appendChild(text)
w = doc.createElement('w')
icon.appendChild(w)
text = doc.createTextNode('32')
w.appendChild(text)
h = doc.createElement('h')
icon.appendChild(h)
text = doc.createTextNode('32')
h.appendChild(text)
return style
def _getLineStringStyle(doc):
"""Returns <Style> element for a line string placemark.
"""
style = doc.createElement('Style')
line_style = doc.createElement('LineStyle')
style.appendChild(line_style)
color = doc.createElement('color')
line_style.appendChild(color)
text = doc.createTextNode('ff00ff00')
color.appendChild(text)
width = doc.createElement('width')
line_style.appendChild(width)
text = doc.createTextNode('1')
width.appendChild(text)
return style
def _getDescriptionForStudent(doc, student, project):
"""Returns <description> element for a given student.
"""
description = doc.createElement('description')
text = doc.createTextNode('Working on...')
description.appendChild(text)
description.appendChild(doc.createElement('br'))
i = doc.createElement('i')
description.appendChild(i)
title = doc.createTextNode(project.title)
i.appendChild(title)
description.appendChild(doc.createElement('br'))
mentor = doc.createTextNode(
'mentored by ' + _getName(project.mentor))
description.appendChild(mentor)
description.appendChild(doc.createElement('br'))
org = doc.createTextNode(project.scope.name)
description.appendChild(org)
description.appendChild(doc.createElement('br'))
description.appendChild(doc.createElement('br'))
description = _appendHomePageAndBlogContent(doc, description, student)
description = _appendStateAndCountryContnent(doc, description, student)
return description
def _appendStateAndCountryContnent(doc, description, state, country):
"""Appends state and country info to the description of a placemark.
"""
if state:
description.appendChild(doc.createTextNode(state + ', '))
description.appendChild(doc.createTextNode(country))
return description
def _appendHomePageAndBlogContent(doc, description, home_pages, blogs):
"""Appends home page and blog info to the description of a placemark.
"""
if home_pages:
text = doc.createTextNode('Home page:')
description.appendChild(text)
description.appendChild(doc.createElement('br'))
for home_page in home_pages:
description.appendChild(doc.createTextNode(home_page))
description.appendChild(doc.createElement('br'))
if home_pages:
description.appendChild(doc.createElement('br'))
if blogs:
text = doc.createTextNode('Blog:')
description.appendChild(text)
description.appendChild(doc.createElement('br'))
for blog in blogs:
description.appendChild(doc.createTextNode(blog))
description.appendChild(doc.createElement('br'))
if blogs:
description.appendChild(doc.createElement('br'))
return description
def _getName(entity):
"""For a given entity returns a name to be displayed.
"""
return entity.name()
def _getMentorDescription(doc, content):
"""Returns <description> element for a mentor / org admin based on content.
"""
description = doc.createElement('description')
admin = content['admin']
if admin:
text = doc.createTextNode('Organization admin for ' + admin)
description.appendChild(text)
description.appendChild(doc.createElement('br'))
projects = content['projects']
if projects:
text = doc.createTextNode('Mentoring...')
description.appendChild(text)
description.appendChild(doc.createElement('br'))
for project in projects:
i = doc.createElement('i')
description.appendChild(i)
title = doc.createTextNode(project['title'])
i.appendChild(title)
description.appendChild(doc.createElement('br'))
student = doc.createTextNode('by ' + project['student'])
description.appendChild(student)
description.appendChild(doc.createElement('br'))
organization = doc.createTextNode(project['org'])
description.appendChild(organization)
description.appendChild(doc.createElement('br'))
consults = content['consults']
for consult in consults:
text = doc.createTextNode(consult)
description.appendChild(text)
description.appendChild(doc.createElement('br'))
description.appendChild(doc.createElement('br'))
home_pages = content['home_pages']
blogs = content['blogs']
description = _appendHomePageAndBlogContent(doc, description,
home_pages, blogs)
state = content['state']
country = content['country']
description = _appendStateAndCountryContnent(doc, description, state,
country)
return description
def _getStudentDescription(doc, content):
"""Returns <description> element for a student based on content.
"""
description = doc.createElement('description')
text = doc.createTextNode('Working on...')
description.appendChild(text)
description.appendChild(doc.createElement('br'))
project = content['project']
i = doc.createElement('i')
description.appendChild(i)
title = doc.createTextNode(project.title)
i.appendChild(title)
description.appendChild(doc.createElement('br'))
mentor = doc.createTextNode('mentored by ' + project.mentor.name())
description.appendChild(mentor)
description.appendChild(doc.createElement('br'))
org = doc.createTextNode(project.scope.name)
description.appendChild(org)
description.appendChild(doc.createElement('br'))
description.appendChild(doc.createElement('br'))
home_pages = content['home_pages']
blogs = content['blogs']
description = _appendHomePageAndBlogContent(doc, description,
home_pages, blogs)
state = content['state']
country = content['country']
description = _appendStateAndCountryContnent(doc, description, state,
country)
return description
def _createFolderForMentorsAndOrgAdmins(doc):
"""
"""
folder = doc.createElement("Folder")
name = doc.createElement("name")
folder.appendChild(name)
nametext = doc.createTextNode("Mentors")
name.appendChild(nametext)
return folder
def _createLineString(doc, student, mentor):
"""Generates line string between a given student and mentor.
"""
line_string = doc.createElement('LineString')
coordinates = doc.createElement('coordinates')
line_string.appendChild(coordinates)
text = doc.createTextNode(str(student[0]) + ',' + str(student[1]) + ' ' +
str(mentor[0]) + ',' + str(mentor[1]))
coordinates.appendChild(text)
altitude_mode = doc.createElement('altitudeMode')
line_string.appendChild(altitude_mode)
text = doc.createTextNode('clampToGround')
altitude_mode.appendChild(text)
extrude = doc.createElement('extrude')
line_string.appendChild(extrude)
text = doc.createTextNode('1')
extrude.appendChild(text)
tessellate = doc.createElement('tessellate')
line_string.appendChild(tessellate)
text = doc.createTextNode('1')
tessellate.appendChild(text)
return line_string
def _createPoint(doc, longitude, latitude):
"""Generates <Point> subtree with coordinates for a given entity.
"""
point = doc.createElement('Point')
coordinates = doc.createElement('coordinates')
point.appendChild(coordinates)
text = doc.createTextNode(str(longitude) + ',' + str(latitude))
coordinates.appendChild(text)
return point
def _createStudentPlacemark(doc, coordinates, content):
"""Creates <Placemark> element for a student based on a given content.
"""
placemark = doc.createElement('Placemark')
style = _getPersonStyle(doc, 'student')
placemark.appendChild(style)
name = doc.createElement('name')
placemark.appendChild(name)
text = doc.createTextNode(content['name'])
name.appendChild(text)
description = _getStudentDescription(doc, content)
placemark.appendChild(description)
point = _createPoint(doc, coordinates[0], coordinates[1])
placemark.appendChild(point)
return placemark
def _createMentorPlacemark(doc, coordinates, content):
"""Creates <Placemark> element for a mentor based on a given content.
"""
placemark = doc.createElement('Placemark')
type = 'org_admin' if content['admin'] is not None else 'mentor'
style = _getPersonStyle(doc, type)
placemark.appendChild(style)
name = doc.createElement('name')
placemark.appendChild(name)
text = doc.createTextNode(content['name'])
name.appendChild(text)
description = _getMentorDescription(doc, content)
placemark.appendChild(description)
point = _createPoint(doc, coordinates[0], coordinates[1])
placemark.appendChild(point)
return placemark
def _createLineStringPlacemark(doc, student_coordinates, mentor_coordinates):
"""Creates <Placemark> element for a line string between given student
coordinates and mentor coordinates.
"""
placemark = doc.createElement('Placemark')
line_string = _createLineString(doc, student_coordinates, mentor_coordinates)
placemark.appendChild(line_string)
style = _getLineStringStyle(doc)
placemark.appendChild(style)
return placemark
def _processMentor(doc, org_admin, mentors, folder):
"""Processes a student and adds information to a folder.
"""
projects = []
placemarks = {}
longitude = None
latitude = None
for entity in mentors:
if not entity.publish_location:
continue
longitude, latitude = (entity.longitude, entity.latitude)
if not placemarks.get((longitude, latitude)):
placemarks[(longitude, latitude)] = {
'admin': None,
'projects': [],
'consults': [],
'name': entity.name(),
'country': entity.res_country,
'state': entity.res_state,
'home_pages': set(),
'blogs': set()
}
projects = _getMentoredProjects(entity)
if not projects:
placemarks[(longitude, latitude)]['consults'].append(
'Mentor for ' + entity.scope.name)
else:
for project in projects:
placemarks[(longitude, latitude)]['projects'].append({
'title': project.title,
'org': project.scope.name,
'student': project.student.name()
})
if entity.home_page:
placemarks[(longitude, latitude)]['home_pages'].add(entity.home_page)
if entity.blog:
placemarks[(longitude, latitude)]['blogs'].add(entity.blog)
if org_admin and org_admin.publish_location:
if not (longitude, latitude):
longitude, latitude = (org_admin.longitude, org_admin.latitude)
if not placemarks.get((longitude, latitude)):
placemarks[(longitude, latitude)] = {
'admin': None,
'projects': [],
'consults': [],
'name': org_admin.name(),
'country': org_admin.res_country,
'state': org_admin.res_state,
'home_pages': set(),
'blogs': set()
}
placemarks[(longitude, latitude)]['admin'] = org_admin.scope.name
if org_admin.home_page:
placemarks[(longitude, latitude)]['home_pages'].add(org_admin.home_page)
if org_admin.blog:
placemarks[(longitude, latitude)]['blogs'].add(org_admin.blog)
for coordinates, content in placemarks.iteritems():
placemark = _createMentorPlacemark(doc, coordinates, content)
folder.appendChild(placemark)
def _processStudent(doc, student, orgs_folder):
"""Processes a student and adds information to a folder.
"""
if not student.publish_location:
return
project = _getStudentProject(student)
if not project:
return
folder = doc.createElement('Folder')
name = doc.createElement('name')
folder.appendChild(name)
name.appendChild(doc.createTextNode(student.name()))
content = {
'name': student.name(),
'project': project,
'country': student.res_country,
'state': student.res_state,
'home_pages': [student.home_page] if student.home_page else [],
'blogs': [student.blog] if student.blog else []
}
coordinates = student.longitude, student.latitude
placemark = _createStudentPlacemark(doc, coordinates, content)
folder.appendChild(placemark)
mentor = project.mentor
if mentor.publish_location:
mentor_coordinates = mentor.longitude, mentor.latitude
line_string = _createLineStringPlacemark(doc, coordinates,
mentor_coordinates)
folder.appendChild(line_string)
org = project.scope
org_folder = orgs_folder[org.name]
org_folder.appendChild(folder)
def _processAllUsers(doc, mentors_folder, orgs_folder):
"""Processes all users and fills folders with information based on roles.
"""
from soc.logic.models.mentor import logic as mentor_logic
from soc.logic.models.org_admin import logic as org_admin_logic
from soc.logic.models.student import logic as student_logic
it = _getAllOrgAdmins()
org_admins = dict()
for org_admin in it:
org_admins[org_admin.link_id] = org_admin
it = _getAllMentors()
mentors = dict()
for mentor in it:
link_id = mentor.link_id
if link_id not in mentors:
mentors[link_id] = []
mentors[link_id].append(mentor)
it = _getAllStudents()
students = dict()
for student in it:
students[student.link_id] = student
link_ids = set(mentors.keys() + org_admins.keys())
for link_id in link_ids:
entity = org_admins.get(link_id)
entities = mentors.get(link_id, [])
if entity or entities:
_processMentor(doc, entity, entities, mentors_folder)
continue
link_ids = students.keys()
for link_id in link_ids:
entity = students.get(link_id)
if entity:
_processStudent(doc, entity, orgs_folder)
def _createFolderForStudentsAndOrgs(doc):
"""Creates <Folder> elements for all students and for all accepted
organizations.
Returns:
A tuple whose first element is a folder for students and the second
one is a dictionary mapping organization names with their folders.
"""
folder = doc.createElement('Folder')
name = doc.createElement('name')
folder.appendChild(name)
text = doc.createTextNode('Students')
name.appendChild(text)
orgs = _getAcceptedOrgs()
org_folders = {}
for org in orgs:
org_folder = doc.createElement('Folder')
folder.appendChild(org_folder)
name = doc.createElement('name')
org_folder.appendChild(name)
text = doc.createTextNode(org.name)
name.appendChild(text)
org_folders[org.name] = org_folder
return folder, org_folders
def generateCompleteKML():
"""Generates complete KML file for Google Summer of Code 2009.
"""
doc = Document()
kml = doc.createElement('kml')
doc.appendChild(kml)
document = doc.createElement('Document')
kml.appendChild(document)
mentor_folder = _createFolderForMentorsAndOrgAdmins(doc)
document.appendChild(mentor_folder)
student_folder, org_folders = _createFolderForStudentsAndOrgs(doc)
document.appendChild(student_folder)
_processAllUsers(doc, mentor_folder, org_folders)
out = codecs.open('soc_map2009.kml', 'w', 'utf-8')
out.write(doc.toprettyxml(indent=' '))
out.close()
def main(args):
context = {
'export': generateCompleteKML,
}
interactive.setup()
interactive.remote(args, context)
if __name__ == '__main__':
if len(sys.argv) < 2:
print "Usage: %s app_id [host]" % (sys.argv[0],)
sys.exit(1)
main(sys.argv[1:])