237 lines
12 KiB
Python
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")
|
|
ItemLocation.delete(self.env, location_id)
|
|
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'))]
|