ctdo-trac/TracRendezVous/tracrendezvous/location/web_ui.py

237 lines
12 KiB
Python

# -*- coding: utf-8 -*-
from datetime import datetime, timedelta
from os import mkdir
from os.path import join
from re import match, sub
from collections import defaultdict
from sqlite3 import IntegrityError
from operator import attrgetter
from trac.config import *
from trac.core import Component, implements, TracError
from trac.perm import PermissionError, IPermissionRequestor
from trac.resource import Resource, get_resource_url, get_resource_name
from trac.util import get_reporter_id
from trac.util.text import to_unicode
from trac.util.datefmt import utc, get_timezone, localtz, timezone
from trac.util.translation import _
from trac.util.html import html
from trac.web.chrome import INavigationContributor, ITemplateProvider, add_stylesheet, add_warning, add_notice, add_ctxtnav, add_script
from trac.web import IRequestHandler
from genshi.builder import tag
from tracrendezvous.location.loc_xml import *
from tracrendezvous.location.model import *
from tracrendezvous.location.utils import *
__all__ = ['LocationModule',]
class LocationModule(Component):
'''The web ui frontend for the location management system'''
implements(INavigationContributor,
IRequestHandler,
IPermissionRequestor,
ITemplateProvider)
# INavigationContributor methods
def get_active_navigation_item(self, req):
return 'location'
def get_navigation_items(self, req):
if "LOCATION_VIEW" in req.perm:
yield ('mainnav', 'location', html.A('Locations', href=req.href.location()))
# IPermissionRequestor methods
def get_permission_actions(self):
'''returns all permissions this component provides'''
return ['LOCATION_VIEW', 'LOCATION_ADD', 'LOCATION_DELETE', 'LOCATION_MODIFY',
('LOCATION_ADMIN', ('LOCATION_VIEW', 'LOCATION_ADD', 'LOCATION_DELETE', 'LOCATION_MODIFY'))]
def match_request(self, req):
self.env.log.debug("LocationModule.match_request %r\n" % req.__dict__)
res = req.path_info == "/location"
self.env.log.debug("LocationModule.match_request res = %r\n" % res)
return res
def process_request(self, req):
self.env.log.debug("LocationModule.process_request %r\n" % req.__dict__)
'''process add,change,delete actions'''
req.perm.require("LOCATION_VIEW")
#add_stylesheet(req, 'hw/css/base.css')
add_stylesheet (req, 'hw/css/location.css')
#add_stylesheet (req, 'hw/css/map.css')
add_script(req, 'http://www.openlayers.org/api/OpenLayers.js')
add_script(req, 'http://www.openstreetmap.org/openlayers/OpenStreetMap.js')
add_script(req, 'hw/script/tom.js')
data = {"results": []}
if req.args.has_key("from") and req.args.has_key("id"):
req.session["from"] = req.args["from"]
req.session["id"] = req.args["id"]
req.session.save()
if req.session.has_key("edited"):
try:
from_resource = req.session.get("from")
resource_id = int(req.session.get("id"))
resource = Resource(from_resource, id=resource_id)
link = get_resource_url(self.env, resource, req.href)
add_notice(req, tag.p("Location edited successfully. Back to " , tag.a(get_resource_description(self.env, resource, "summary"), href=link)))
del req.session["from"]
del req.session["id"]
except Exception, e:
add_notice(req, _("Location edited successfully."))
del req.session["edited"]
req.session.save()
if req.session.has_key("added"):
try:
from_resource = req.args.get("from")
resource_id = int(req.args.get("id"))
resource = Resource(from_resource, id=resource_id)
link = get_resource_url(from_resource, resource_id)
add_notice(req, tag.p(_("Location created successfully. Back to ") % resource, tag.a(resource, href=link)))
except Exception:
add_notice(req, _("Location created successfully."))
del req.session["added"]
req.session.save()
if req.method == "POST":
if req.args.has_key("location_search"):
query = unicode(req.args["location_search"])
results = search_location(query)
data["location_results"] = results
if req.args.has_key("savelocations"):
req.perm.require("LOCATION_MODIFY")
deleted = []
locations = {}
changed = {}
if req.args.has_key("default"):
default_location = self.config.getint("rendezvous", "default_location")
default = int(req.args["default"])
if default_location != default:
default_location = default
self.config.set("rendezvous", "default_location", default)
self.config.save()
for key in req.args:
kind = location_id = None
try:
kind, location_id = key.split(":", 1)
except ValueError:
continue
location_id = int(location_id)
if location_id in deleted:
continue
if not locations.has_key(location_id):
location = ItemLocation.fetch_one(self.env, location_id)
if not location:
add_warning(req, "Could not find ItemLocation with location_id '%d'" % location_id)
continue
locations[location_id] = location
if kind == "delete":
req.perm.require("LOCATION_DELETE")
locations[location_id].delete()
deleted.append(location_id)
del locations[location_id]
elif kind == "name":
name = req.args[key]
if not name:
add_warning(req, "location name must be specified for ItemLocation '%d'" % location_id)
continue
if name != locations[location_id].name:
locations[location_id].name = name
changed[location_id] = True
elif kind == "location":
coordinates = req.args[key]
if coordinates:
try:
lat, lon = validate_dd_coordinates(coordinates)
lat_side, lat_deg, lat_min, lat_sec, lon_side, lon_deg, lon_min, lon_sec = convert_dd_2_dms(lat, lon)
except ValueError:
try:
lat_side, lat_deg, lat_min, lat_sec, lon_side, lon_deg, lon_min, lon_sec = validate_dms_coordinates(coordinates)
lat, lon = convert_dms_2_dd(lat_side, lat_deg, lat_min, lat_sec, lon_side, lon_deg, lon_min, lon_sec)
except ValueError:
add_warning(req, "coordinates have wrong format")
continue
if lat != location.lat:
location.lat = lat
changed[location_id] = True
if lon != location.lon:
location.lon = lon
changed[location_id] = True
if lat_side != location.lat_side:
location.lat_side = lat_side
changed[location_id] = True
if lat_deg != location.lat_deg:
location.lat_deg = lat_deg
changed[location_id] = True
if lat_min != location.lat_min:
location.lat_min = lat_min
changed[location_id] = True
if lat_sec != location.lat_sec:
location.lat_sec= lat_sec
changed[location_id] = True
if lon_side != location.lon_side:
location.lon_side = lon_side
changed[location_id] = True
if lon_deg != location.lon_deg:
location.lon_deg = lon_deg
changed[location_id] = True
if lon_min != location.lon_min:
location.lon_min = lon_min
changed[location_id] = True
if lon_sec != location.lon_sec:
location.lon_sec = lon_sec
changed[location_id] = True
done=True
for dvi in changed:
if dvi not in deleted:
try:
locations[dvi].update()
except Exception, err:
add_warning(req, str(err))
done=False
continue
if done:
req.session["edited"] = True
req.session.save()
req.redirect(req.href.location())
if req.args.has_key("addlocation") and req.args.has_key("location_name"):
req.perm.require("LOCATION_ADD")
rl = ItemLocation(self.env, name=req.args["location_name"])
is_valid = True
if not rl.name:
add_warning(req, "Coordinate name is empty")
is_valid = False
if req.args.has_key("coordinates"):
coordinates = unicode(req.args["coordinates"])
if coordinates:
try:
rl.lat, rl.lon = validate_dd_coordinates(coordinates)
rl.lat_side, rl.lat_deg, rl.lat_min, rl.lat_sec, rl.lon_side, rl.lon_deg, rl.lon_min, rl.lon_sec = convert_dd_2_dms(rl.lat, rl.lon)
except ValueError:
try:
rl.lat_side, rl.lat_deg, rl.lat_min, rl.lat_sec, rl.lon_side, rl.lon_deg, rl.lon_min, rl.lon_sec = validate_dms_coordinates(coordinates)
rl.lat, rl.lon = convert_dms_2_dd(rl.lat_side, rl.lat_deg, rl.lat_min, rl.lat_sec, rl.lon_side, rl.lon_deg, rl.lon_min, rl.lon_sec)
except ValueError:
add_warning(req, "coordinates have wrong format")
is_valid = False
if is_valid:
rl.commit()
req.session["added"] = True
req.session.save()
req.redirect(req.href.location())
data.update({"results" : None,
"default_location" : self.config.getint("rendezvous", "default_location"),
"locations" : ItemLocation.fetch_all(self.env)})
return 'location.html', data, None
# ITemplateProvider methods
def get_templates_dirs(self):
from pkg_resources import resource_filename
return [resource_filename(__name__, 'templates')]
def get_htdocs_dirs(self):
from pkg_resources import resource_filename
return [('hw', resource_filename(__name__, 'htdocs'))]