Merge lp:~zack-krejci/healthscapes/trunk into lp:healthscapes/trunk

Proposed by Zack
Status: Merged
Merged at revision: 8
Proposed branch: lp:~zack-krejci/healthscapes/trunk
Merge into: lp:healthscapes/trunk
Diff against target: 1990387 lines (+25/-978057)
2252 files modified
controllers/admin.py (+0/-1241)
controllers/appadmin.py (+0/-268)
controllers/assess.py (+0/-789)
controllers/auth.py (+0/-20)
controllers/budget.py (+0/-1468)
controllers/cr.py (+0/-404)
controllers/default.py (+0/-252)
controllers/delphi.py (+0/-505)
controllers/doc.py (+0/-221)
controllers/dvi.py (+0/-272)
controllers/dvr.py (+0/-40)
controllers/errors.py (+0/-71)
controllers/flood.py (+0/-132)
controllers/gis.py (+0/-2591)
controllers/hms.py (+0/-185)
controllers/impact.py (+0/-35)
controllers/importer.py (+0/-333)
controllers/inventory.py (+0/-139)
controllers/irs.py (+0/-166)
controllers/lms.py (+0/-172)
controllers/logs.py (+0/-443)
controllers/msg.py (+0/-842)
controllers/ocr.py (+0/-156)
controllers/org.py (+0/-250)
controllers/pf.py (+0/-328)
controllers/pr.py (+0/-473)
controllers/project.py (+0/-431)
controllers/rms.py (+0/-184)
controllers/supply.py (+0/-80)
controllers/survey.py (+0/-532)
controllers/sync.py (+0/-1153)
controllers/test.py (+0/-100)
controllers/ticket.py (+0/-99)
controllers/tool.py (+0/-114)
controllers/vol.py (+0/-1093)
controllers/xforms.py (+0/-341)
deployment-templates/models/000_config.py (+0/-393)
models/tool.py (+17/-3)
modules/EXIF.py (+0/-1813)
modules/arial10.py (+0/-154)
modules/fixed_datetime.py (+0/-421)
modules/geo/__init__.py (+0/-301)
modules/geo/enum.py (+0/-15)
modules/geo/func.py (+0/-49)
modules/geo/load.py (+0/-80)
modules/geo/query.py (+0/-139)
modules/geo/r.py (+0/-99)
modules/geo/spatial.py (+0/-51)
modules/geo/tree.py (+0/-82)
modules/geo/utils.py (+0/-68)
modules/geopy/__init__.py (+0/-3)
modules/geopy/distance.py (+0/-388)
modules/geopy/format.py (+0/-77)
modules/geopy/geocoders/__init__.py (+0/-1)
modules/geopy/geocoders/base.py (+0/-34)
modules/geopy/geocoders/dot_us.py (+0/-64)
modules/geopy/geocoders/google.py (+0/-169)
modules/geopy/geocoders/osm.py (+0/-47)
modules/geopy/geocoders/virtual_earth.py (+0/-69)
modules/geopy/geocoders/wiki_semantic.py (+0/-103)
modules/geopy/geocoders/yahoo.py (+0/-64)
modules/geopy/geocoders_old.py (+0/-765)
modules/geopy/geohash.py (+0/-66)
modules/geopy/location.py (+0/-27)
modules/geopy/parsers/__init__.py (+0/-1)
modules/geopy/parsers/base.py (+0/-10)
modules/geopy/parsers/gpx.py (+0/-379)
modules/geopy/parsers/html.py (+0/-143)
modules/geopy/parsers/iso8601.py (+0/-70)
modules/geopy/parsers/rdf.py (+0/-56)
modules/geopy/point.py (+0/-300)
modules/geopy/units.py (+0/-97)
modules/geopy/util.py (+0/-94)
modules/hs/lit/__init__.py (+0/-1)
modules/hs/lit/keywords.py (+0/-108)
modules/jsonrpclib.py (+0/-378)
modules/pygsm/LICENSE (+0/-27)
modules/pygsm/__init__.py (+0/-22)
modules/pygsm/autogsmmodem.py (+0/-109)
modules/pygsm/devicewrapper.py (+0/-108)
modules/pygsm/errors.py (+0/-107)
modules/pygsm/gsmcodecs/__init__.py (+0/-28)
modules/pygsm/gsmcodecs/gsm0338.py (+0/-520)
modules/pygsm/gsmcodecs/mappings/GSM0338.TXT (+0/-239)
modules/pygsm/gsmmodem.py (+0/-612)
modules/pygsm/gsmpdu.py (+0/-658)
modules/pygsm/message/__init__.py (+0/-6)
modules/pygsm/message/incoming.py (+0/-68)
modules/pygsm/message/outgoing.py (+0/-6)
modules/pygsm/pdusmshandler.py (+0/-213)
modules/pygsm/prober.py (+0/-55)
modules/pygsm/scanlinux.py (+0/-20)
modules/pygsm/scanmac.py (+0/-20)
modules/pygsm/scanwin32.py (+0/-243)
modules/pygsm/smshandler.py (+0/-26)
modules/pygsm/textsmshandler.py (+0/-248)
modules/pyparsing.py (+0/-3767)
modules/s3/__init__.py (+0/-80)
modules/s3/s3aaa.py (+0/-2565)
modules/s3/s3cfg.py (+0/-284)
modules/s3/s3crud.py (+0/-1551)
modules/s3/s3export.py (+0/-454)
modules/s3/s3gis.py (+0/-4335)
modules/s3/s3import.py (+0/-263)
modules/s3/s3model.py (+0/-775)
modules/s3/s3msg.py (+0/-594)
modules/s3/s3rest.py (+0/-2459)
modules/s3/s3search.py (+0/-505)
modules/s3/s3test.py (+0/-30)
modules/s3/s3tools.py (+0/-487)
modules/s3/s3utils.py (+0/-433)
modules/s3/s3validators.py (+0/-588)
modules/s3/s3vita.py (+0/-462)
modules/s3/s3widgets.py (+0/-1924)
modules/s3/s3xml.py (+0/-1278)
modules/s3/s3xrc.py (+0/-1946)
modules/sahana.py (+0/-340)
modules/savage/doc/color.rst (+0/-64)
modules/savage/doc/graph.rst (+0/-41)
modules/savage/graph/__init__.py (+0/-292)
modules/savage/graph/axes.py (+0/-150)
modules/savage/graph/base.py (+0/-721)
modules/savage/graph/canvas.py (+0/-571)
modules/savage/graph/reg.py (+0/-22)
modules/savage/graphics/__init__.py (+0/-103)
modules/savage/graphics/base.py (+0/-520)
modules/savage/graphics/color.py (+0/-76)
modules/savage/graphics/defs.py (+0/-35)
modules/savage/graphics/group.py (+0/-157)
modules/savage/graphics/shapes.py (+0/-609)
modules/savage/graphics/utils.py (+0/-102)
modules/savage/utils/dictionary.py (+0/-57)
modules/savage/utils/struct.py (+0/-235)
modules/tropo.py (+0/-667)
modules/wurfl.py (+0/-13921)
static/formats/agasti/import.xsl (+0/-117)
static/formats/fods/import.xsl (+0/-212)
static/formats/geojson/export.xsl (+0/-96)
static/formats/geojson/import.xsl (+0/-106)
static/formats/georss/export.xsl (+0/-92)
static/formats/gpx/export.xsl (+0/-123)
static/formats/gpx/import.xsl (+0/-110)
static/formats/have/export.xsl (+0/-635)
static/formats/have/import.xsl (+0/-527)
static/formats/kml/export.xsl (+0/-190)
static/formats/lmx/export.xsl (+0/-56)
static/formats/lmx/import.xsl (+0/-45)
static/formats/odk/import.xsl (+0/-31)
static/formats/osm/export.xsl (+0/-160)
static/formats/osm/import.xsl (+0/-299)
static/formats/pfif/export.xsl (+0/-215)
static/formats/pfif/import.xsl (+0/-193)
static/formats/rss/base.xsl (+0/-179)
static/formats/rss/export.xsl (+0/-195)
static/formats/s3json/export.xsl (+0/-9)
static/formats/s3json/import.xsl (+0/-9)
static/formats/tc/export.xsl (+0/-158)
static/formats/tc/import.xsl (+0/-54)
static/formats/ushahidi/import.xsl (+0/-159)
static/formats/xml/commons.xsl (+0/-79)
static/formats/xml/countries.xsl (+0/-321)
static/helper.html (+0/-32)
static/http-proxy.py (+0/-122)
static/img/gis/geosilk/readme.txt (+0/-28)
static/img/markers/canada/copyright.txt (+0/-1)
static/potlatch2/features/barrier_generic.svg (+0/-127)
static/potlatch2/features/paths__bike.svg (+0/-217)
static/potlatch2/features/paths__bridleway.svg (+0/-125)
static/potlatch2/features/paths__footway.svg (+0/-133)
static/potlatch2/features/paths__pedestrian.svg (+0/-137)
static/potlatch2/features/paths__steps.svg (+0/-125)
static/potlatch2/features/paths__unknown.svg (+0/-135)
static/potlatch2/features/pois/barrier_generic.svg (+0/-76)
static/potlatch2/features/pois/water_generic.svg (+0/-100)
static/potlatch2/features/power_high.svg (+0/-162)
static/potlatch2/features/power_low.svg (+0/-114)
static/potlatch2/features/transport__railway.svg (+0/-78)
static/potlatch2/features/transport__subway.svg (+0/-91)
static/potlatch2/features/transport__tram.svg (+0/-88)
static/potlatch2/features/waterway__canal.svg (+0/-176)
static/potlatch2/features/waterway__dam.svg (+0/-180)
static/potlatch2/features/waterway__river.svg (+0/-281)
static/potlatch2/features/waterway__stream.svg (+0/-162)
static/potlatch2/gpx.css (+0/-12)
static/potlatch2/imagery.xml (+0/-88)
static/potlatch2/map_features.xml (+0/-3346)
static/potlatch2/opencyclemap.css (+0/-160)
static/potlatch2/potlatch.css (+0/-282)
static/potlatch2/stylesheets.xml (+0/-22)
static/potlatch2/swfobject.js (+0/-8)
static/potlatch2/test.css (+0/-71)
static/potlatch2/wireframe.css (+0/-15)
static/robots.txt (+0/-2)
static/scripts/S3/S3.js (+0/-317)
static/scripts/S3/S3.min.js (+0/-559)
static/scripts/S3/ba-debug.min.js (+0/-12)
static/scripts/S3/colorpicker.js (+0/-484)
static/scripts/S3/excanvas.js (+0/-924)
static/scripts/S3/excanvas.min.js (+0/-35)
static/scripts/S3/fileuploader.js (+0/-1247)
static/scripts/S3/importer/import.js (+0/-71)
static/scripts/S3/importer/re_import.js (+0/-162)
static/scripts/S3/importer/similar_rows.js (+0/-151)
static/scripts/S3/importer/view1.js (+0/-238)
static/scripts/S3/importer/view2.js (+0/-68)
static/scripts/S3/importer/view3.js (+0/-253)
static/scripts/S3/importer/view4.js (+0/-374)
static/scripts/S3/jqplot_plugins/jqplot.BezierCurveRenderer.js (+0/-300)
static/scripts/S3/jqplot_plugins/jqplot.BezierCurveRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.barRenderer.js (+0/-629)
static/scripts/S3/jqplot_plugins/jqplot.barRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.blockRenderer.js (+0/-221)
static/scripts/S3/jqplot_plugins/jqplot.blockRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.bubbleRenderer.js (+0/-724)
static/scripts/S3/jqplot_plugins/jqplot.bubbleRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.canvasAxisLabelRenderer.js (+0/-187)
static/scripts/S3/jqplot_plugins/jqplot.canvasAxisLabelRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.canvasAxisTickRenderer.js (+0/-226)
static/scripts/S3/jqplot_plugins/jqplot.canvasAxisTickRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.canvasTextRenderer.js (+0/-408)
static/scripts/S3/jqplot_plugins/jqplot.canvasTextRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.categoryAxisRenderer.js (+0/-621)
static/scripts/S3/jqplot_plugins/jqplot.categoryAxisRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.ciParser.js (+0/-90)
static/scripts/S3/jqplot_plugins/jqplot.ciParser.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.cursor.js (+0/-952)
static/scripts/S3/jqplot_plugins/jqplot.cursor.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.dateAxisRenderer.js (+0/-313)
static/scripts/S3/jqplot_plugins/jqplot.dateAxisRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.donutRenderer.js (+0/-891)
static/scripts/S3/jqplot_plugins/jqplot.donutRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.dragable.js (+0/-206)
static/scripts/S3/jqplot_plugins/jqplot.dragable.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.enhancedLegendRenderer.js (+0/-186)
static/scripts/S3/jqplot_plugins/jqplot.enhancedLegendRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.funnelRenderer.js (+0/-919)
static/scripts/S3/jqplot_plugins/jqplot.funnelRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.highlighter.js (+0/-374)
static/scripts/S3/jqplot_plugins/jqplot.highlighter.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.json2.js (+0/-475)
static/scripts/S3/jqplot_plugins/jqplot.json2.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.logAxisRenderer.js (+0/-434)
static/scripts/S3/jqplot_plugins/jqplot.logAxisRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.mekkoAxisRenderer.js (+0/-595)
static/scripts/S3/jqplot_plugins/jqplot.mekkoAxisRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.mekkoRenderer.js (+0/-419)
static/scripts/S3/jqplot_plugins/jqplot.mekkoRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.meterGaugeRenderer.js (+0/-1129)
static/scripts/S3/jqplot_plugins/jqplot.meterGaugeRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.ohlcRenderer.js (+0/-343)
static/scripts/S3/jqplot_plugins/jqplot.ohlcRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.pieRenderer.js (+0/-766)
static/scripts/S3/jqplot_plugins/jqplot.pieRenderer.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.pointLabels.js (+0/-325)
static/scripts/S3/jqplot_plugins/jqplot.pointLabels.min.js (+0/-34)
static/scripts/S3/jqplot_plugins/jqplot.trendline.js (+0/-208)
static/scripts/S3/jqplot_plugins/jqplot.trendline.min.js (+0/-34)
static/scripts/S3/jquery.bgiframe.min.js (+0/-10)
static/scripts/S3/jquery.bsmselect.js (+0/-407)
static/scripts/S3/jquery.bsmselect.min.js (+0/-1)
static/scripts/S3/jquery.cluetip.js (+0/-553)
static/scripts/S3/jquery.colorbox-min.js (+0/-4)
static/scripts/S3/jquery.colorbox.js (+0/-788)
static/scripts/S3/jquery.dataTables.js (+0/-6691)
static/scripts/S3/jquery.dataTables.min.js (+0/-125)
static/scripts/S3/jquery.form-extension.js (+0/-508)
static/scripts/S3/jquery.jqplot.js (+0/-6983)
static/scripts/S3/jquery.jqplot.min.js (+0/-34)
static/scripts/S3/jquery.multiSelect.js (+0/-543)
static/scripts/S3/jquery.pstrength-min.1.2.js (+0/-7)
static/scripts/S3/jquery.selectboxes.js (+0/-533)
static/scripts/S3/jquery.selectboxes.pack.js (+0/-14)
static/scripts/S3/jquery.ui.autocomplete.js (+0/-595)
static/scripts/S3/jquery.ui.core.js (+0/-308)
static/scripts/S3/jquery.ui.datepicker.js (+0/-1757)
static/scripts/S3/jquery.ui.draggable.js (+0/-797)
static/scripts/S3/jquery.ui.droppable.js (+0/-285)
static/scripts/S3/jquery.ui.mouse.js (+0/-151)
static/scripts/S3/jquery.ui.position.js (+0/-252)
static/scripts/S3/jquery.ui.sortable.js (+0/-1071)
static/scripts/S3/jquery.ui.widget.js (+0/-262)
static/scripts/S3/jquery.validate.js (+0/-1146)
static/scripts/S3/jquery.validate.pack.js (+0/-15)
static/scripts/S3/labels.js (+0/-14)
static/scripts/S3/s3.checkboxes.widget.js (+0/-18)
static/scripts/S3/s3.locationselector.widget.js (+0/-914)
static/scripts/S3/s3.locationselector.widget.min.js (+0/-1)
static/scripts/S3/s3.multiselect.widget.js (+0/-188)
static/scripts/T2/fancyzoom.min.js (+0/-1)
static/scripts/T2/rating.js (+0/-77)
static/scripts/ext-2.2.1/CHANGES.html (+0/-62)
static/scripts/ext-2.2.1/INCLUDE_ORDER.txt (+0/-35)
static/scripts/ext-2.2.1/adapter/ext/ext-base.js (+0/-9)
static/scripts/ext-2.2.1/adapter/jquery/ext-jquery-adapter.js (+0/-1)
static/scripts/ext-2.2.1/adapter/jquery/jquery.js (+0/-3408)
static/scripts/ext-2.2.1/adapter/prototype/effects.js (+0/-1122)
static/scripts/ext-2.2.1/adapter/prototype/ext-prototype-adapter.js (+0/-1)
static/scripts/ext-2.2.1/adapter/prototype/prototype.js (+0/-4221)
static/scripts/ext-2.2.1/adapter/prototype/scriptaculous.js (+0/-58)
static/scripts/ext-2.2.1/adapter/yui/ext-yui-adapter.js (+0/-1)
static/scripts/ext-2.2.1/adapter/yui/yui-utilities.js (+0/-17)
static/scripts/ext-2.2.1/air/README.txt (+0/-8)
static/scripts/ext-2.2.1/air/air.jsb (+0/-394)
static/scripts/ext-2.2.1/air/ext-air.js (+0/-182)
static/scripts/ext-2.2.1/air/resources/air-resources.jsb (+0/-15)
static/scripts/ext-2.2.1/air/resources/ext-air.css (+0/-101)
static/scripts/ext-2.2.1/air/samples/tasks/.project (+0/-12)
static/scripts/ext-2.2.1/air/samples/tasks/LICENSE.TXT (+0/-6)
static/scripts/ext-2.2.1/air/samples/tasks/about.html (+0/-21)
static/scripts/ext-2.2.1/air/samples/tasks/adobe/AIRAliases.js (+0/-204)
static/scripts/ext-2.2.1/air/samples/tasks/adobe/AIRIntrospector.js (+0/-1948)
static/scripts/ext-2.2.1/air/samples/tasks/application.xml (+0/-25)
static/scripts/ext-2.2.1/air/samples/tasks/ext-2.0/adapter/ext/ext-base.js (+0/-2739)
static/scripts/ext-2.2.1/air/samples/tasks/ext-2.0/ext-all.js (+0/-33803)
static/scripts/ext-2.2.1/air/samples/tasks/ext-2.0/resources/css/ext-all.css (+0/-4144)
static/scripts/ext-2.2.1/air/samples/tasks/ext-2.0/resources/css/xtheme-gray.css (+0/-423)
static/scripts/ext-2.2.1/air/samples/tasks/ext-2.0/resources/license.txt (+0/-30)
static/scripts/ext-2.2.1/air/samples/tasks/ext-air/ext-air-debug.js (+0/-1604)
static/scripts/ext-2.2.1/air/samples/tasks/ext-air/ext-air.js (+0/-1604)
static/scripts/ext-2.2.1/air/samples/tasks/ext-air/resources/air-resources.jsb (+0/-14)
static/scripts/ext-2.2.1/air/samples/tasks/ext-air/resources/ext-air.css (+0/-101)
static/scripts/ext-2.2.1/air/samples/tasks/js/DateTimeField.js (+0/-384)
static/scripts/ext-2.2.1/air/samples/tasks/js/Exporter.js (+0/-60)
static/scripts/ext-2.2.1/air/samples/tasks/js/Importer.js (+0/-111)
static/scripts/ext-2.2.1/air/samples/tasks/js/ListLoader.js (+0/-60)
static/scripts/ext-2.2.1/air/samples/tasks/js/ListSelector.js (+0/-60)
static/scripts/ext-2.2.1/air/samples/tasks/js/ListStore.js (+0/-116)
static/scripts/ext-2.2.1/air/samples/tasks/js/ListTree.js (+0/-180)
static/scripts/ext-2.2.1/air/samples/tasks/js/Reminder.js (+0/-39)
static/scripts/ext-2.2.1/air/samples/tasks/js/SelectBox.js (+0/-199)
static/scripts/ext-2.2.1/air/samples/tasks/js/SwitchButton.js (+0/-97)
static/scripts/ext-2.2.1/air/samples/tasks/js/TaskGrid.js (+0/-249)
static/scripts/ext-2.2.1/air/samples/tasks/js/TaskStore.js (+0/-172)
static/scripts/ext-2.2.1/air/samples/tasks/js/TaskWindow.js (+0/-73)
static/scripts/ext-2.2.1/air/samples/tasks/js/Templates.js (+0/-29)
static/scripts/ext-2.2.1/air/samples/tasks/js/TextDate.js (+0/-53)
static/scripts/ext-2.2.1/air/samples/tasks/js/TreeSelector.js (+0/-290)
static/scripts/ext-2.2.1/air/samples/tasks/js/columns.js (+0/-167)
static/scripts/ext-2.2.1/air/samples/tasks/js/data.js (+0/-67)
static/scripts/ext-2.2.1/air/samples/tasks/js/ext-config.js (+0/-23)
static/scripts/ext-2.2.1/air/samples/tasks/main.css (+0/-347)
static/scripts/ext-2.2.1/air/samples/tasks/main.html (+0/-40)
static/scripts/ext-2.2.1/air/samples/tasks/main.js (+0/-424)
static/scripts/ext-2.2.1/air/samples/tasks/mimetype (+0/-1)
static/scripts/ext-2.2.1/air/samples/tasks/preferences.css (+0/-28)
static/scripts/ext-2.2.1/air/samples/tasks/preferences.html (+0/-133)
static/scripts/ext-2.2.1/air/samples/tasks/preferences.js (+0/-47)
static/scripts/ext-2.2.1/air/samples/tasks/reminder.css (+0/-39)
static/scripts/ext-2.2.1/air/samples/tasks/reminder.html (+0/-58)
static/scripts/ext-2.2.1/air/samples/tasks/reminder.js (+0/-64)
static/scripts/ext-2.2.1/air/samples/tasks/task.css (+0/-34)
static/scripts/ext-2.2.1/air/samples/tasks/task.html (+0/-27)
static/scripts/ext-2.2.1/air/samples/tasks/task.js (+0/-297)
static/scripts/ext-2.2.1/air/src/App.js (+0/-18)
static/scripts/ext-2.2.1/air/src/Clipboard.js (+0/-74)
static/scripts/ext-2.2.1/air/src/Debug.js (+0/-31)
static/scripts/ext-2.2.1/air/src/FileProvider.js (+0/-75)
static/scripts/ext-2.2.1/air/src/FileTreeLoader.js (+0/-83)
static/scripts/ext-2.2.1/air/src/MusicPlayer.js (+0/-198)
static/scripts/ext-2.2.1/air/src/NativeDD.js (+0/-60)
static/scripts/ext-2.2.1/air/src/NativeObservable.js (+0/-35)
static/scripts/ext-2.2.1/air/src/NativeWindow.js (+0/-430)
static/scripts/ext-2.2.1/air/src/Notify.js (+0/-59)
static/scripts/ext-2.2.1/air/src/Sound.js (+0/-26)
static/scripts/ext-2.2.1/air/src/SystemMenu.js (+0/-118)
static/scripts/ext-2.2.1/air/src/SystemTray.js (+0/-122)
static/scripts/ext-2.2.1/air/src/VideoPanel.js (+0/-71)
static/scripts/ext-2.2.1/air/src/air.jsb (+0/-21)
static/scripts/ext-2.2.1/air/src/ext-air-adapter.js (+0/-834)
static/scripts/ext-2.2.1/air/src/sql/AirConnection.js (+0/-86)
static/scripts/ext-2.2.1/air/src/sql/Connection.js (+0/-98)
static/scripts/ext-2.2.1/air/src/sql/Proxy.js (+0/-114)
static/scripts/ext-2.2.1/air/src/sql/SQLiteStore.js (+0/-49)
static/scripts/ext-2.2.1/air/src/sql/Table.js (+0/-94)
static/scripts/ext-2.2.1/ext-all-debug.js (+0/-37063)
static/scripts/ext-2.2.1/ext-all.js (+0/-9)
static/scripts/ext-2.2.1/ext-core-debug.js (+0/-5913)
static/scripts/ext-2.2.1/ext-core.js (+0/-9)
static/scripts/ext-2.2.1/license.txt (+0/-42)
static/scripts/ext-2.2.1/resources/css/README.txt (+0/-3)
static/scripts/ext-2.2.1/resources/css/borders.css (+0/-61)
static/scripts/ext-2.2.1/resources/css/box.css (+0/-111)
static/scripts/ext-2.2.1/resources/css/button.css (+0/-161)
static/scripts/ext-2.2.1/resources/css/combo.css (+0/-55)
static/scripts/ext-2.2.1/resources/css/core.css (+0/-317)
static/scripts/ext-2.2.1/resources/css/date-picker.css (+0/-247)
static/scripts/ext-2.2.1/resources/css/dd.css (+0/-75)
static/scripts/ext-2.2.1/resources/css/debug.css (+0/-37)
static/scripts/ext-2.2.1/resources/css/dialog.css (+0/-69)
static/scripts/ext-2.2.1/resources/css/editor.css (+0/-66)
static/scripts/ext-2.2.1/resources/css/ext-all.css (+0/-9)
static/scripts/ext-2.2.1/resources/css/form.css (+0/-559)
static/scripts/ext-2.2.1/resources/css/grid.css (+0/-554)
static/scripts/ext-2.2.1/resources/css/layout.css (+0/-273)
static/scripts/ext-2.2.1/resources/css/menu.css (+0/-146)
static/scripts/ext-2.2.1/resources/css/panel.css (+0/-424)
static/scripts/ext-2.2.1/resources/css/progress.css (+0/-43)
static/scripts/ext-2.2.1/resources/css/qtips.css (+0/-134)
static/scripts/ext-2.2.1/resources/css/reset-min.css (+0/-9)
static/scripts/ext-2.2.1/resources/css/reset.css (+0/-9)
static/scripts/ext-2.2.1/resources/css/resizable.css (+0/-143)
static/scripts/ext-2.2.1/resources/css/slider.css (+0/-90)
static/scripts/ext-2.2.1/resources/css/tabs.css (+0/-362)
static/scripts/ext-2.2.1/resources/css/toolbar.css (+0/-183)
static/scripts/ext-2.2.1/resources/css/tree.css (+0/-254)
static/scripts/ext-2.2.1/resources/css/window.css (+0/-208)
static/scripts/ext-2.2.1/resources/css/xtheme-gray.css (+0/-416)
static/scripts/ext-2.2.1/resources/css/xtheme-slate.css (+0/-804)
static/scripts/ext-2.2.1/resources/resources.jsb (+0/-787)
static/scripts/ext-2.2.1/source/adapter/ext-base.js (+0/-2189)
static/scripts/ext-2.2.1/source/adapter/jquery-bridge.js (+0/-541)
static/scripts/ext-2.2.1/source/adapter/prototype-bridge.js (+0/-548)
static/scripts/ext-2.2.1/source/adapter/yui-bridge.js (+0/-342)
static/scripts/ext-2.2.1/source/core/CompositeElement.js (+0/-371)
static/scripts/ext-2.2.1/source/core/DomHelper.js (+0/-419)
static/scripts/ext-2.2.1/source/core/DomQuery.js (+0/-816)
static/scripts/ext-2.2.1/source/core/Element.js (+0/-3062)
static/scripts/ext-2.2.1/source/core/EventManager.js (+0/-934)
static/scripts/ext-2.2.1/source/core/Ext.js (+0/-1060)
static/scripts/ext-2.2.1/source/core/Fx.js (+0/-1020)
static/scripts/ext-2.2.1/source/core/Template.js (+0/-242)
static/scripts/ext-2.2.1/source/core/UpdateManager.js (+0/-529)
static/scripts/ext-2.2.1/source/data/ArrayReader.js (+0/-73)
static/scripts/ext-2.2.1/source/data/Connection.js (+0/-511)
static/scripts/ext-2.2.1/source/data/DataField.js (+0/-165)
static/scripts/ext-2.2.1/source/data/DataProxy.js (+0/-43)
static/scripts/ext-2.2.1/source/data/DataReader.js (+0/-35)
static/scripts/ext-2.2.1/source/data/GroupingStore.js (+0/-118)
static/scripts/ext-2.2.1/source/data/HttpProxy.js (+0/-138)
static/scripts/ext-2.2.1/source/data/JsonReader.js (+0/-231)
static/scripts/ext-2.2.1/source/data/JsonStore.js (+0/-57)
static/scripts/ext-2.2.1/source/data/MemoryProxy.js (+0/-67)
static/scripts/ext-2.2.1/source/data/Record.js (+0/-301)
static/scripts/ext-2.2.1/source/data/ScriptTagProxy.js (+0/-218)
static/scripts/ext-2.2.1/source/data/SimpleStore.js (+0/-39)
static/scripts/ext-2.2.1/source/data/SortTypes.js (+0/-95)
static/scripts/ext-2.2.1/source/data/Store.js (+0/-857)
static/scripts/ext-2.2.1/source/data/StoreMgr.js (+0/-58)
static/scripts/ext-2.2.1/source/data/Tree.js (+0/-764)
static/scripts/ext-2.2.1/source/data/XmlReader.js (+0/-129)
static/scripts/ext-2.2.1/source/dd/DDCore.js (+0/-2987)
static/scripts/ext-2.2.1/source/dd/DragSource.js (+0/-367)
static/scripts/ext-2.2.1/source/dd/DragTracker.js (+0/-160)
static/scripts/ext-2.2.1/source/dd/DragZone.js (+0/-79)
static/scripts/ext-2.2.1/source/dd/DropTarget.js (+0/-117)
static/scripts/ext-2.2.1/source/dd/DropZone.js (+0/-208)
static/scripts/ext-2.2.1/source/dd/Registry.js (+0/-129)
static/scripts/ext-2.2.1/source/dd/ScrollManager.js (+0/-203)
static/scripts/ext-2.2.1/source/dd/StatusProxy.js (+0/-173)
static/scripts/ext-2.2.1/source/debug.js (+0/-491)
static/scripts/ext-2.2.1/source/ext.jsb (+0/-736)
static/scripts/ext-2.2.1/source/license.txt (+0/-42)
static/scripts/ext-2.2.1/source/locale/ext-lang-af.js (+0/-178)
static/scripts/ext-2.2.1/source/locale/ext-lang-bg.js (+0/-272)
static/scripts/ext-2.2.1/source/locale/ext-lang-ca.js (+0/-309)
static/scripts/ext-2.2.1/source/locale/ext-lang-cs.js (+0/-287)
static/scripts/ext-2.2.1/source/locale/ext-lang-da.js (+0/-290)
static/scripts/ext-2.2.1/source/locale/ext-lang-de.js (+0/-301)
static/scripts/ext-2.2.1/source/locale/ext-lang-el_GR.js (+0/-311)
static/scripts/ext-2.2.1/source/locale/ext-lang-en.js (+0/-309)
static/scripts/ext-2.2.1/source/locale/ext-lang-en_GB.js (+0/-309)
static/scripts/ext-2.2.1/source/locale/ext-lang-es.js (+0/-312)
static/scripts/ext-2.2.1/source/locale/ext-lang-fa.js (+0/-266)
static/scripts/ext-2.2.1/source/locale/ext-lang-fi.js (+0/-296)
static/scripts/ext-2.2.1/source/locale/ext-lang-fr.js (+0/-329)
static/scripts/ext-2.2.1/source/locale/ext-lang-fr_CA.js (+0/-212)
static/scripts/ext-2.2.1/source/locale/ext-lang-gr.js (+0/-169)
static/scripts/ext-2.2.1/source/locale/ext-lang-he.js (+0/-286)
static/scripts/ext-2.2.1/source/locale/ext-lang-hr.js (+0/-297)
static/scripts/ext-2.2.1/source/locale/ext-lang-hu.js (+0/-297)
static/scripts/ext-2.2.1/source/locale/ext-lang-id.js (+0/-296)
static/scripts/ext-2.2.1/source/locale/ext-lang-it.js (+0/-289)
static/scripts/ext-2.2.1/source/locale/ext-lang-ja.js (+0/-312)
static/scripts/ext-2.2.1/source/locale/ext-lang-ko.js (+0/-261)
static/scripts/ext-2.2.1/source/locale/ext-lang-lt.js (+0/-299)
static/scripts/ext-2.2.1/source/locale/ext-lang-lv.js (+0/-170)
static/scripts/ext-2.2.1/source/locale/ext-lang-mk.js (+0/-170)
static/scripts/ext-2.2.1/source/locale/ext-lang-nl.js (+0/-317)
static/scripts/ext-2.2.1/source/locale/ext-lang-no_NB.js (+0/-288)
static/scripts/ext-2.2.1/source/locale/ext-lang-no_NN.js (+0/-288)
static/scripts/ext-2.2.1/source/locale/ext-lang-pl.js (+0/-298)
static/scripts/ext-2.2.1/source/locale/ext-lang-pt.js (+0/-254)
static/scripts/ext-2.2.1/source/locale/ext-lang-pt_BR.js (+0/-304)
static/scripts/ext-2.2.1/source/locale/ext-lang-pt_PT.js (+0/-292)
static/scripts/ext-2.2.1/source/locale/ext-lang-ro.js (+0/-289)
static/scripts/ext-2.2.1/source/locale/ext-lang-ru.js (+0/-313)
static/scripts/ext-2.2.1/source/locale/ext-lang-sk.js (+0/-176)
static/scripts/ext-2.2.1/source/locale/ext-lang-sl.js (+0/-170)
static/scripts/ext-2.2.1/source/locale/ext-lang-sr.js (+0/-173)
static/scripts/ext-2.2.1/source/locale/ext-lang-sr_RS.js (+0/-172)
static/scripts/ext-2.2.1/source/locale/ext-lang-sv_SE.js (+0/-172)
static/scripts/ext-2.2.1/source/locale/ext-lang-th.js (+0/-288)
static/scripts/ext-2.2.1/source/locale/ext-lang-tr.js (+0/-300)
static/scripts/ext-2.2.1/source/locale/ext-lang-ukr.js (+0/-252)
static/scripts/ext-2.2.1/source/locale/ext-lang-vn.js (+0/-175)
static/scripts/ext-2.2.1/source/locale/ext-lang-zh_CN.js (+0/-168)
static/scripts/ext-2.2.1/source/locale/ext-lang-zh_TW.js (+0/-172)
static/scripts/ext-2.2.1/source/state/CookieProvider.js (+0/-93)
static/scripts/ext-2.2.1/source/state/Provider.js (+0/-129)
static/scripts/ext-2.2.1/source/state/StateManager.js (+0/-71)
static/scripts/ext-2.2.1/source/util/CSS.js (+0/-163)
static/scripts/ext-2.2.1/source/util/ClickRepeater.js (+0/-163)
static/scripts/ext-2.2.1/source/util/Date.js (+0/-1063)
static/scripts/ext-2.2.1/source/util/DelayedTask.js (+0/-62)
static/scripts/ext-2.2.1/source/util/Format.js (+0/-233)
static/scripts/ext-2.2.1/source/util/History.js (+0/-205)
static/scripts/ext-2.2.1/source/util/JSON.js (+0/-149)
static/scripts/ext-2.2.1/source/util/KeyMap.js (+0/-226)
static/scripts/ext-2.2.1/source/util/KeyNav.js (+0/-151)
static/scripts/ext-2.2.1/source/util/MixedCollection.js (+0/-577)
static/scripts/ext-2.2.1/source/util/Observable.js (+0/-475)
static/scripts/ext-2.2.1/source/util/TaskMgr.js (+0/-163)
static/scripts/ext-2.2.1/source/util/TextMetrics.js (+0/-121)
static/scripts/ext-2.2.1/source/util/XTemplate.js (+0/-356)
static/scripts/ext-2.2.1/source/widgets/Action.js (+0/-233)
static/scripts/ext-2.2.1/source/widgets/BoxComponent.js (+0/-361)
static/scripts/ext-2.2.1/source/widgets/Button.js (+0/-635)
static/scripts/ext-2.2.1/source/widgets/ColorPalette.js (+0/-149)
static/scripts/ext-2.2.1/source/widgets/Component.js (+0/-1079)
static/scripts/ext-2.2.1/source/widgets/ComponentMgr.js (+0/-113)
static/scripts/ext-2.2.1/source/widgets/Container.js (+0/-632)
static/scripts/ext-2.2.1/source/widgets/CycleButton.js (+0/-184)
static/scripts/ext-2.2.1/source/widgets/DataView.js (+0/-724)
static/scripts/ext-2.2.1/source/widgets/DatePicker.js (+0/-725)
static/scripts/ext-2.2.1/source/widgets/Editor.js (+0/-364)
static/scripts/ext-2.2.1/source/widgets/Layer.js (+0/-452)
static/scripts/ext-2.2.1/source/widgets/LoadMask.js (+0/-125)
static/scripts/ext-2.2.1/source/widgets/MessageBox.js (+0/-624)
static/scripts/ext-2.2.1/source/widgets/PagingToolbar.js (+0/-358)
static/scripts/ext-2.2.1/source/widgets/Panel.js (+0/-1414)
static/scripts/ext-2.2.1/source/widgets/PanelDD.js (+0/-156)
static/scripts/ext-2.2.1/source/widgets/ProgressBar.js (+0/-294)
static/scripts/ext-2.2.1/source/widgets/Resizable.js (+0/-699)
static/scripts/ext-2.2.1/source/widgets/Shadow.js (+0/-193)
static/scripts/ext-2.2.1/source/widgets/Slider.js (+0/-421)
static/scripts/ext-2.2.1/source/widgets/SplitBar.js (+0/-433)
static/scripts/ext-2.2.1/source/widgets/SplitButton.js (+0/-198)
static/scripts/ext-2.2.1/source/widgets/StatusBar.js (+0/-406)
static/scripts/ext-2.2.1/source/widgets/TabPanel.js (+0/-1035)
static/scripts/ext-2.2.1/source/widgets/Toolbar.js (+0/-604)
static/scripts/ext-2.2.1/source/widgets/Viewport.js (+0/-137)
static/scripts/ext-2.2.1/source/widgets/Window.js (+0/-904)
static/scripts/ext-2.2.1/source/widgets/WindowManager.js (+0/-189)
static/scripts/ext-2.2.1/source/widgets/form/Action.js (+0/-409)
static/scripts/ext-2.2.1/source/widgets/form/BasicForm.js (+0/-599)
static/scripts/ext-2.2.1/source/widgets/form/Checkbox.js (+0/-285)
static/scripts/ext-2.2.1/source/widgets/form/CheckboxGroup.js (+0/-249)
static/scripts/ext-2.2.1/source/widgets/form/Combo.js (+0/-1015)
static/scripts/ext-2.2.1/source/widgets/form/DateField.js (+0/-377)
static/scripts/ext-2.2.1/source/widgets/form/Field.js (+0/-681)
static/scripts/ext-2.2.1/source/widgets/form/FieldSet.js (+0/-252)
static/scripts/ext-2.2.1/source/widgets/form/Form.js (+0/-272)
static/scripts/ext-2.2.1/source/widgets/form/Hidden.js (+0/-40)
static/scripts/ext-2.2.1/source/widgets/form/HtmlEditor.js (+0/-1147)
static/scripts/ext-2.2.1/source/widgets/form/Label.js (+0/-63)
static/scripts/ext-2.2.1/source/widgets/form/NumberField.js (+0/-148)
static/scripts/ext-2.2.1/source/widgets/form/Radio.js (+0/-80)
static/scripts/ext-2.2.1/source/widgets/form/RadioGroup.js (+0/-36)
static/scripts/ext-2.2.1/source/widgets/form/TextArea.js (+0/-117)
static/scripts/ext-2.2.1/source/widgets/form/TextField.js (+0/-405)
static/scripts/ext-2.2.1/source/widgets/form/TimeField.js (+0/-157)
static/scripts/ext-2.2.1/source/widgets/form/TriggerField.js (+0/-280)
static/scripts/ext-2.2.1/source/widgets/form/VTypes.js (+0/-104)
static/scripts/ext-2.2.1/source/widgets/grid/AbstractSelectionModel.js (+0/-49)
static/scripts/ext-2.2.1/source/widgets/grid/CellSelectionModel.js (+0/-252)
static/scripts/ext-2.2.1/source/widgets/grid/CheckboxSelectionModel.js (+0/-87)
static/scripts/ext-2.2.1/source/widgets/grid/ColumnDD.js (+0/-219)
static/scripts/ext-2.2.1/source/widgets/grid/ColumnModel.js (+0/-590)
static/scripts/ext-2.2.1/source/widgets/grid/ColumnSplitDD.js (+0/-64)
static/scripts/ext-2.2.1/source/widgets/grid/EditorGrid.js (+0/-273)
static/scripts/ext-2.2.1/source/widgets/grid/GridDD.js (+0/-101)
static/scripts/ext-2.2.1/source/widgets/grid/GridEditor.js (+0/-23)
static/scripts/ext-2.2.1/source/widgets/grid/GridPanel.js (+0/-882)
static/scripts/ext-2.2.1/source/widgets/grid/GridView.js (+0/-1662)
static/scripts/ext-2.2.1/source/widgets/grid/GroupingView.js (+0/-492)
static/scripts/ext-2.2.1/source/widgets/grid/PropertyGrid.js (+0/-369)
static/scripts/ext-2.2.1/source/widgets/grid/RowNumberer.js (+0/-63)
static/scripts/ext-2.2.1/source/widgets/grid/RowSelectionModel.js (+0/-487)
static/scripts/ext-2.2.1/source/widgets/layout/AbsoluteLayout.js (+0/-60)
static/scripts/ext-2.2.1/source/widgets/layout/AccordionLayout.js (+0/-164)
static/scripts/ext-2.2.1/source/widgets/layout/AnchorLayout.js (+0/-148)
static/scripts/ext-2.2.1/source/widgets/layout/BorderLayout.js (+0/-1023)
static/scripts/ext-2.2.1/source/widgets/layout/CardLayout.js (+0/-112)
static/scripts/ext-2.2.1/source/widgets/layout/ColumnLayout.js (+0/-137)
static/scripts/ext-2.2.1/source/widgets/layout/ContainerLayout.js (+0/-162)
static/scripts/ext-2.2.1/source/widgets/layout/FitLayout.js (+0/-49)
static/scripts/ext-2.2.1/source/widgets/layout/FormLayout.js (+0/-205)
static/scripts/ext-2.2.1/source/widgets/layout/TableLayout.js (+0/-178)
static/scripts/ext-2.2.1/source/widgets/menu/Adapter.js (+0/-59)
static/scripts/ext-2.2.1/source/widgets/menu/BaseItem.js (+0/-163)
static/scripts/ext-2.2.1/source/widgets/menu/CheckItem.js (+0/-114)
static/scripts/ext-2.2.1/source/widgets/menu/ColorItem.js (+0/-26)
static/scripts/ext-2.2.1/source/widgets/menu/ColorMenu.js (+0/-39)
static/scripts/ext-2.2.1/source/widgets/menu/DateItem.js (+0/-37)
static/scripts/ext-2.2.1/source/widgets/menu/DateMenu.js (+0/-47)
static/scripts/ext-2.2.1/source/widgets/menu/Item.js (+0/-192)
static/scripts/ext-2.2.1/source/widgets/menu/Menu.js (+0/-596)
static/scripts/ext-2.2.1/source/widgets/menu/MenuMgr.js (+0/-213)
static/scripts/ext-2.2.1/source/widgets/menu/Separator.js (+0/-40)
static/scripts/ext-2.2.1/source/widgets/menu/TextItem.js (+0/-46)
static/scripts/ext-2.2.1/source/widgets/tips/QuickTip.js (+0/-180)
static/scripts/ext-2.2.1/source/widgets/tips/QuickTips.js (+0/-161)
static/scripts/ext-2.2.1/source/widgets/tips/Tip.js (+0/-157)
static/scripts/ext-2.2.1/source/widgets/tips/ToolTip.js (+0/-207)
static/scripts/ext-2.2.1/source/widgets/tree/AsyncTreeNode.js (+0/-115)
static/scripts/ext-2.2.1/source/widgets/tree/TreeDragZone.js (+0/-84)
static/scripts/ext-2.2.1/source/widgets/tree/TreeDropZone.js (+0/-300)
static/scripts/ext-2.2.1/source/widgets/tree/TreeEditor.js (+0/-155)
static/scripts/ext-2.2.1/source/widgets/tree/TreeEventModel.js (+0/-157)
static/scripts/ext-2.2.1/source/widgets/tree/TreeFilter.js (+0/-116)
static/scripts/ext-2.2.1/source/widgets/tree/TreeLoader.js (+0/-281)
static/scripts/ext-2.2.1/source/widgets/tree/TreeNode.js (+0/-526)
static/scripts/ext-2.2.1/source/widgets/tree/TreeNodeUI.js (+0/-627)
static/scripts/ext-2.2.1/source/widgets/tree/TreePanel.js (+0/-826)
static/scripts/ext-2.2.1/source/widgets/tree/TreeSelectionModel.js (+0/-311)
static/scripts/ext-2.2.1/source/widgets/tree/TreeSorter.js (+0/-108)
static/scripts/ext-3.03/INCLUDE_ORDER.txt (+0/-35)
static/scripts/ext-3.03/adapter/ext/ext-base-debug.js (+0/-3645)
static/scripts/ext-3.03/adapter/ext/ext-base.js (+0/-7)
static/scripts/ext-3.03/adapter/jquery/ext-jquery-adapter-debug.js (+0/-2389)
static/scripts/ext-3.03/adapter/jquery/ext-jquery-adapter.js (+0/-7)
static/scripts/ext-3.03/adapter/prototype/ext-prototype-adapter-debug.js (+0/-2419)
static/scripts/ext-3.03/adapter/prototype/ext-prototype-adapter.js (+0/-7)
static/scripts/ext-3.03/adapter/yui/ext-yui-adapter-debug.js (+0/-2189)
static/scripts/ext-3.03/adapter/yui/ext-yui-adapter.js (+0/-7)
static/scripts/ext-3.03/examples/App.js (+0/-236)
static/scripts/ext-3.03/examples/RowEditor.js (+0/-554)
static/scripts/ext-3.03/ext-all-debug.js (+0/-67473)
static/scripts/ext-3.03/ext-all.js (+0/-11)
static/scripts/ext-3.03/ext-elastic-text-area.js (+0/-100)
static/scripts/ext-3.03/ext.jsb2 (+0/-1247)
static/scripts/ext-3.03/license.txt (+0/-42)
static/scripts/ext-3.03/pkgs/cmp-foundation-debug.js (+0/-11562)
static/scripts/ext-3.03/pkgs/cmp-foundation.js (+0/-7)
static/scripts/ext-3.03/pkgs/data-foundation-debug.js (+0/-4020)
static/scripts/ext-3.03/pkgs/data-foundation.js (+0/-7)
static/scripts/ext-3.03/pkgs/data-grouping-debug.js (+0/-139)
static/scripts/ext-3.03/pkgs/data-grouping.js (+0/-7)
static/scripts/ext-3.03/pkgs/data-json-debug.js (+0/-658)
static/scripts/ext-3.03/pkgs/data-json.js (+0/-7)
static/scripts/ext-3.03/pkgs/data-list-views-debug.js (+0/-1301)
static/scripts/ext-3.03/pkgs/data-list-views.js (+0/-7)
static/scripts/ext-3.03/pkgs/data-xml-debug.js (+0/-474)
static/scripts/ext-3.03/pkgs/data-xml.js (+0/-7)
static/scripts/ext-3.03/pkgs/direct-debug.js (+0/-1131)
static/scripts/ext-3.03/pkgs/direct.js (+0/-7)
static/scripts/ext-3.03/pkgs/ext-dd-debug.js (+0/-4567)
static/scripts/ext-3.03/pkgs/ext-dd.js (+0/-7)
static/scripts/ext-3.03/pkgs/ext-foundation-debug.js (+0/-13766)
static/scripts/ext-3.03/pkgs/ext-foundation.js (+0/-7)
static/scripts/ext-3.03/pkgs/pkg-buttons-debug.js (+0/-1072)
static/scripts/ext-3.03/pkgs/pkg-buttons.js (+0/-7)
static/scripts/ext-3.03/pkgs/pkg-charts-debug.js (+0/-1639)
static/scripts/ext-3.03/pkgs/pkg-charts.js (+0/-10)
static/scripts/ext-3.03/pkgs/pkg-forms-debug.js (+0/-7904)
static/scripts/ext-3.03/pkgs/pkg-forms.js (+0/-7)
static/scripts/ext-3.03/pkgs/pkg-grid-editor-debug.js (+0/-603)
static/scripts/ext-3.03/pkgs/pkg-grid-editor.js (+0/-7)
static/scripts/ext-3.03/pkgs/pkg-grid-foundation-debug.js (+0/-4846)
static/scripts/ext-3.03/pkgs/pkg-grid-foundation.js (+0/-7)
static/scripts/ext-3.03/pkgs/pkg-grid-grouping-debug.js (+0/-527)
static/scripts/ext-3.03/pkgs/pkg-grid-grouping.js (+0/-7)
static/scripts/ext-3.03/pkgs/pkg-grid-property-debug.js (+0/-372)
static/scripts/ext-3.03/pkgs/pkg-grid-property.js (+0/-7)
static/scripts/ext-3.03/pkgs/pkg-history-debug.js (+0/-203)
static/scripts/ext-3.03/pkgs/pkg-history.js (+0/-7)
static/scripts/ext-3.03/pkgs/pkg-menu-debug.js (+0/-1745)
static/scripts/ext-3.03/pkgs/pkg-menu.js (+0/-7)
static/scripts/ext-3.03/pkgs/pkg-tabs-debug.js (+0/-1108)
static/scripts/ext-3.03/pkgs/pkg-tabs.js (+0/-7)
static/scripts/ext-3.03/pkgs/pkg-tips-debug.js (+0/-1040)
static/scripts/ext-3.03/pkgs/pkg-tips.js (+0/-7)
static/scripts/ext-3.03/pkgs/pkg-toolbars-debug.js (+0/-1442)
static/scripts/ext-3.03/pkgs/pkg-toolbars.js (+0/-7)
static/scripts/ext-3.03/pkgs/pkg-tree-debug.js (+0/-4553)
static/scripts/ext-3.03/pkgs/pkg-tree.js (+0/-7)
static/scripts/ext-3.03/pkgs/resizable-debug.js (+0/-760)
static/scripts/ext-3.03/pkgs/resizable.js (+0/-7)
static/scripts/ext-3.03/pkgs/state-debug.js (+0/-276)
static/scripts/ext-3.03/pkgs/state.js (+0/-7)
static/scripts/ext-3.03/pkgs/window-debug.js (+0/-1914)
static/scripts/ext-3.03/pkgs/window.js (+0/-7)
static/scripts/ext-3.03/resources/css/README.txt (+0/-3)
static/scripts/ext-3.03/resources/css/ext-all-notheme.css (+0/-5101)
static/scripts/ext-3.03/resources/css/ext-all.css (+0/-6738)
static/scripts/ext-3.03/resources/css/ext-all.min.css (+0/-1)
static/scripts/ext-3.03/resources/css/reset-min.css (+0/-7)
static/scripts/ext-3.03/resources/css/structure/borders.css (+0/-54)
static/scripts/ext-3.03/resources/css/structure/box.css (+0/-80)
static/scripts/ext-3.03/resources/css/structure/button.css (+0/-445)
static/scripts/ext-3.03/resources/css/structure/combo.css (+0/-45)
static/scripts/ext-3.03/resources/css/structure/core.css (+0/-326)
static/scripts/ext-3.03/resources/css/structure/date-picker.css (+0/-265)
static/scripts/ext-3.03/resources/css/structure/dd.css (+0/-61)
static/scripts/ext-3.03/resources/css/structure/debug.css (+0/-26)
static/scripts/ext-3.03/resources/css/structure/dialog.css (+0/-62)
static/scripts/ext-3.03/resources/css/structure/editor.css (+0/-92)
static/scripts/ext-3.03/resources/css/structure/form.css (+0/-562)
static/scripts/ext-3.03/resources/css/structure/grid.css (+0/-552)
static/scripts/ext-3.03/resources/css/structure/layout.css (+0/-296)
static/scripts/ext-3.03/resources/css/structure/list-view.css (+0/-89)
static/scripts/ext-3.03/resources/css/structure/menu.css (+0/-205)
static/scripts/ext-3.03/resources/css/structure/panel-reset.css (+0/-130)
static/scripts/ext-3.03/resources/css/structure/panel.css (+0/-468)
static/scripts/ext-3.03/resources/css/structure/progress.css (+0/-46)
static/scripts/ext-3.03/resources/css/structure/qtips.css (+0/-153)
static/scripts/ext-3.03/resources/css/structure/reset.css (+0/-7)
static/scripts/ext-3.03/resources/css/structure/resizable.css (+0/-149)
static/scripts/ext-3.03/resources/css/structure/slider.css (+0/-103)
static/scripts/ext-3.03/resources/css/structure/tabs.css (+0/-372)
static/scripts/ext-3.03/resources/css/structure/toolbar.css (+0/-242)
static/scripts/ext-3.03/resources/css/structure/tree.css (+0/-214)
static/scripts/ext-3.03/resources/css/structure/window.css (+0/-222)
static/scripts/ext-3.03/resources/css/visual/borders.css (+0/-25)
static/scripts/ext-3.03/resources/css/visual/box.css (+0/-74)
static/scripts/ext-3.03/resources/css/visual/button.css (+0/-94)
static/scripts/ext-3.03/resources/css/visual/combo.css (+0/-43)
static/scripts/ext-3.03/resources/css/visual/core.css (+0/-80)
static/scripts/ext-3.03/resources/css/visual/date-picker.css (+0/-143)
static/scripts/ext-3.03/resources/css/visual/dd.css (+0/-29)
static/scripts/ext-3.03/resources/css/visual/debug.css (+0/-24)
static/scripts/ext-3.03/resources/css/visual/dialog.css (+0/-34)
static/scripts/ext-3.03/resources/css/visual/editor.css (+0/-13)
static/scripts/ext-3.03/resources/css/visual/form.css (+0/-117)
static/scripts/ext-3.03/resources/css/visual/grid.css (+0/-268)
static/scripts/ext-3.03/resources/css/visual/layout.css (+0/-53)
static/scripts/ext-3.03/resources/css/visual/list-view.css (+0/-37)
static/scripts/ext-3.03/resources/css/visual/menu.css (+0/-87)
static/scripts/ext-3.03/resources/css/visual/panel.css (+0/-87)
static/scripts/ext-3.03/resources/css/visual/progress.css (+0/-32)
static/scripts/ext-3.03/resources/css/visual/qtips.css (+0/-44)
static/scripts/ext-3.03/resources/css/visual/resizable.css (+0/-43)
static/scripts/ext-3.03/resources/css/visual/slider.css (+0/-21)
static/scripts/ext-3.03/resources/css/visual/tabs.css (+0/-119)
static/scripts/ext-3.03/resources/css/visual/toolbar.css (+0/-95)
static/scripts/ext-3.03/resources/css/visual/tree.css (+0/-152)
static/scripts/ext-3.03/resources/css/visual/window.css (+0/-86)
static/scripts/ext-3.03/resources/css/xtheme-blue.css (+0/-1644)
static/scripts/ext-3.03/resources/css/xtheme-gray.css (+0/-1679)
static/scripts/ext-3.03/resources/resources.jsb (+0/-481)
static/scripts/ext-3.03/src/adapter/core/ext-base-ajax.js (+0/-371)
static/scripts/ext-3.03/src/adapter/core/ext-base-anim-extra.js (+0/-301)
static/scripts/ext-3.03/src/adapter/core/ext-base-anim.js (+0/-477)
static/scripts/ext-3.03/src/adapter/core/ext-base-begin.js (+0/-18)
static/scripts/ext-3.03/src/adapter/core/ext-base-dom.js (+0/-158)
static/scripts/ext-3.03/src/adapter/core/ext-base-end.js (+0/-21)
static/scripts/ext-3.03/src/adapter/core/ext-base-event.js (+0/-439)
static/scripts/ext-3.03/src/adapter/core/ext-base-point.js (+0/-17)
static/scripts/ext-3.03/src/adapter/core/ext-base-region.js (+0/-81)
static/scripts/ext-3.03/src/adapter/ext-base-dom-more.js (+0/-9)
static/scripts/ext-3.03/src/adapter/jquery-bridge.js (+0/-574)
static/scripts/ext-3.03/src/adapter/prototype-bridge.js (+0/-604)
static/scripts/ext-3.03/src/adapter/yui-bridge.js (+0/-374)
static/scripts/ext-3.03/src/core/CompositeElement.js (+0/-151)
static/scripts/ext-3.03/src/core/CompositeElementLite-more.js (+0/-75)
static/scripts/ext-3.03/src/core/DomHelper-more.js (+0/-152)
static/scripts/ext-3.03/src/core/Element-more.js (+0/-192)
static/scripts/ext-3.03/src/core/Element.alignment.js (+0/-370)
static/scripts/ext-3.03/src/core/Element.dd.js (+0/-46)
static/scripts/ext-3.03/src/core/Element.fx-more.js (+0/-150)
static/scripts/ext-3.03/src/core/Element.insertion-more.js (+0/-52)
static/scripts/ext-3.03/src/core/Element.keys.js (+0/-48)
static/scripts/ext-3.03/src/core/Element.legacy.js (+0/-42)
static/scripts/ext-3.03/src/core/Element.position-more.js (+0/-165)
static/scripts/ext-3.03/src/core/Element.scroll-more.js (+0/-110)
static/scripts/ext-3.03/src/core/Element.style-more.js (+0/-318)
static/scripts/ext-3.03/src/core/Error.js (+0/-81)
static/scripts/ext-3.03/src/core/EventManager-more.js (+0/-334)
static/scripts/ext-3.03/src/core/Ext-more.js (+0/-688)
static/scripts/ext-3.03/src/core/Template-more.js (+0/-133)
static/scripts/ext-3.03/src/core/core/CompositeElementLite.js (+0/-270)
static/scripts/ext-3.03/src/core/core/DomHelper.js (+0/-416)
static/scripts/ext-3.03/src/core/core/DomQuery.js (+0/-847)
static/scripts/ext-3.03/src/core/core/Element.fx.js (+0/-324)
static/scripts/ext-3.03/src/core/core/Element.insertion.js (+0/-144)
static/scripts/ext-3.03/src/core/core/Element.js (+0/-957)
static/scripts/ext-3.03/src/core/core/Element.position.js (+0/-301)
static/scripts/ext-3.03/src/core/core/Element.scroll.js (+0/-58)
static/scripts/ext-3.03/src/core/core/Element.style.js (+0/-447)
static/scripts/ext-3.03/src/core/core/Element.traversal.js (+0/-176)
static/scripts/ext-3.03/src/core/core/EventManager.js (+0/-627)
static/scripts/ext-3.03/src/core/core/Ext.js (+0/-972)
static/scripts/ext-3.03/src/core/core/Fx.js (+0/-1112)
static/scripts/ext-3.03/src/core/core/Template.js (+0/-244)
static/scripts/ext-3.03/src/data/Api.js (+0/-289)
static/scripts/ext-3.03/src/data/ArrayReader.js (+0/-102)
static/scripts/ext-3.03/src/data/ArrayStore.js (+0/-70)
static/scripts/ext-3.03/src/data/DataField.js (+0/-249)
static/scripts/ext-3.03/src/data/DataProxy.js (+0/-469)
static/scripts/ext-3.03/src/data/DataReader.js (+0/-227)
static/scripts/ext-3.03/src/data/DataWriter.js (+0/-148)
static/scripts/ext-3.03/src/data/DirectProxy.js (+0/-146)
static/scripts/ext-3.03/src/data/DirectStore.js (+0/-52)
static/scripts/ext-3.03/src/data/GroupingStore.js (+0/-139)
static/scripts/ext-3.03/src/data/HttpProxy.js (+0/-265)
static/scripts/ext-3.03/src/data/JsonReader.js (+0/-383)
static/scripts/ext-3.03/src/data/JsonStore.js (+0/-49)
static/scripts/ext-3.03/src/data/JsonWriter.js (+0/-81)
static/scripts/ext-3.03/src/data/MemoryProxy.js (+0/-69)
static/scripts/ext-3.03/src/data/Record.js (+0/-401)
static/scripts/ext-3.03/src/data/ScriptTagProxy.js (+0/-279)
static/scripts/ext-3.03/src/data/SortTypes.js (+0/-91)
static/scripts/ext-3.03/src/data/Store.js (+0/-1534)
static/scripts/ext-3.03/src/data/StoreMgr.js (+0/-72)
static/scripts/ext-3.03/src/data/Tree.js (+0/-785)
static/scripts/ext-3.03/src/data/XmlReader.js (+0/-279)
static/scripts/ext-3.03/src/data/XmlStore.js (+0/-75)
static/scripts/ext-3.03/src/data/XmlWriter.js (+0/-133)
static/scripts/ext-3.03/src/data/core/Connection.js (+0/-575)
static/scripts/ext-3.03/src/dd/DDCore.js (+0/-2992)
static/scripts/ext-3.03/src/dd/DragSource.js (+0/-365)
static/scripts/ext-3.03/src/dd/DragTracker.js (+0/-217)
static/scripts/ext-3.03/src/dd/DragZone.js (+0/-133)
static/scripts/ext-3.03/src/dd/DropTarget.js (+0/-115)
static/scripts/ext-3.03/src/dd/DropZone.js (+0/-262)
static/scripts/ext-3.03/src/dd/Registry.js (+0/-127)
static/scripts/ext-3.03/src/dd/ScrollManager.js (+0/-201)
static/scripts/ext-3.03/src/dd/StatusProxy.js (+0/-171)
static/scripts/ext-3.03/src/debug.js (+0/-906)
static/scripts/ext-3.03/src/direct/Direct.js (+0/-235)
static/scripts/ext-3.03/src/direct/Event.js (+0/-34)
static/scripts/ext-3.03/src/direct/JsonProvider.js (+0/-45)
static/scripts/ext-3.03/src/direct/PollingProvider.js (+0/-151)
static/scripts/ext-3.03/src/direct/Provider.js (+0/-110)
static/scripts/ext-3.03/src/direct/RemotingProvider.js (+0/-378)
static/scripts/ext-3.03/src/direct/Transaction.js (+0/-32)
static/scripts/ext-3.03/src/locale/ext-lang-af.js (+0/-184)
static/scripts/ext-3.03/src/locale/ext-lang-bg.js (+0/-278)
static/scripts/ext-3.03/src/locale/ext-lang-ca.js (+0/-315)
static/scripts/ext-3.03/src/locale/ext-lang-cs.js (+0/-293)
static/scripts/ext-3.03/src/locale/ext-lang-da.js (+0/-296)
static/scripts/ext-3.03/src/locale/ext-lang-de.js (+0/-326)
static/scripts/ext-3.03/src/locale/ext-lang-el_GR.js (+0/-309)
static/scripts/ext-3.03/src/locale/ext-lang-en.js (+0/-339)
static/scripts/ext-3.03/src/locale/ext-lang-en_GB.js (+0/-319)
static/scripts/ext-3.03/src/locale/ext-lang-es.js (+0/-318)
static/scripts/ext-3.03/src/locale/ext-lang-fa.js (+0/-272)
static/scripts/ext-3.03/src/locale/ext-lang-fi.js (+0/-302)
static/scripts/ext-3.03/src/locale/ext-lang-fr.js (+0/-335)
static/scripts/ext-3.03/src/locale/ext-lang-fr_CA.js (+0/-218)
static/scripts/ext-3.03/src/locale/ext-lang-gr.js (+0/-175)
static/scripts/ext-3.03/src/locale/ext-lang-he.js (+0/-292)
static/scripts/ext-3.03/src/locale/ext-lang-hr.js (+0/-295)
static/scripts/ext-3.03/src/locale/ext-lang-hu.js (+0/-296)
static/scripts/ext-3.03/src/locale/ext-lang-id.js (+0/-302)
static/scripts/ext-3.03/src/locale/ext-lang-it.js (+0/-295)
static/scripts/ext-3.03/src/locale/ext-lang-ja.js (+0/-318)
static/scripts/ext-3.03/src/locale/ext-lang-ko.js (+0/-267)
static/scripts/ext-3.03/src/locale/ext-lang-lt.js (+0/-333)
static/scripts/ext-3.03/src/locale/ext-lang-lv.js (+0/-176)
static/scripts/ext-3.03/src/locale/ext-lang-mk.js (+0/-176)
static/scripts/ext-3.03/src/locale/ext-lang-nl.js (+0/-323)
static/scripts/ext-3.03/src/locale/ext-lang-no_NB.js (+0/-294)
static/scripts/ext-3.03/src/locale/ext-lang-no_NN.js (+0/-294)
static/scripts/ext-3.03/src/locale/ext-lang-pl.js (+0/-304)
static/scripts/ext-3.03/src/locale/ext-lang-pt.js (+0/-260)
static/scripts/ext-3.03/src/locale/ext-lang-pt_BR.js (+0/-302)
static/scripts/ext-3.03/src/locale/ext-lang-pt_PT.js (+0/-298)
static/scripts/ext-3.03/src/locale/ext-lang-ro.js (+0/-295)
static/scripts/ext-3.03/src/locale/ext-lang-ru.js (+0/-319)
static/scripts/ext-3.03/src/locale/ext-lang-sk.js (+0/-182)
static/scripts/ext-3.03/src/locale/ext-lang-sl.js (+0/-176)
static/scripts/ext-3.03/src/locale/ext-lang-sr.js (+0/-179)
static/scripts/ext-3.03/src/locale/ext-lang-sr_RS.js (+0/-178)
static/scripts/ext-3.03/src/locale/ext-lang-sv_SE.js (+0/-178)
static/scripts/ext-3.03/src/locale/ext-lang-th.js (+0/-294)
static/scripts/ext-3.03/src/locale/ext-lang-tr.js (+0/-306)
static/scripts/ext-3.03/src/locale/ext-lang-ukr.js (+0/-262)
static/scripts/ext-3.03/src/locale/ext-lang-vn.js (+0/-181)
static/scripts/ext-3.03/src/locale/ext-lang-zh_CN.js (+0/-174)
static/scripts/ext-3.03/src/locale/ext-lang-zh_TW.js (+0/-178)
static/scripts/ext-3.03/src/state/CookieProvider.js (+0/-91)
static/scripts/ext-3.03/src/state/Provider.js (+0/-129)
static/scripts/ext-3.03/src/state/StateManager.js (+0/-69)
static/scripts/ext-3.03/src/util/CSS.js (+0/-161)
static/scripts/ext-3.03/src/util/ClickRepeater.js (+0/-200)
static/scripts/ext-3.03/src/util/Cookies.js (+0/-96)
static/scripts/ext-3.03/src/util/Date.js (+0/-1317)
static/scripts/ext-3.03/src/util/Format.js (+0/-356)
static/scripts/ext-3.03/src/util/History.js (+0/-203)
static/scripts/ext-3.03/src/util/KeyMap.js (+0/-242)
static/scripts/ext-3.03/src/util/KeyNav.js (+0/-160)
static/scripts/ext-3.03/src/util/MixedCollection.js (+0/-595)
static/scripts/ext-3.03/src/util/Observable-more.js (+0/-213)
static/scripts/ext-3.03/src/util/TextMetrics.js (+0/-131)
static/scripts/ext-3.03/src/util/UpdateManager.js (+0/-536)
static/scripts/ext-3.03/src/util/XTemplate.js (+0/-478)
static/scripts/ext-3.03/src/util/core/DelayedTask.js (+0/-70)
static/scripts/ext-3.03/src/util/core/JSON.js (+0/-178)
static/scripts/ext-3.03/src/util/core/Observable.js (+0/-488)
static/scripts/ext-3.03/src/util/core/TaskMgr.js (+0/-174)
static/scripts/ext-3.03/src/widgets/Action.js (+0/-252)
static/scripts/ext-3.03/src/widgets/BoxComponent.js (+0/-522)
static/scripts/ext-3.03/src/widgets/Button.js (+0/-768)
static/scripts/ext-3.03/src/widgets/ButtonGroup.js (+0/-103)
static/scripts/ext-3.03/src/widgets/ColorPalette.js (+0/-162)
static/scripts/ext-3.03/src/widgets/Component.js (+0/-1551)
static/scripts/ext-3.03/src/widgets/ComponentMgr.js (+0/-170)
static/scripts/ext-3.03/src/widgets/Container.js (+0/-953)
static/scripts/ext-3.03/src/widgets/CycleButton.js (+0/-194)
static/scripts/ext-3.03/src/widgets/DataView.js (+0/-755)
static/scripts/ext-3.03/src/widgets/DatePicker.js (+0/-779)
static/scripts/ext-3.03/src/widgets/Editor.js (+0/-383)
static/scripts/ext-3.03/src/widgets/Layer.js (+0/-466)
static/scripts/ext-3.03/src/widgets/LoadMask.js (+0/-123)
static/scripts/ext-3.03/src/widgets/MessageBox.js (+0/-632)
static/scripts/ext-3.03/src/widgets/PagingToolbar.js (+0/-542)
static/scripts/ext-3.03/src/widgets/Panel.js (+0/-1813)
static/scripts/ext-3.03/src/widgets/PanelDD.js (+0/-154)
static/scripts/ext-3.03/src/widgets/ProgressBar.js (+0/-290)
static/scripts/ext-3.03/src/widgets/Resizable.js (+0/-760)
static/scripts/ext-3.03/src/widgets/Shadow.js (+0/-192)
static/scripts/ext-3.03/src/widgets/Slider.js (+0/-426)
static/scripts/ext-3.03/src/widgets/SplitBar.js (+0/-436)
static/scripts/ext-3.03/src/widgets/SplitButton.js (+0/-124)
static/scripts/ext-3.03/src/widgets/TabPanel.js (+0/-1108)
static/scripts/ext-3.03/src/widgets/Toolbar.js (+0/-809)
static/scripts/ext-3.03/src/widgets/Viewport.js (+0/-124)
static/scripts/ext-3.03/src/widgets/Window.js (+0/-961)
static/scripts/ext-3.03/src/widgets/WindowManager.js (+0/-187)
static/scripts/ext-3.03/src/widgets/chart/Chart.js (+0/-726)
static/scripts/ext-3.03/src/widgets/chart/EventProxy.js (+0/-20)
static/scripts/ext-3.03/src/widgets/chart/FlashComponent.js (+0/-130)
static/scripts/ext-3.03/src/widgets/chart/swfobject.js (+0/-783)
static/scripts/ext-3.03/src/widgets/form/Action.js (+0/-751)
static/scripts/ext-3.03/src/widgets/form/BasicForm.js (+0/-746)
static/scripts/ext-3.03/src/widgets/form/Checkbox.js (+0/-175)
static/scripts/ext-3.03/src/widgets/form/CheckboxGroup.js (+0/-438)
static/scripts/ext-3.03/src/widgets/form/Combo.js (+0/-1246)
static/scripts/ext-3.03/src/widgets/form/DateField.js (+0/-389)
static/scripts/ext-3.03/src/widgets/form/DisplayField.js (+0/-98)
static/scripts/ext-3.03/src/widgets/form/Field.js (+0/-649)
static/scripts/ext-3.03/src/widgets/form/FieldSet.js (+0/-297)
static/scripts/ext-3.03/src/widgets/form/Form.js (+0/-358)
static/scripts/ext-3.03/src/widgets/form/Hidden.js (+0/-39)
static/scripts/ext-3.03/src/widgets/form/HtmlEditor.js (+0/-1172)
static/scripts/ext-3.03/src/widgets/form/Label.js (+0/-64)
static/scripts/ext-3.03/src/widgets/form/NumberField.js (+0/-139)
static/scripts/ext-3.03/src/widgets/form/Radio.js (+0/-81)
static/scripts/ext-3.03/src/widgets/form/RadioGroup.js (+0/-118)
static/scripts/ext-3.03/src/widgets/form/TextArea.js (+0/-118)
static/scripts/ext-3.03/src/widgets/form/TextField.js (+0/-527)
static/scripts/ext-3.03/src/widgets/form/TimeField.js (+0/-146)
static/scripts/ext-3.03/src/widgets/form/TriggerField.js (+0/-348)
static/scripts/ext-3.03/src/widgets/form/VTypes.js (+0/-135)
static/scripts/ext-3.03/src/widgets/grid/AbstractSelectionModel.js (+0/-57)
static/scripts/ext-3.03/src/widgets/grid/CellSelectionModel.js (+0/-286)
static/scripts/ext-3.03/src/widgets/grid/CheckboxSelectionModel.js (+0/-103)
static/scripts/ext-3.03/src/widgets/grid/Column.js (+0/-411)
static/scripts/ext-3.03/src/widgets/grid/ColumnDD.js (+0/-198)
static/scripts/ext-3.03/src/widgets/grid/ColumnModel.js (+0/-598)
static/scripts/ext-3.03/src/widgets/grid/ColumnSplitDD.js (+0/-62)
static/scripts/ext-3.03/src/widgets/grid/EditorGrid.js (+0/-310)
static/scripts/ext-3.03/src/widgets/grid/GridDD.js (+0/-95)
static/scripts/ext-3.03/src/widgets/grid/GridEditor.js (+0/-21)
static/scripts/ext-3.03/src/widgets/grid/GridPanel.js (+0/-967)
static/scripts/ext-3.03/src/widgets/grid/GridView.js (+0/-1822)
static/scripts/ext-3.03/src/widgets/grid/GroupingView.js (+0/-527)
static/scripts/ext-3.03/src/widgets/grid/PropertyGrid.js (+0/-372)
static/scripts/ext-3.03/src/widgets/grid/RowNumberer.js (+0/-61)
static/scripts/ext-3.03/src/widgets/grid/RowSelectionModel.js (+0/-540)
static/scripts/ext-3.03/src/widgets/layout/AbsoluteLayout.js (+0/-82)
static/scripts/ext-3.03/src/widgets/layout/AccordionLayout.js (+0/-186)
static/scripts/ext-3.03/src/widgets/layout/AnchorLayout.js (+0/-200)
static/scripts/ext-3.03/src/widgets/layout/BorderLayout.js (+0/-1108)
static/scripts/ext-3.03/src/widgets/layout/BoxLayout.js (+0/-440)
static/scripts/ext-3.03/src/widgets/layout/CardLayout.js (+0/-128)
static/scripts/ext-3.03/src/widgets/layout/ColumnLayout.js (+0/-130)
static/scripts/ext-3.03/src/widgets/layout/ContainerLayout.js (+0/-228)
static/scripts/ext-3.03/src/widgets/layout/FitLayout.js (+0/-48)
static/scripts/ext-3.03/src/widgets/layout/FormLayout.js (+0/-347)
static/scripts/ext-3.03/src/widgets/layout/TableLayout.js (+0/-196)
static/scripts/ext-3.03/src/widgets/list/ColumnResizer.js (+0/-125)
static/scripts/ext-3.03/src/widgets/list/ListView.js (+0/-372)
static/scripts/ext-3.03/src/widgets/list/Sorter.js (+0/-70)
static/scripts/ext-3.03/src/widgets/menu/BaseItem.js (+0/-165)
static/scripts/ext-3.03/src/widgets/menu/CheckItem.js (+0/-114)
static/scripts/ext-3.03/src/widgets/menu/ColorMenu.js (+0/-109)
static/scripts/ext-3.03/src/widgets/menu/DateMenu.js (+0/-124)
static/scripts/ext-3.03/src/widgets/menu/Item.js (+0/-211)
static/scripts/ext-3.03/src/widgets/menu/Menu.js (+0/-773)
static/scripts/ext-3.03/src/widgets/menu/MenuMgr.js (+0/-211)
static/scripts/ext-3.03/src/widgets/menu/Separator.js (+0/-46)
static/scripts/ext-3.03/src/widgets/menu/TextItem.js (+0/-46)
static/scripts/ext-3.03/src/widgets/tips/QuickTip.js (+0/-222)
static/scripts/ext-3.03/src/widgets/tips/QuickTips.js (+0/-159)
static/scripts/ext-3.03/src/widgets/tips/Tip.js (+0/-160)
static/scripts/ext-3.03/src/widgets/tips/ToolTip.js (+0/-520)
static/scripts/ext-3.03/src/widgets/tree/AsyncTreeNode.js (+0/-114)
static/scripts/ext-3.03/src/widgets/tree/TreeDragZone.js (+0/-82)
static/scripts/ext-3.03/src/widgets/tree/TreeDropZone.js (+0/-321)
static/scripts/ext-3.03/src/widgets/tree/TreeEditor.js (+0/-160)
static/scripts/ext-3.03/src/widgets/tree/TreeEventModel.js (+0/-176)
static/scripts/ext-3.03/src/widgets/tree/TreeFilter.js (+0/-114)
static/scripts/ext-3.03/src/widgets/tree/TreeLoader.js (+0/-342)
static/scripts/ext-3.03/src/widgets/tree/TreeNode.js (+0/-553)
static/scripts/ext-3.03/src/widgets/tree/TreeNodeUI.js (+0/-632)
static/scripts/ext-3.03/src/widgets/tree/TreePanel.js (+0/-932)
static/scripts/ext-3.03/src/widgets/tree/TreeSelectionModel.js (+0/-319)
static/scripts/ext-3.03/src/widgets/tree/TreeSorter.js (+0/-106)
static/scripts/ext-community-extensions/Ext.ux.MultiSelect.css (+0/-32)
static/scripts/ext-community-extensions/Ext.ux.MultiSelect.js (+0/-604)
static/scripts/ext-community-extensions/Ext.ux.PasswordMeter.js (+0/-158)
static/scripts/ext-community-extensions/PagingStore.js (+0/-330)
static/scripts/ext-community-extensions/color-field.css (+0/-7)
static/scripts/ext-community-extensions/color-field.js (+0/-166)
static/scripts/ext-community-extensions/rowactions/Ext.ux.grid.RowActions.js (+0/-514)
static/scripts/ext-community-extensions/rowactions/css/Ext.ux.grid.RowActions.css (+0/-78)
static/scripts/ext-community-extensions/rowactions/css/icons.css (+0/-351)
static/scripts/ext-community-extensions/rowactions/css/rowactions.css (+0/-62)
static/scripts/ext-community-extensions/rowactions/css/webpage.css (+0/-154)
static/scripts/ext-community-extensions/rowactions/get-grid-data.php (+0/-54)
static/scripts/ext-community-extensions/rowactions/js/Ext.ux.HttpProvider.js (+0/-424)
static/scripts/ext-community-extensions/rowactions/js/Ext.ux.ThemeCombo.js (+0/-106)
static/scripts/ext-community-extensions/rowactions/js/Ext.ux.Toast.js (+0/-36)
static/scripts/ext-community-extensions/rowactions/js/Ext.ux.form.ThemeCombo.js (+0/-137)
static/scripts/ext-community-extensions/rowactions/js/Ext.ux.grid.RowActions.js (+0/-514)
static/scripts/ext-community-extensions/rowactions/js/Ext.ux.state.HttpProvider.js (+0/-415)
static/scripts/ext-community-extensions/rowactions/js/Ext.ux.util.js (+0/-412)
static/scripts/ext-community-extensions/rowactions/js/RowExpander.js (+0/-128)
static/scripts/ext-community-extensions/rowactions/js/WebPage.js (+0/-209)
static/scripts/ext-community-extensions/rowactions/process-request.php (+0/-116)
static/scripts/ext-community-extensions/rowactions/provider-sqlite.php (+0/-42)
static/scripts/ext-community-extensions/rowactions/rowactions.html (+0/-187)
static/scripts/ext-community-extensions/rowactions/rowactions.js (+0/-215)
static/scripts/ext-community-extensions/rowactions/state-sqlite.php (+0/-120)
static/scripts/ext/INCLUDE_ORDER.txt (+0/-35)
static/scripts/ext/adapter/ext/ext-base-debug.js (+0/-2886)
static/scripts/ext/adapter/ext/ext-base.js (+0/-7)
static/scripts/ext/adapter/jquery/ext-jquery-adapter-debug.js (+0/-1797)
static/scripts/ext/adapter/jquery/ext-jquery-adapter.js (+0/-7)
static/scripts/ext/examples/App.js (+0/-236)
static/scripts/ext/examples/CheckColumn.js (+0/-71)
static/scripts/ext/examples/FileUploadField.js (+0/-182)
static/scripts/ext/examples/RowEditor.js (+0/-531)
static/scripts/ext/examples/RowExpander.js (+0/-241)
static/scripts/ext/examples/fileuploadfield.css (+0/-33)
static/scripts/ext/ext-all-debug-w-comments.js (+0/-78773)
static/scripts/ext/ext-all-debug.js (+0/-51256)
static/scripts/ext/ext-all.js (+0/-11)
static/scripts/ext/ext.jsb2 (+0/-1640)
static/scripts/ext/gpl-3.0.txt (+0/-674)
static/scripts/ext/index.html (+0/-344)
static/scripts/ext/license.txt (+0/-41)
static/scripts/ext/release-notes.html (+0/-139)
static/scripts/ext/resources/css/README.txt (+0/-6)
static/scripts/ext/resources/css/debug.css (+0/-43)
static/scripts/ext/resources/css/ext-all-notheme.css (+0/-5302)
static/scripts/ext/resources/css/ext-all.css (+0/-6969)
static/scripts/ext/resources/css/ext-theme.min.css (+0/-1)
static/scripts/ext/resources/css/reset-min.css (+0/-7)
static/scripts/ext/resources/css/structure/borders.css (+0/-54)
static/scripts/ext/resources/css/structure/box.css (+0/-80)
static/scripts/ext/resources/css/structure/button.css (+0/-445)
static/scripts/ext/resources/css/structure/combo.css (+0/-45)
static/scripts/ext/resources/css/structure/core.css (+0/-341)
static/scripts/ext/resources/css/structure/date-picker.css (+0/-271)
static/scripts/ext/resources/css/structure/dd.css (+0/-61)
static/scripts/ext/resources/css/structure/debug.css (+0/-26)
static/scripts/ext/resources/css/structure/dialog.css (+0/-59)
static/scripts/ext/resources/css/structure/editor.css (+0/-92)
static/scripts/ext/resources/css/structure/form.css (+0/-573)
static/scripts/ext/resources/css/structure/grid.css (+0/-588)
static/scripts/ext/resources/css/structure/layout.css (+0/-296)
static/scripts/ext/resources/css/structure/list-view.css (+0/-86)
static/scripts/ext/resources/css/structure/menu.css (+0/-245)
static/scripts/ext/resources/css/structure/panel-reset.css (+0/-130)
static/scripts/ext/resources/css/structure/panel.css (+0/-493)
static/scripts/ext/resources/css/structure/pivotgrid.css (+0/-65)
static/scripts/ext/resources/css/structure/progress.css (+0/-46)
static/scripts/ext/resources/css/structure/qtips.css (+0/-153)
static/scripts/ext/resources/css/structure/reset.css (+0/-13)
static/scripts/ext/resources/css/structure/resizable.css (+0/-149)
static/scripts/ext/resources/css/structure/slider.css (+0/-103)
static/scripts/ext/resources/css/structure/tabs.css (+0/-392)
static/scripts/ext/resources/css/structure/toolbar.css (+0/-246)
static/scripts/ext/resources/css/structure/tree.css (+0/-218)
static/scripts/ext/resources/css/structure/window.css (+0/-222)
static/scripts/ext/resources/css/theme-access/borders.css (+0/-25)
static/scripts/ext/resources/css/theme-access/box.css (+0/-74)
static/scripts/ext/resources/css/theme-access/button.css (+0/-136)
static/scripts/ext/resources/css/theme-access/combo.css (+0/-43)
static/scripts/ext/resources/css/theme-access/core.css (+0/-81)
static/scripts/ext/resources/css/theme-access/date-picker.css (+0/-145)
static/scripts/ext/resources/css/theme-access/dd.css (+0/-29)
static/scripts/ext/resources/css/theme-access/debug.css (+0/-24)
static/scripts/ext/resources/css/theme-access/dialog.css (+0/-34)
static/scripts/ext/resources/css/theme-access/editor.css (+0/-16)
static/scripts/ext/resources/css/theme-access/form.css (+0/-176)
static/scripts/ext/resources/css/theme-access/grid.css (+0/-288)
static/scripts/ext/resources/css/theme-access/layout.css (+0/-56)
static/scripts/ext/resources/css/theme-access/list-view.css (+0/-43)
static/scripts/ext/resources/css/theme-access/menu.css (+0/-79)
static/scripts/ext/resources/css/theme-access/panel.css (+0/-94)
static/scripts/ext/resources/css/theme-access/progress.css (+0/-35)
static/scripts/ext/resources/css/theme-access/qtips.css (+0/-44)
static/scripts/ext/resources/css/theme-access/resizable.css (+0/-44)
static/scripts/ext/resources/css/theme-access/slider.css (+0/-21)
static/scripts/ext/resources/css/theme-access/tabs.css (+0/-119)
static/scripts/ext/resources/css/theme-access/toolbar.css (+0/-120)
static/scripts/ext/resources/css/theme-access/tree.css (+0/-165)
static/scripts/ext/resources/css/theme-access/window.css (+0/-87)
static/scripts/ext/resources/css/theme-gray/borders.css (+0/-29)
static/scripts/ext/resources/css/theme-gray/box.css (+0/-74)
static/scripts/ext/resources/css/theme-gray/button.css (+0/-94)
static/scripts/ext/resources/css/theme-gray/combo.css (+0/-43)
static/scripts/ext/resources/css/theme-gray/core.css (+0/-83)
static/scripts/ext/resources/css/theme-gray/date-picker.css (+0/-143)
static/scripts/ext/resources/css/theme-gray/dd.css (+0/-29)
static/scripts/ext/resources/css/theme-gray/debug.css (+0/-24)
static/scripts/ext/resources/css/theme-gray/dialog.css (+0/-34)
static/scripts/ext/resources/css/theme-gray/editor.css (+0/-13)
static/scripts/ext/resources/css/theme-gray/form.css (+0/-117)
static/scripts/ext/resources/css/theme-gray/grid.css (+0/-276)
static/scripts/ext/resources/css/theme-gray/layout.css (+0/-53)
static/scripts/ext/resources/css/theme-gray/list-view.css (+0/-37)
static/scripts/ext/resources/css/theme-gray/menu.css (+0/-82)
static/scripts/ext/resources/css/theme-gray/panel.css (+0/-87)
static/scripts/ext/resources/css/theme-gray/pivotgrid.css (+0/-28)
static/scripts/ext/resources/css/theme-gray/progress.css (+0/-32)
static/scripts/ext/resources/css/theme-gray/qtips.css (+0/-44)
static/scripts/ext/resources/css/theme-gray/resizable.css (+0/-43)
static/scripts/ext/resources/css/theme-gray/slider.css (+0/-21)
static/scripts/ext/resources/css/theme-gray/tabs.css (+0/-127)
static/scripts/ext/resources/css/theme-gray/toolbar.css (+0/-95)
static/scripts/ext/resources/css/theme-gray/tree.css (+0/-157)
static/scripts/ext/resources/css/theme-gray/window.css (+0/-86)
static/scripts/ext/resources/css/visual/borders.css (+0/-25)
static/scripts/ext/resources/css/visual/box.css (+0/-74)
static/scripts/ext/resources/css/visual/button.css (+0/-94)
static/scripts/ext/resources/css/visual/combo.css (+0/-43)
static/scripts/ext/resources/css/visual/core.css (+0/-82)
static/scripts/ext/resources/css/visual/date-picker.css (+0/-143)
static/scripts/ext/resources/css/visual/dd.css (+0/-29)
static/scripts/ext/resources/css/visual/debug.css (+0/-24)
static/scripts/ext/resources/css/visual/dialog.css (+0/-34)
static/scripts/ext/resources/css/visual/editor.css (+0/-13)
static/scripts/ext/resources/css/visual/form.css (+0/-123)
static/scripts/ext/resources/css/visual/grid.css (+0/-277)
static/scripts/ext/resources/css/visual/layout.css (+0/-53)
static/scripts/ext/resources/css/visual/list-view.css (+0/-37)
static/scripts/ext/resources/css/visual/menu.css (+0/-87)
static/scripts/ext/resources/css/visual/panel.css (+0/-87)
static/scripts/ext/resources/css/visual/pivotgrid.css (+0/-28)
static/scripts/ext/resources/css/visual/progress.css (+0/-32)
static/scripts/ext/resources/css/visual/qtips.css (+0/-44)
static/scripts/ext/resources/css/visual/resizable.css (+0/-43)
static/scripts/ext/resources/css/visual/slider.css (+0/-21)
static/scripts/ext/resources/css/visual/tabs.css (+0/-127)
static/scripts/ext/resources/css/visual/toolbar.css (+0/-95)
static/scripts/ext/resources/css/visual/tree.css (+0/-152)
static/scripts/ext/resources/css/visual/window.css (+0/-86)
static/scripts/ext/resources/css/xtheme-access.css (+0/-1820)
static/scripts/ext/resources/css/xtheme-blue.css (+0/-1674)
static/scripts/ext/resources/css/xtheme-gray.css (+0/-1682)
static/scripts/ext/resources/css/yourtheme.css (+0/-1652)
static/scripts/ext/resources/images/yourtheme/README.txt (+0/-2)
static/scripts/ext/src/locale/ext-lang-af.js (+0/-185)
static/scripts/ext/src/locale/ext-lang-am.js (+0/-359)
static/scripts/ext/src/locale/ext-lang-bg.js (+0/-279)
static/scripts/ext/src/locale/ext-lang-ca.js (+0/-316)
static/scripts/ext/src/locale/ext-lang-cs.js (+0/-311)
static/scripts/ext/src/locale/ext-lang-da.js (+0/-297)
static/scripts/ext/src/locale/ext-lang-de.js (+0/-346)
static/scripts/ext/src/locale/ext-lang-el_GR.js (+0/-309)
static/scripts/ext/src/locale/ext-lang-en.js (+0/-346)
static/scripts/ext/src/locale/ext-lang-en_GB.js (+0/-322)
static/scripts/ext/src/locale/ext-lang-es.js (+0/-319)
static/scripts/ext/src/locale/ext-lang-fa.js (+0/-273)
static/scripts/ext/src/locale/ext-lang-fi.js (+0/-303)
static/scripts/ext/src/locale/ext-lang-fr.js (+0/-346)
static/scripts/ext/src/locale/ext-lang-fr_CA.js (+0/-218)
static/scripts/ext/src/locale/ext-lang-gr.js (+0/-175)
static/scripts/ext/src/locale/ext-lang-he.js (+0/-293)
static/scripts/ext/src/locale/ext-lang-hr.js (+0/-296)
static/scripts/ext/src/locale/ext-lang-hu.js (+0/-297)
static/scripts/ext/src/locale/ext-lang-id.js (+0/-303)
static/scripts/ext/src/locale/ext-lang-it.js (+0/-296)
static/scripts/ext/src/locale/ext-lang-ja.js (+0/-319)
static/scripts/ext/src/locale/ext-lang-ko.js (+0/-268)
static/scripts/ext/src/locale/ext-lang-lt.js (+0/-334)
static/scripts/ext/src/locale/ext-lang-lv.js (+0/-177)
static/scripts/ext/src/locale/ext-lang-mk.js (+0/-176)
static/scripts/ext/src/locale/ext-lang-nl.js (+0/-324)
static/scripts/ext/src/locale/ext-lang-no_NB.js (+0/-295)
static/scripts/ext/src/locale/ext-lang-no_NN.js (+0/-295)
static/scripts/ext/src/locale/ext-lang-pl.js (+0/-304)
static/scripts/ext/src/locale/ext-lang-pt.js (+0/-261)
static/scripts/ext/src/locale/ext-lang-pt_BR.js (+0/-303)
static/scripts/ext/src/locale/ext-lang-pt_PT.js (+0/-298)
static/scripts/ext/src/locale/ext-lang-ro.js (+0/-296)
static/scripts/ext/src/locale/ext-lang-ru.js (+0/-320)
static/scripts/ext/src/locale/ext-lang-sk.js (+0/-182)
static/scripts/ext/src/locale/ext-lang-sl.js (+0/-177)
static/scripts/ext/src/locale/ext-lang-sr.js (+0/-180)
static/scripts/ext/src/locale/ext-lang-sr_RS.js (+0/-179)
static/scripts/ext/src/locale/ext-lang-sv_SE.js (+0/-179)
static/scripts/ext/src/locale/ext-lang-th.js (+0/-295)
static/scripts/ext/src/locale/ext-lang-tr.js (+0/-307)
static/scripts/ext/src/locale/ext-lang-ukr.js (+0/-263)
static/scripts/ext/src/locale/ext-lang-vn.js (+0/-181)
static/scripts/ext/src/locale/ext-lang-zh_CN.js (+0/-263)
static/scripts/ext/src/locale/ext-lang-zh_TW.js (+0/-178)
static/scripts/gis/Gazetteer.js (+0/-60)
static/scripts/gis/GeoExplorer.js (+0/-29)
static/scripts/gis/GeoExplorer/GeoExplorer.js (+0/-1513)
static/scripts/gis/GeoExplorer/GeoExplorer/Composer.js (+0/-160)
static/scripts/gis/GeoExplorer/GeoExplorer/NewSourceWindow.js (+0/-90)
static/scripts/gis/GeoExplorer/GeoExplorer/Sahana.js (+0/-88)
static/scripts/gis/GeoExplorer/GeoExplorer/Viewer.js (+0/-99)
static/scripts/gis/GeoExt.js (+0/-299)
static/scripts/gis/GeoExt/lib/GeoExt.js (+0/-149)
static/scripts/gis/GeoExt/lib/GeoExt/Lang.js (+0/-134)
static/scripts/gis/GeoExt/lib/GeoExt/SingleFile.js (+0/-11)
static/scripts/gis/GeoExt/lib/GeoExt/data/AttributeReader.js (+0/-146)
static/scripts/gis/GeoExt/lib/GeoExt/data/AttributeStore.js (+0/-187)
static/scripts/gis/GeoExt/lib/GeoExt/data/FeatureReader.js (+0/-125)
static/scripts/gis/GeoExt/lib/GeoExt/data/FeatureRecord.js (+0/-92)
static/scripts/gis/GeoExt/lib/GeoExt/data/FeatureStore.js (+0/-428)
static/scripts/gis/GeoExt/lib/GeoExt/data/LayerReader.js (+0/-89)
static/scripts/gis/GeoExt/lib/GeoExt/data/LayerRecord.js (+0/-105)
static/scripts/gis/GeoExt/lib/GeoExt/data/LayerStore.js (+0/-455)
static/scripts/gis/GeoExt/lib/GeoExt/data/PrintPage.js (+0/-328)
static/scripts/gis/GeoExt/lib/GeoExt/data/PrintProvider.js (+0/-759)
static/scripts/gis/GeoExt/lib/GeoExt/data/ProtocolProxy.js (+0/-127)
static/scripts/gis/GeoExt/lib/GeoExt/data/ScaleStore.js (+0/-130)
static/scripts/gis/GeoExt/lib/GeoExt/data/WFSCapabilitiesReader.js (+0/-142)
static/scripts/gis/GeoExt/lib/GeoExt/data/WFSCapabilitiesStore.js (+0/-61)
static/scripts/gis/GeoExt/lib/GeoExt/data/WMCReader.js (+0/-116)
static/scripts/gis/GeoExt/lib/GeoExt/data/WMSCapabilitiesReader.js (+0/-265)
static/scripts/gis/GeoExt/lib/GeoExt/data/WMSCapabilitiesStore.js (+0/-61)
static/scripts/gis/GeoExt/lib/GeoExt/data/WMSDescribeLayerReader.js (+0/-94)
static/scripts/gis/GeoExt/lib/GeoExt/data/WMSDescribeLayerStore.js (+0/-61)
static/scripts/gis/GeoExt/lib/GeoExt/locale/GeoExt-fr.js (+0/-23)
static/scripts/gis/GeoExt/lib/GeoExt/plugins/AttributeForm.js (+0/-154)
static/scripts/gis/GeoExt/lib/GeoExt/plugins/PrintExtent.js (+0/-400)
static/scripts/gis/GeoExt/lib/GeoExt/plugins/PrintPageField.js (+0/-199)
static/scripts/gis/GeoExt/lib/GeoExt/plugins/PrintProviderField.js (+0/-187)
static/scripts/gis/GeoExt/lib/GeoExt/plugins/TreeNodeComponent.js (+0/-130)
static/scripts/gis/GeoExt/lib/GeoExt/plugins/TreeNodeRadioButton.js (+0/-135)
static/scripts/gis/GeoExt/lib/GeoExt/state/PermalinkProvider.js (+0/-138)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/Action.js (+0/-268)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/FeatureRenderer.js (+0/-377)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/LayerLegend.js (+0/-196)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/LayerOpacitySlider.js (+0/-384)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/LegendImage.js (+0/-103)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/LegendPanel.js (+0/-244)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/MapPanel.js (+0/-415)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/Popup.js (+0/-361)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/PrintMapPanel.js (+0/-381)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/UrlLegend.js (+0/-64)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/VectorLegend.js (+0/-671)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/WMSLegend.js (+0/-237)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/ZoomSlider.js (+0/-268)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/form.js (+0/-186)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/form/BasicForm.js (+0/-85)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/form/FormPanel.js (+0/-102)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/form/SearchAction.js (+0/-156)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/grid/FeatureSelectionModel.js (+0/-317)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/tips/LayerOpacitySliderTip.js (+0/-78)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/tips/SliderTip.js (+0/-109)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/tips/ZoomSliderTip.js (+0/-84)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/tree/BaseLayerContainer.js (+0/-73)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/tree/LayerContainer.js (+0/-105)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/tree/LayerLoader.js (+0/-326)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/tree/LayerNode.js (+0/-396)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/tree/LayerParamLoader.js (+0/-152)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/tree/LayerParamNode.js (+0/-250)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/tree/OverlayLayerContainer.js (+0/-64)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/tree/TreeNodeUIEventMixin.js (+0/-91)
static/scripts/gis/GeoExt/lib/GeoExt/widgets/tree/WMSCapabilitiesLoader.js (+0/-132)
static/scripts/gis/GeoExt/lib/overrides/override-ext-ajax.js (+0/-83)
static/scripts/gis/GeoExt/lib/overrides/override-ext-ajax.jst (+0/-64)
static/scripts/gis/GeoExt/license.txt (+0/-44)
static/scripts/gis/GeoExt/ux/FeatureBrowser.js (+0/-206)
static/scripts/gis/GeoExt/ux/FeatureEditorGrid.js.txt (+0/-469)
static/scripts/gis/GeoExt/ux/GeoNamesSearchCombo.js (+0/-315)
static/scripts/gis/GeoExt/ux/Measure.js (+0/-203)
static/scripts/gis/GeoExt/ux/MeasureArea.js (+0/-57)
static/scripts/gis/GeoExt/ux/MeasureLength.js (+0/-57)
static/scripts/gis/GeoExt/ux/PrintPreview.js (+0/-420)
static/scripts/gis/GeoExt/ux/SimplePrint.js (+0/-268)
static/scripts/gis/GeoExt/ux/WMSBrowser.js (+0/-574)
static/scripts/gis/MP.js (+0/-181)
static/scripts/gis/OpenLayers.js (+0/-1831)
static/scripts/gis/OpenStreetMap.js (+0/-83)
static/scripts/gis/RemoveFeature.js (+0/-185)
static/scripts/gis/SessionProvider.js (+0/-20)
static/scripts/gis/cdauth.js (+0/-199)
static/scripts/gis/examples.js (+0/-109)
static/scripts/gis/gis_layers.js (+0/-71)
static/scripts/gis/gxp.js (+0/-51)
static/scripts/gis/gxp/data/WFSFeatureStore.js (+0/-104)
static/scripts/gis/gxp/data/WFSProtocolProxy.js (+0/-218)
static/scripts/gis/gxp/loader.js (+0/-86)
static/scripts/gis/gxp/locale/en.js (+0/-155)
static/scripts/gis/gxp/menu/LayerMenu.js (+0/-99)
static/scripts/gis/gxp/plugins/AddLayers.js (+0/-241)
static/scripts/gis/gxp/plugins/BingSource.js (+0/-183)
static/scripts/gis/gxp/plugins/FeatureEditor.js (+0/-520)
static/scripts/gis/gxp/plugins/FeatureGrid.js (+0/-193)
static/scripts/gis/gxp/plugins/FeatureManager.js (+0/-912)
static/scripts/gis/gxp/plugins/FeatureToField.js (+0/-86)
static/scripts/gis/gxp/plugins/GeoServerStyleWriter.js (+0/-182)
static/scripts/gis/gxp/plugins/GoogleGeocoder.js (+0/-98)
static/scripts/gis/gxp/plugins/GoogleSource.js (+0/-345)
static/scripts/gis/gxp/plugins/KMLSource.js (+0/-298)
static/scripts/gis/gxp/plugins/LayerSource.js (+0/-143)
static/scripts/gis/gxp/plugins/LayerTree.js (+0/-220)
static/scripts/gis/gxp/plugins/OLSource.js (+0/-145)
static/scripts/gis/gxp/plugins/OSMSource.js (+0/-188)
static/scripts/gis/gxp/plugins/QueryForm.js (+0/-216)
static/scripts/gis/gxp/plugins/RemoveLayer.js (+0/-86)
static/scripts/gis/gxp/plugins/SnappingAgent.js (+0/-124)
static/scripts/gis/gxp/plugins/StyleWriter.js (+0/-88)
static/scripts/gis/gxp/plugins/TMSSource.js (+0/-288)
static/scripts/gis/gxp/plugins/Tool.js (+0/-292)
static/scripts/gis/gxp/plugins/WMSGetFeatureInfo.js (+0/-176)
static/scripts/gis/gxp/plugins/WMSRasterStylesDialog.js (+0/-359)
static/scripts/gis/gxp/plugins/WMSSource.js (+0/-422)
static/scripts/gis/gxp/plugins/YahooSource.js (+0/-307)
static/scripts/gis/gxp/plugins/ZoomToExtent.js (+0/-107)
static/scripts/gis/gxp/util.js (+0/-102)
static/scripts/gis/gxp/util.jst (+0/-22)
static/scripts/gis/gxp/widgets/EmbedMapDialog.js (+0/-202)
static/scripts/gis/gxp/widgets/FeatureEditPopup.js (+0/-505)
static/scripts/gis/gxp/widgets/FillSymbolizer.js (+0/-159)
static/scripts/gis/gxp/widgets/FilterBuilder.js (+0/-576)
static/scripts/gis/gxp/widgets/GoogleEarthPanel.js (+0/-346)
static/scripts/gis/gxp/widgets/GoogleStreetViewPanel.js (+0/-150)
static/scripts/gis/gxp/widgets/LineSymbolizer.js (+0/-68)
static/scripts/gis/gxp/widgets/NewSourceWindow.js (+0/-163)
static/scripts/gis/gxp/widgets/PointSymbolizer.js (+0/-295)
static/scripts/gis/gxp/widgets/PolygonSymbolizer.js (+0/-78)
static/scripts/gis/gxp/widgets/QueryPanel.js (+0/-422)
static/scripts/gis/gxp/widgets/RulePanel.js (+0/-513)
static/scripts/gis/gxp/widgets/ScaleLimitPanel.js (+0/-395)
static/scripts/gis/gxp/widgets/StrokeSymbolizer.js (+0/-218)
static/scripts/gis/gxp/widgets/StylePropertiesDialog.js (+0/-94)
static/scripts/gis/gxp/widgets/TextSymbolizer.js (+0/-281)
static/scripts/gis/gxp/widgets/Viewer.js (+0/-581)
static/scripts/gis/gxp/widgets/WMSLayerPanel.js (+0/-209)
static/scripts/gis/gxp/widgets/WMSStylesDialog.js (+0/-930)
static/scripts/gis/gxp/widgets/form/ColorField.js (+0/-188)
static/scripts/gis/gxp/widgets/form/ComparisonComboBox.js (+0/-76)
static/scripts/gis/gxp/widgets/form/FilterField.js (+0/-176)
static/scripts/gis/gxp/widgets/form/FontComboBox.js (+0/-77)
static/scripts/gis/gxp/widgets/form/GoogleGeocoderComboBox.js (+0/-190)
static/scripts/gis/gxp/widgets/form/ViewerField.js (+0/-116)
static/scripts/gis/gxp/widgets/grid/CapabilitiesGrid.js (+0/-327)
static/scripts/gis/gxp/widgets/grid/FeatureGrid.js (+0/-137)
static/scripts/gis/gxp/widgets/tips/SliderTip.js (+0/-79)
static/scripts/gis/mapfish/MapFish.js (+0/-162)
static/scripts/gis/mapfish/SingleFile.js (+0/-52)
static/scripts/gis/mapfish/core/Color.js (+0/-198)
static/scripts/gis/mapfish/core/GeoStat.js (+0/-524)
static/scripts/gis/mapfish/core/GeoStat/Choropleth.js (+0/-207)
static/scripts/gis/mapfish/core/GeoStat/ProportionalSymbol.js (+0/-150)
static/scripts/gis/mapfish/core/Offline.js (+0/-235)
static/scripts/gis/mapfish/core/PrintProtocol.js (+0/-786)
static/scripts/gis/mapfish/core/Protocol.js (+0/-70)
static/scripts/gis/mapfish/core/Protocol/MapFish.js (+0/-485)
static/scripts/gis/mapfish/core/Protocol/MergeFilterDecorator.js (+0/-311)
static/scripts/gis/mapfish/core/Protocol/TriggerEventDecorator.js (+0/-278)
static/scripts/gis/mapfish/core/Routing.js (+0/-159)
static/scripts/gis/mapfish/core/Searcher.js (+0/-82)
static/scripts/gis/mapfish/core/Searcher/Form.js (+0/-182)
static/scripts/gis/mapfish/core/Searcher/Map.js (+0/-567)
static/scripts/gis/mapfish/core/Strategy.js (+0/-29)
static/scripts/gis/mapfish/core/Strategy/ProtocolListener.js (+0/-164)
static/scripts/gis/mapfish/core/Util.js (+0/-225)
static/scripts/gis/mapfish/lang/de.js (+0/-54)
static/scripts/gis/mapfish/lang/en.js (+0/-77)
static/scripts/gis/mapfish/lang/fr.js (+0/-77)
static/scripts/gis/mapfish/lang/it.js (+0/-54)
static/scripts/gis/mapfish/widgets/ComboBoxFactory.js (+0/-74)
static/scripts/gis/mapfish/widgets/MapComponent.js (+0/-72)
static/scripts/gis/mapfish/widgets/Shortcuts.js (+0/-138)
static/scripts/gis/mapfish/widgets/data/FeatureReader.js (+0/-126)
static/scripts/gis/mapfish/widgets/data/FeatureStore.js (+0/-75)
static/scripts/gis/mapfish/widgets/data/FeatureStoreMediator.js (+0/-162)
static/scripts/gis/mapfish/widgets/data/GridRowFeatureMediator.js (+0/-261)
static/scripts/gis/mapfish/widgets/data/LayerStoreMediator.js (+0/-181)
static/scripts/gis/mapfish/widgets/data/SearchStoreMediator.js (+0/-206)
static/scripts/gis/mapfish/widgets/editing/FeatureEditingPanel.js (+0/-1183)
static/scripts/gis/mapfish/widgets/editing/FeatureList.js (+0/-631)
static/scripts/gis/mapfish/widgets/editing/FeatureProperties.js (+0/-317)
static/scripts/gis/mapfish/widgets/geostat/Choropleth.js (+0/-338)
static/scripts/gis/mapfish/widgets/geostat/ProportionalSymbol.js (+0/-250)
static/scripts/gis/mapfish/widgets/print/Base.js (+0/-327)
static/scripts/gis/mapfish/widgets/print/BaseWidget.js (+0/-674)
static/scripts/gis/mapfish/widgets/print/MultiPage.js (+0/-574)
static/scripts/gis/mapfish/widgets/print/PrintAction.js (+0/-118)
static/scripts/gis/mapfish/widgets/print/SimpleForm.js (+0/-284)
static/scripts/gis/mapfish/widgets/recenter/Base.js (+0/-342)
static/scripts/gis/mapfish/widgets/recenter/Coords.js (+0/-163)
static/scripts/gis/mapfish/widgets/recenter/DataField.js (+0/-190)
static/scripts/gis/mapfish/widgets/search/Form.js (+0/-109)
static/scripts/gis/mapfish/widgets/toolbar/CheckItem.js (+0/-145)
static/scripts/gis/mapfish/widgets/toolbar/MenuItem.js (+0/-74)
static/scripts/gis/mapfish/widgets/toolbar/Toolbar.js (+0/-389)
static/scripts/gis/mapfish/widgets/tree/LayerTree.js (+0/-1231)
static/scripts/gis/mapfish/widgets/tree/LayerTreeExtra.js (+0/-317)
static/scripts/gis/openlayers/OpenLayers.js (+0/-2553)
static/scripts/gis/openlayers/art/arrows.svg (+0/-127)
static/scripts/gis/openlayers/art/layer-switcher-maximize.svg (+0/-128)
static/scripts/gis/openlayers/art/layer-switcher-minimize.svg (+0/-142)
static/scripts/gis/openlayers/art/marker.svg (+0/-25)
static/scripts/gis/openlayers/art/measuring-stick-off.svg (+0/-36)
static/scripts/gis/openlayers/art/measuring-stick-on.svg (+0/-36)
static/scripts/gis/openlayers/art/panning-hand-off.svg (+0/-44)
static/scripts/gis/openlayers/art/panning-hand-on.svg (+0/-44)
static/scripts/gis/openlayers/art/slider.svg (+0/-71)
static/scripts/gis/openlayers/art/zoom-world.svg (+0/-193)
static/scripts/gis/openlayers/art/zoombar.svg (+0/-73)
static/scripts/gis/openlayers/lib/Firebug/firebug.css (+0/-209)
static/scripts/gis/openlayers/lib/Firebug/firebug.html (+0/-23)
static/scripts/gis/openlayers/lib/Firebug/firebug.js (+0/-674)
static/scripts/gis/openlayers/lib/Firebug/firebugx.js (+0/-9)
static/scripts/gis/openlayers/lib/Firebug/license.txt (+0/-30)
static/scripts/gis/openlayers/lib/Firebug/readme.txt (+0/-13)
static/scripts/gis/openlayers/lib/Gears/gears_init.js (+0/-88)
static/scripts/gis/openlayers/lib/OpenLayers.js (+0/-349)
static/scripts/gis/openlayers/lib/OpenLayers/Ajax.js (+0/-678)
static/scripts/gis/openlayers/lib/OpenLayers/BaseTypes.js (+0/-682)
static/scripts/gis/openlayers/lib/OpenLayers/BaseTypes/Bounds.js (+0/-681)
static/scripts/gis/openlayers/lib/OpenLayers/BaseTypes/Class.js (+0/-116)
static/scripts/gis/openlayers/lib/OpenLayers/BaseTypes/Element.js (+0/-251)
static/scripts/gis/openlayers/lib/OpenLayers/BaseTypes/LonLat.js (+0/-190)
static/scripts/gis/openlayers/lib/OpenLayers/BaseTypes/Pixel.js (+0/-125)
static/scripts/gis/openlayers/lib/OpenLayers/BaseTypes/Size.js (+0/-85)
static/scripts/gis/openlayers/lib/OpenLayers/Console.js (+0/-246)
static/scripts/gis/openlayers/lib/OpenLayers/Control.js (+0/-368)
static/scripts/gis/openlayers/lib/OpenLayers/Control/ArgParser.js (+0/-166)
static/scripts/gis/openlayers/lib/OpenLayers/Control/Attribution.js (+0/-97)
static/scripts/gis/openlayers/lib/OpenLayers/Control/Button.js (+0/-44)
static/scripts/gis/openlayers/lib/OpenLayers/Control/DragFeature.js (+0/-303)
static/scripts/gis/openlayers/lib/OpenLayers/Control/DragPan.js (+0/-94)
static/scripts/gis/openlayers/lib/OpenLayers/Control/DrawFeature.js (+0/-126)
static/scripts/gis/openlayers/lib/OpenLayers/Control/EditingToolbar.js (+0/-63)
static/scripts/gis/openlayers/lib/OpenLayers/Control/GetFeature.js (+0/-595)
static/scripts/gis/openlayers/lib/OpenLayers/Control/Graticule.js (+0/-373)
static/scripts/gis/openlayers/lib/OpenLayers/Control/KeyboardDefaults.js (+0/-127)
static/scripts/gis/openlayers/lib/OpenLayers/Control/LayerSwitcher.js (+0/-620)
static/scripts/gis/openlayers/lib/OpenLayers/Control/Measure.js (+0/-321)
static/scripts/gis/openlayers/lib/OpenLayers/Control/ModifyFeature.js (+0/-777)
static/scripts/gis/openlayers/lib/OpenLayers/Control/MouseDefaults.js (+0/-368)
static/scripts/gis/openlayers/lib/OpenLayers/Control/MousePosition.js (+0/-213)
static/scripts/gis/openlayers/lib/OpenLayers/Control/MouseToolbar.js (+0/-406)
static/scripts/gis/openlayers/lib/OpenLayers/Control/NavToolbar.js (+0/-55)
static/scripts/gis/openlayers/lib/OpenLayers/Control/Navigation.js (+0/-303)
static/scripts/gis/openlayers/lib/OpenLayers/Control/NavigationHistory.js (+0/-423)
static/scripts/gis/openlayers/lib/OpenLayers/Control/OverviewMap.js (+0/-720)
static/scripts/gis/openlayers/lib/OpenLayers/Control/Pan.js (+0/-86)
static/scripts/gis/openlayers/lib/OpenLayers/Control/PanPanel.js (+0/-63)
static/scripts/gis/openlayers/lib/OpenLayers/Control/PanZoom.js (+0/-246)
static/scripts/gis/openlayers/lib/OpenLayers/Control/PanZoomBar.js (+0/-396)
static/scripts/gis/openlayers/lib/OpenLayers/Control/Panel.js (+0/-371)
static/scripts/gis/openlayers/lib/OpenLayers/Control/Permalink.js (+0/-220)
static/scripts/gis/openlayers/lib/OpenLayers/Control/SLDSelect.js (+0/-570)
static/scripts/gis/openlayers/lib/OpenLayers/Control/Scale.js (+0/-99)
static/scripts/gis/openlayers/lib/OpenLayers/Control/ScaleLine.js (+0/-223)
static/scripts/gis/openlayers/lib/OpenLayers/Control/SelectFeature.js (+0/-613)
static/scripts/gis/openlayers/lib/OpenLayers/Control/Snapping.js (+0/-547)
static/scripts/gis/openlayers/lib/OpenLayers/Control/Split.js (+0/-498)
static/scripts/gis/openlayers/lib/OpenLayers/Control/TransformFeature.js (+0/-579)
static/scripts/gis/openlayers/lib/OpenLayers/Control/WMSGetFeatureInfo.js (+0/-524)
static/scripts/gis/openlayers/lib/OpenLayers/Control/WMTSGetFeatureInfo.js (+0/-442)
static/scripts/gis/openlayers/lib/OpenLayers/Control/ZoomBox.js (+0/-95)
static/scripts/gis/openlayers/lib/OpenLayers/Control/ZoomIn.js (+0/-35)
static/scripts/gis/openlayers/lib/OpenLayers/Control/ZoomOut.js (+0/-35)
static/scripts/gis/openlayers/lib/OpenLayers/Control/ZoomPanel.js (+0/-54)
static/scripts/gis/openlayers/lib/OpenLayers/Control/ZoomToMaxExtent.js (+0/-40)
static/scripts/gis/openlayers/lib/OpenLayers/Events.js (+0/-855)
static/scripts/gis/openlayers/lib/OpenLayers/Feature.js (+0/-227)
static/scripts/gis/openlayers/lib/OpenLayers/Feature/Vector.js (+0/-454)
static/scripts/gis/openlayers/lib/OpenLayers/Feature/WFS.js (+0/-80)
static/scripts/gis/openlayers/lib/OpenLayers/Filter.js (+0/-68)
static/scripts/gis/openlayers/lib/OpenLayers/Filter/Comparison.js (+0/-258)
static/scripts/gis/openlayers/lib/OpenLayers/Filter/FeatureId.js (+0/-81)
static/scripts/gis/openlayers/lib/OpenLayers/Filter/Logical.js (+0/-119)
static/scripts/gis/openlayers/lib/OpenLayers/Filter/Spatial.js (+0/-128)
static/scripts/gis/openlayers/lib/OpenLayers/Format.js (+0/-123)
static/scripts/gis/openlayers/lib/OpenLayers/Format/ArcXML.js (+0/-1028)
static/scripts/gis/openlayers/lib/OpenLayers/Format/ArcXML/Features.js (+0/-49)
static/scripts/gis/openlayers/lib/OpenLayers/Format/Atom.js (+0/-727)
static/scripts/gis/openlayers/lib/OpenLayers/Format/CSWGetDomain.js (+0/-34)
static/scripts/gis/openlayers/lib/OpenLayers/Format/CSWGetDomain/v2_0_2.js (+0/-243)
static/scripts/gis/openlayers/lib/OpenLayers/Format/CSWGetRecords.js (+0/-34)
static/scripts/gis/openlayers/lib/OpenLayers/Format/CSWGetRecords/v2_0_2.js (+0/-440)
static/scripts/gis/openlayers/lib/OpenLayers/Format/Context.js (+0/-334)
static/scripts/gis/openlayers/lib/OpenLayers/Format/Filter.js (+0/-115)
static/scripts/gis/openlayers/lib/OpenLayers/Format/Filter/v1.js (+0/-426)
static/scripts/gis/openlayers/lib/OpenLayers/Format/Filter/v1_0_0.js (+0/-169)
static/scripts/gis/openlayers/lib/OpenLayers/Format/Filter/v1_1_0.js (+0/-182)
static/scripts/gis/openlayers/lib/OpenLayers/Format/GML.js (+0/-924)
static/scripts/gis/openlayers/lib/OpenLayers/Format/GML/Base.js (+0/-578)
static/scripts/gis/openlayers/lib/OpenLayers/Format/GML/v2.js (+0/-193)
static/scripts/gis/openlayers/lib/OpenLayers/Format/GML/v3.js (+0/-462)
static/scripts/gis/openlayers/lib/OpenLayers/Format/GPX.js (+0/-184)
static/scripts/gis/openlayers/lib/OpenLayers/Format/GeoJSON.js (+0/-716)
static/scripts/gis/openlayers/lib/OpenLayers/Format/GeoRSS.js (+0/-420)
static/scripts/gis/openlayers/lib/OpenLayers/Format/JSON.js (+0/-389)
static/scripts/gis/openlayers/lib/OpenLayers/Format/KML.js (+0/-1429)
static/scripts/gis/openlayers/lib/OpenLayers/Format/OSM.js (+0/-457)
static/scripts/gis/openlayers/lib/OpenLayers/Format/OWSCommon/v1.js (+0/-256)
static/scripts/gis/openlayers/lib/OpenLayers/Format/OWSCommon/v1_0_0.js (+0/-50)
static/scripts/gis/openlayers/lib/OpenLayers/Format/OWSCommon/v1_1_0.js (+0/-64)
static/scripts/gis/openlayers/lib/OpenLayers/Format/OWSContext.js (+0/-81)
static/scripts/gis/openlayers/lib/OpenLayers/Format/OWSContext/v0_3_1.js (+0/-589)
static/scripts/gis/openlayers/lib/OpenLayers/Format/SLD.js (+0/-131)
static/scripts/gis/openlayers/lib/OpenLayers/Format/SLD/v1.js (+0/-1100)
static/scripts/gis/openlayers/lib/OpenLayers/Format/SLD/v1_0_0.js (+0/-51)
static/scripts/gis/openlayers/lib/OpenLayers/Format/SOSCapabilities.js (+0/-83)
static/scripts/gis/openlayers/lib/OpenLayers/Format/SOSCapabilities/v1_0_0.js (+0/-158)
static/scripts/gis/openlayers/lib/OpenLayers/Format/SOSGetFeatureOfInterest.js (+0/-193)
static/scripts/gis/openlayers/lib/OpenLayers/Format/SOSGetObservation.js (+0/-262)
static/scripts/gis/openlayers/lib/OpenLayers/Format/Text.js (+0/-152)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WFS.js (+0/-220)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WFSCapabilities.js (+0/-80)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WFSCapabilities/v1.js (+0/-126)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WFSCapabilities/v1_0_0.js (+0/-157)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WFSCapabilities/v1_1_0.js (+0/-36)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WFSDescribeFeatureType.js (+0/-198)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WFST.js (+0/-34)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WFST/v1.js (+0/-368)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WFST/v1_0_0.js (+0/-150)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WFST/v1_1_0.js (+0/-161)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WKT.js (+0/-358)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMC.js (+0/-152)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMC/v1.js (+0/-835)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMC/v1_0_0.js (+0/-76)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMC/v1_1_0.js (+0/-127)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMSCapabilities.js (+0/-82)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1.js (+0/-418)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_1.js (+0/-118)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_1_0.js (+0/-62)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_1_1.js (+0/-58)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_3.js (+0/-128)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_3_0.js (+0/-30)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMSDescribeLayer.js (+0/-91)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMSDescribeLayer/v1_1.js (+0/-100)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMSGetFeatureInfo.js (+0/-284)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMTSCapabilities.js (+0/-162)
static/scripts/gis/openlayers/lib/OpenLayers/Format/WMTSCapabilities/v1_0_0.js (+0/-221)
static/scripts/gis/openlayers/lib/OpenLayers/Format/XML.js (+0/-881)
static/scripts/gis/openlayers/lib/OpenLayers/Geometry.js (+0/-456)
static/scripts/gis/openlayers/lib/OpenLayers/Geometry/Collection.js (+0/-546)
static/scripts/gis/openlayers/lib/OpenLayers/Geometry/Curve.js (+0/-93)
static/scripts/gis/openlayers/lib/OpenLayers/Geometry/LineString.js (+0/-552)
static/scripts/gis/openlayers/lib/OpenLayers/Geometry/LinearRing.js (+0/-417)
static/scripts/gis/openlayers/lib/OpenLayers/Geometry/MultiLineString.js (+0/-262)
static/scripts/gis/openlayers/lib/OpenLayers/Geometry/MultiPoint.js (+0/-70)
static/scripts/gis/openlayers/lib/OpenLayers/Geometry/MultiPolygon.js (+0/-46)
static/scripts/gis/openlayers/lib/OpenLayers/Geometry/Point.js (+0/-283)
static/scripts/gis/openlayers/lib/OpenLayers/Geometry/Polygon.js (+0/-259)
static/scripts/gis/openlayers/lib/OpenLayers/Geometry/Rectangle.js (+0/-99)
static/scripts/gis/openlayers/lib/OpenLayers/Geometry/Surface.js (+0/-17)
static/scripts/gis/openlayers/lib/OpenLayers/Handler.js (+0/-287)
static/scripts/gis/openlayers/lib/OpenLayers/Handler/Box.js (+0/-221)
static/scripts/gis/openlayers/lib/OpenLayers/Handler/Click.js (+0/-325)
static/scripts/gis/openlayers/lib/OpenLayers/Handler/Drag.js (+0/-420)
static/scripts/gis/openlayers/lib/OpenLayers/Handler/Feature.js (+0/-388)
static/scripts/gis/openlayers/lib/OpenLayers/Handler/Hover.js (+0/-183)
static/scripts/gis/openlayers/lib/OpenLayers/Handler/Keyboard.js (+0/-109)
static/scripts/gis/openlayers/lib/OpenLayers/Handler/MouseWheel.js (+0/-283)
static/scripts/gis/openlayers/lib/OpenLayers/Handler/Path.js (+0/-302)
static/scripts/gis/openlayers/lib/OpenLayers/Handler/Point.js (+0/-373)
static/scripts/gis/openlayers/lib/OpenLayers/Handler/Polygon.js (+0/-144)
static/scripts/gis/openlayers/lib/OpenLayers/Handler/RegularPolygon.js (+0/-421)
static/scripts/gis/openlayers/lib/OpenLayers/Icon.js (+0/-227)
static/scripts/gis/openlayers/lib/OpenLayers/Lang.js (+0/-133)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/ar.js (+0/-38)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/be-tarask.js (+0/-80)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/bg.js (+0/-29)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/br.js (+0/-79)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/ca.js (+0/-128)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/cs-CZ.js (+0/-69)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/da-DK.js (+0/-119)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/de.js (+0/-81)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/el.js (+0/-19)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/en-CA.js (+0/-21)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/en.js (+0/-128)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/es.js (+0/-129)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/fi.js (+0/-34)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/fr.js (+0/-80)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/fur.js (+0/-35)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/gl.js (+0/-79)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/gsw.js (+0/-79)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/hr.js (+0/-61)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/hsb.js (+0/-79)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/hu.js (+0/-80)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/ia.js (+0/-79)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/id.js (+0/-80)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/io.js (+0/-19)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/is.js (+0/-37)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/it.js (+0/-116)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/ja.js (+0/-80)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/km.js (+0/-25)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/ksh.js (+0/-79)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/nb.js (+0/-118)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/nds.js (+0/-61)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/nl.js (+0/-79)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/nn.js (+0/-27)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/oc.js (+0/-79)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/pt-BR.js (+0/-80)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/pt.js (+0/-81)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/ru.js (+0/-82)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/sk.js (+0/-71)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/sv-SE.js (+0/-71)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/te.js (+0/-27)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/vi.js (+0/-79)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/zh-CN.js (+0/-116)
static/scripts/gis/openlayers/lib/OpenLayers/Lang/zh-TW.js (+0/-117)
static/scripts/gis/openlayers/lib/OpenLayers/Layer.js (+0/-1304)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/ArcGIS93Rest.js (+0/-253)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/ArcIMS.js (+0/-466)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/Bing.js (+0/-312)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/Boxes.js (+0/-76)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/EventPane.js (+0/-418)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/FixedZoomLevels.js (+0/-315)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/GML.js (+0/-174)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/GeoRSS.js (+0/-266)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/Google.js (+0/-795)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/Google/v3.js (+0/-420)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/Grid.js (+0/-755)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/HTTPRequest.js (+0/-230)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/Image.js (+0/-254)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/KaMap.js (+0/-206)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/KaMapCache.js (+0/-148)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/MapGuide.js (+0/-489)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/MapServer.js (+0/-199)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/MapServer/Untiled.js (+0/-72)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/Markers.js (+0/-187)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/MultiMap.js (+0/-284)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/PointTrack.js (+0/-103)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/SphericalMercator.js (+0/-196)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/TMS.js (+0/-167)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/Text.js (+0/-264)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/TileCache.js (+0/-165)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/Vector.js (+0/-947)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/Vector/RootContainer.js (+0/-157)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/VirtualEarth.js (+0/-368)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/WFS.js (+0/-609)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/WMS.js (+0/-268)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/WMS/Post.js (+0/-99)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/WMS/Untiled.js (+0/-72)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/WMTS.js (+0/-476)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/WorldWind.js (+0/-120)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/XYZ.js (+0/-219)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/Yahoo.js (+0/-430)
static/scripts/gis/openlayers/lib/OpenLayers/Layer/Zoomify.js (+0/-308)
static/scripts/gis/openlayers/lib/OpenLayers/Map.js (+0/-2417)
static/scripts/gis/openlayers/lib/OpenLayers/Marker.js (+0/-242)
static/scripts/gis/openlayers/lib/OpenLayers/Marker/Box.js (+0/-120)
static/scripts/gis/openlayers/lib/OpenLayers/Popup.js (+0/-1052)
static/scripts/gis/openlayers/lib/OpenLayers/Popup/Anchored.js (+0/-198)
static/scripts/gis/openlayers/lib/OpenLayers/Popup/AnchoredBubble.js (+0/-190)
static/scripts/gis/openlayers/lib/OpenLayers/Popup/Framed.js (+0/-343)
static/scripts/gis/openlayers/lib/OpenLayers/Popup/FramedCloud.js (+0/-231)
static/scripts/gis/openlayers/lib/OpenLayers/Projection.js (+0/-178)
static/scripts/gis/openlayers/lib/OpenLayers/Protocol.js (+0/-272)
static/scripts/gis/openlayers/lib/OpenLayers/Protocol/HTTP.js (+0/-655)
static/scripts/gis/openlayers/lib/OpenLayers/Protocol/SOS.js (+0/-33)
static/scripts/gis/openlayers/lib/OpenLayers/Protocol/SOS/v1_0_0.js (+0/-132)
static/scripts/gis/openlayers/lib/OpenLayers/Protocol/SQL.js (+0/-88)
static/scripts/gis/openlayers/lib/OpenLayers/Protocol/SQL/Gears.js (+0/-561)
static/scripts/gis/openlayers/lib/OpenLayers/Protocol/WFS.js (+0/-71)
static/scripts/gis/openlayers/lib/OpenLayers/Protocol/WFS/v1.js (+0/-342)
static/scripts/gis/openlayers/lib/OpenLayers/Protocol/WFS/v1_0_0.js (+0/-44)
static/scripts/gis/openlayers/lib/OpenLayers/Protocol/WFS/v1_1_0.js (+0/-48)
static/scripts/gis/openlayers/lib/OpenLayers/Renderer.js (+0/-362)
static/scripts/gis/openlayers/lib/OpenLayers/Renderer/Canvas.js (+0/-494)
static/scripts/gis/openlayers/lib/OpenLayers/Renderer/Elements.js (+0/-1010)
static/scripts/gis/openlayers/lib/OpenLayers/Renderer/SVG.js (+0/-995)
static/scripts/gis/openlayers/lib/OpenLayers/Renderer/VML.js (+0/-999)
static/scripts/gis/openlayers/lib/OpenLayers/Request.js (+0/-358)
static/scripts/gis/openlayers/lib/OpenLayers/Request/XMLHttpRequest.js (+0/-384)
static/scripts/gis/openlayers/lib/OpenLayers/Rule.js (+0/-240)
static/scripts/gis/openlayers/lib/OpenLayers/SingleFile.js (+0/-10)
static/scripts/gis/openlayers/lib/OpenLayers/Strategy.js (+0/-117)
static/scripts/gis/openlayers/lib/OpenLayers/Strategy/BBOX.js (+0/-278)
static/scripts/gis/openlayers/lib/OpenLayers/Strategy/Cluster.js (+0/-280)
static/scripts/gis/openlayers/lib/OpenLayers/Strategy/Filter.js (+0/-164)
static/scripts/gis/openlayers/lib/OpenLayers/Strategy/Fixed.js (+0/-138)
static/scripts/gis/openlayers/lib/OpenLayers/Strategy/Paging.js (+0/-236)
static/scripts/gis/openlayers/lib/OpenLayers/Strategy/Refresh.js (+0/-140)
static/scripts/gis/openlayers/lib/OpenLayers/Strategy/Save.js (+0/-229)
static/scripts/gis/openlayers/lib/OpenLayers/Style.js (+0/-443)
static/scripts/gis/openlayers/lib/OpenLayers/Style2.js (+0/-111)
static/scripts/gis/openlayers/lib/OpenLayers/StyleMap.js (+0/-160)
static/scripts/gis/openlayers/lib/OpenLayers/Symbolizer.js (+0/-51)
static/scripts/gis/openlayers/lib/OpenLayers/Symbolizer/Line.js (+0/-69)
static/scripts/gis/openlayers/lib/OpenLayers/Symbolizer/Point.js (+0/-141)
static/scripts/gis/openlayers/lib/OpenLayers/Symbolizer/Polygon.js (+0/-81)
static/scripts/gis/openlayers/lib/OpenLayers/Symbolizer/Raster.js (+0/-34)
static/scripts/gis/openlayers/lib/OpenLayers/Symbolizer/Text.js (+0/-65)
static/scripts/gis/openlayers/lib/OpenLayers/Tile.js (+0/-281)
static/scripts/gis/openlayers/lib/OpenLayers/Tile/Image.js (+0/-578)
static/scripts/gis/openlayers/lib/OpenLayers/Tile/Image/IFrame.js (+0/-262)
static/scripts/gis/openlayers/lib/OpenLayers/Tile/WFS.js (+0/-192)
static/scripts/gis/openlayers/lib/OpenLayers/Tween.js (+0/-318)
static/scripts/gis/openlayers/lib/OpenLayers/Util.js (+0/-1797)
static/scripts/gis/openlayers/lib/Rico/Color.js (+0/-244)
static/scripts/gis/openlayers/lib/Rico/Corner.js (+0/-330)
static/scripts/gis/openlayers/license.txt (+0/-38)
static/scripts/gis/openlayers/news.txt (+0/-59)
static/scripts/gis/openlayers/readme.txt (+0/-72)
static/scripts/gis/openlayers/release-license.txt (+0/-3)
static/scripts/gis/openlayers/repository-license.txt (+0/-3)
static/scripts/gis/openlayers/theme/default/google.css (+0/-10)
static/scripts/gis/openlayers/theme/default/ie6-style.css (+0/-7)
static/scripts/gis/openlayers/theme/default/style.css (+0/-397)
static/scripts/gis/osm_styles.js (+0/-13)
static/scripts/gis/proj4js/index.html (+0/-172)
static/scripts/gis/proj4js/lib/OverloadedProj4js.js (+0/-201)
static/scripts/gis/proj4js/lib/defs/EPSG102757.js (+0/-1)
static/scripts/gis/proj4js/lib/defs/EPSG102758.js (+0/-1)
static/scripts/gis/proj4js/lib/defs/EPSG21781.js (+0/-1)
static/scripts/gis/proj4js/lib/defs/EPSG26591.js (+0/-1)
static/scripts/gis/proj4js/lib/defs/EPSG26912.js (+0/-1)
static/scripts/gis/proj4js/lib/defs/EPSG27200.js (+0/-5)
static/scripts/gis/proj4js/lib/defs/EPSG27563.js (+0/-1)
static/scripts/gis/proj4js/lib/defs/EPSG41001.js (+0/-1)
static/scripts/gis/proj4js/lib/defs/EPSG4139.js (+0/-1)
static/scripts/gis/proj4js/lib/defs/EPSG4181.js (+0/-1)
static/scripts/gis/proj4js/lib/defs/EPSG42304.js (+0/-1)
static/scripts/gis/proj4js/lib/defs/EPSG4272.js (+0/-1)
static/scripts/gis/proj4js/lib/defs/EPSG4302.js (+0/-2)
static/scripts/gis/proj4js/lib/defs/EPSG900913.js (+0/-5)
static/scripts/gis/proj4js/lib/defs/EPSG900913.txt (+0/-11)
static/scripts/gis/proj4js/lib/defs/GOOGLE.js (+0/-2)
static/scripts/gis/proj4js/lib/proj4js-combined.js (+0/-4987)
static/scripts/gis/proj4js/lib/proj4js-compressed.js (+0/-216)
static/scripts/gis/proj4js/lib/proj4js.js (+0/-1517)
static/scripts/gis/proj4js/lib/projCode/aea.js (+0/-149)
static/scripts/gis/proj4js/lib/projCode/aeqd.js (+0/-75)
static/scripts/gis/proj4js/lib/projCode/cass.js (+0/-162)
static/scripts/gis/proj4js/lib/projCode/cea.js (+0/-85)
static/scripts/gis/proj4js/lib/projCode/eqc.js (+0/-42)
static/scripts/gis/proj4js/lib/projCode/eqdc.js (+0/-140)
static/scripts/gis/proj4js/lib/projCode/equi.js (+0/-72)
static/scripts/gis/proj4js/lib/projCode/gauss.js (+0/-44)
static/scripts/gis/proj4js/lib/projCode/gnom.js (+0/-115)
static/scripts/gis/proj4js/lib/projCode/gstmerc.js (+0/-52)
static/scripts/gis/proj4js/lib/projCode/laea.js (+0/-356)
static/scripts/gis/proj4js/lib/projCode/lcc.js (+0/-148)
static/scripts/gis/proj4js/lib/projCode/merc.js (+0/-115)
static/scripts/gis/proj4js/lib/projCode/mill.js (+0/-68)
static/scripts/gis/proj4js/lib/projCode/moll.js (+0/-100)
static/scripts/gis/proj4js/lib/projCode/nzmg.js (+0/-286)
static/scripts/gis/proj4js/lib/projCode/omerc.js (+0/-256)
static/scripts/gis/proj4js/lib/projCode/ortho.js (+0/-113)
static/scripts/gis/proj4js/lib/projCode/poly.js (+0/-157)
static/scripts/gis/proj4js/lib/projCode/sinu.js (+0/-79)
static/scripts/gis/proj4js/lib/projCode/somerc.js (+0/-110)
static/scripts/gis/proj4js/lib/projCode/stere.js (+0/-244)
static/scripts/gis/proj4js/lib/projCode/sterea.js (+0/-56)
static/scripts/gis/proj4js/lib/projCode/tmerc.js (+0/-141)
static/scripts/gis/proj4js/lib/projCode/utm.js (+0/-43)
static/scripts/gis/proj4js/lib/projCode/vandg.js (+0/-137)
static/scripts/gis/usng2.js (+0/-553)
static/scripts/hs_base.js (+0/-33)
static/scripts/panels/side_panel.js (+0/-141)
static/scripts/panels/tool_panel.js (+0/-790)
static/scripts/sencha/sencha-touch-debug.js (+0/-29754)
static/scripts/sencha/sencha-touch.js (+0/-6)
static/scripts/tools/Eden-Python-Installer-Dev.nsi (+0/-143)
static/scripts/tools/build.cmd (+0/-5)
static/scripts/tools/build.sahana.py (+0/-319)
static/scripts/tools/compile.py (+0/-34)
static/scripts/tools/dbstruct.py (+0/-192)
static/scripts/tools/fabfile.py (+0/-421)
static/scripts/tools/jsmin.py (+0/-216)
static/scripts/tools/languages.py (+0/-37)
static/scripts/tools/mergejs.py (+0/-295)
static/scripts/tools/noop.py (+0/-6)
static/scripts/tools/pep8.py (+0/-863)
static/scripts/tools/sahana.js.cfg (+0/-27)
static/scripts/tools/sahana.js.geoexplorer.cfg (+0/-12)
static/scripts/tools/sahana.js.geoext.cfg (+0/-73)
static/scripts/tools/sahana.js.gis.cfg (+0/-159)
static/scripts/tools/sahana.js.gxp.cfg (+0/-21)
static/scripts/tools/standalone_exe.py (+0/-65)
static/scripts/tools/topo.py (+0/-107)
static/scripts/tools/toposort.py (+0/-260)
static/scripts/tools/trans.py (+0/-63)
static/scripts/web2py/calendar-1.0.js (+0/-1806)
static/scripts/web2py/calendar.js (+0/-22)
static/scripts/web2py/dd_belatedpng.js (+0/-13)
static/scripts/web2py/jquery-1.4.4.js (+0/-7179)
static/scripts/web2py/jquery-1.4.4.min.js (+0/-167)
static/scripts/web2py/jquery.timeentry.js (+0/-570)
static/scripts/web2py/modernizr-1.6.min.js (+0/-30)
static/scripts/web2py/timeentry.js (+0/-19)
static/scripts/web2py/web2py.js (+0/-71)
static/selenium/client/selenium.py (+0/-2071)
static/selenium/client/selenium_test_suite.py (+0/-34)
static/selenium/client/selenium_test_suite_headless.py (+0/-31)
static/selenium/client/test_ajax_jsf.py (+0/-54)
static/selenium/client/test_default_server.py (+0/-52)
static/selenium/client/test_google.py (+0/-38)
static/selenium/client/test_i18n.py (+0/-49)
static/selenium/data/browser.txt (+0/-7)
static/selenium/data/location.txt (+0/-21)
static/selenium/data/organisation.txt (+0/-2)
static/selenium/data/testModules.txt (+0/-5)
static/selenium/data/user.txt (+0/-1)
static/selenium/scripts/HTMLTestRunner.py (+0/-824)
static/selenium/scripts/actions.py (+0/-337)
static/selenium/scripts/adminUserDetails.py (+0/-6)
static/selenium/scripts/createTestAccount.py (+0/-19)
static/selenium/scripts/deleteTestAccount.py (+0/-17)
static/selenium/scripts/dummyTest.py (+0/-30)
static/selenium/scripts/locationSelector.py (+0/-1759)
static/selenium/scripts/locations.py (+0/-1947)
static/selenium/scripts/organisationTest.py (+0/-178)
static/selenium/scripts/organzationTest.html (+0/-241)
static/selenium/scripts/organzationUITest.html (+0/-36)
static/selenium/scripts/regressionTests.cmd (+0/-1)
static/selenium/scripts/regressionTests.py (+0/-383)
static/selenium/scripts/sahanaTest.py (+0/-141)
static/selenium/scripts/selenium.py (+0/-2071)
static/selenium/scripts/userManagement.py (+0/-66)
static/selenium/selenium-version (+0/-8)
static/styles/S3/RowEditor.css (+0/-61)
static/styles/S3/ajaxS3.css (+0/-34)
static/styles/S3/colorbox.css (+0/-63)
static/styles/S3/colorpicker.css (+0/-161)
static/styles/S3/fileuploader.css (+0/-31)
static/styles/S3/importer.css (+0/-12)
static/styles/S3/jquery.autocomplete.css (+0/-48)
static/styles/S3/jquery.bsmselect.css (+0/-64)
static/styles/S3/jquery.cluetip.css (+0/-230)
static/styles/S3/jquery.dataTables.css (+0/-380)
static/styles/S3/jquery.jqplot.css (+0/-212)
static/styles/S3/jquery.jqplot.min.css (+0/-1)
static/styles/S3/jquery.multiSelect.css (+0/-85)
static/styles/S3/jquery.ui.autocomplete.css (+0/-54)
static/styles/S3/jquery.ui.core.css (+0/-41)
static/styles/S3/jquery.ui.datepicker.css (+0/-68)
static/styles/S3/jquery.ui.theme.css (+0/-254)
static/styles/S3/potlatch2.css (+0/-10)
static/styles/S3/print_form.css (+0/-138)
static/styles/S3/rat.css (+0/-74)
static/styles/S3/role.css (+0/-45)
static/styles/S3/s3.multiselect.widget.css (+0/-33)
static/styles/S3/sahana.css (+0/-899)
static/styles/S3/sahana.min.css (+0/-1)
static/styles/S3/silk.css (+0/-185)
static/styles/S3/sync.css (+0/-47)
static/styles/S3/template.css (+0/-898)
static/styles/T2/rating.css (+0/-45)
static/styles/T2/t2.css (+0/-18)
static/styles/admin/import_job.css (+0/-4)
static/styles/gis/about.css (+0/-35)
static/styles/gis/cdauth.css (+0/-6)
static/styles/gis/geoexplorer.css (+0/-402)
static/styles/gis/geoext-all-debug.css (+0/-7)
static/styles/gis/gis.css (+0/-153)
static/styles/gis/google.css (+0/-14)
static/styles/gis/ie.css (+0/-20)
static/styles/gis/ie6-style.css (+0/-7)
static/styles/gis/layerlegend.css (+0/-6)
static/styles/gis/mapfish.css (+0/-82)
static/styles/gis/popup.css (+0/-9)
static/styles/gis/printpreview.css (+0/-42)
static/styles/gis/style.css (+0/-401)
static/styles/hs.css (+3/-0)
static/styles/sencha/android.css (+0/-1)
static/styles/sencha/apple.css (+0/-1)
static/styles/sencha/sencha-touch-debug.css (+0/-1)
static/styles/sencha/sencha-touch.css (+0/-1)
static/styles/web2py/calendar.css (+0/-1)
static/xslt/export/geojson.xsl (+0/-87)
static/xslt/export/georss.xsl (+0/-92)
static/xslt/export/gpx.xsl (+0/-123)
static/xslt/export/have.xsl (+0/-531)
static/xslt/export/kml.xsl (+0/-180)
static/xslt/export/lmx.xsl (+0/-56)
static/xslt/export/osm.xsl (+0/-160)
static/xslt/export/pfif.xsl (+0/-231)
static/xslt/export/rss.xsl (+0/-195)
static/xslt/export/rss_base.xsl (+0/-179)
static/xslt/export/xml.xsl (+0/-7)
static/xslt/import/have.xsl (+0/-83)
static/xslt/import/lmx.xsl (+0/-45)
static/xslt/import/odk.xsl (+0/-31)
static/xslt/import/osm.xsl (+0/-76)
static/xslt/import/pfif.xsl (+0/-199)
static/xslt/import/ushahidi.xsl (+0/-146)
static/xslt/import/xml.xsl (+0/-7)
tool/aggregate.py (+5/-2)
tool/sample.py (+0/-78)
views/_create.html (+0/-26)
views/_delete.html (+0/-30)
views/_display.html (+0/-39)
views/_list.html (+0/-30)
views/_list_create.html (+0/-59)
views/_popup.html (+0/-8)
views/_search.html (+0/-51)
views/_searchbox.html (+0/-31)
views/_update.html (+0/-30)
views/admin/_import_job_reload_status.html (+0/-20)
views/admin/_import_job_status_failed.html (+0/-10)
views/admin/_import_job_status_import.html (+0/-4)
views/admin/_import_job_status_imported.html (+0/-11)
views/admin/_import_job_status_new.html (+0/-25)
views/admin/_import_job_status_processed.html (+0/-27)
views/admin/_import_job_status_processing.html (+0/-5)
views/admin/appadmin.html (+0/-72)
views/admin/errors.html (+0/-47)
views/admin/export_data.html (+0/-50)
views/admin/group_update.html (+0/-10)
views/admin/groups.html (+0/-38)
views/admin/import_data.html (+0/-88)
views/admin/import_job_list.html (+0/-9)
views/admin/import_job_update.html (+0/-37)
views/admin/index.html (+0/-17)
views/admin/resources.js (+0/-32)
views/admin/role_edit.html (+0/-49)
views/admin/role_list.html (+0/-23)
views/admin/role_users.html (+0/-31)
views/admin/theme_create.html (+0/-3)
views/admin/theme_list_create.html (+0/-3)
views/admin/theme_popup.html (+0/-3)
views/admin/theme_update.html (+0/-3)
views/admin/themes.html (+0/-19)
views/admin/ticket.html (+0/-10)
views/admin/user_create.html (+0/-3)
views/admin/user_form.html (+0/-62)
views/admin/user_list_create.html (+0/-3)
views/admin/user_roles.html (+0/-2)
views/admin/user_update.html (+0/-5)
views/admin/users.html (+0/-38)
views/assess/assess_create.html (+0/-11)
views/assess/assess_list.html (+0/-6)
views/assess/assess_list_create.html (+0/-11)
views/assess/assess_short_mobile.html (+0/-34)
views/assess/basic_assess.html (+0/-22)
views/assess/index.html (+0/-22)
views/assess/mobile_basic_assess.html (+0/-35)
views/auth/_login.html (+0/-9)
views/auth/_register.html (+0/-18)
views/auth/login.html (+0/-23)
views/auth/validation.js (+0/-45)
views/budget/budget_display.html (+0/-8)
views/budget/budget_staff_bundle_header.html (+0/-3)
views/budget/budget_staff_bundle_list.html (+0/-15)
views/budget/budget_staff_bundle_list_create.html (+0/-71)
views/budget/bundle_display.html (+0/-8)
views/budget/bundle_kit_item_header.html (+0/-3)
views/budget/bundle_kit_item_list.html (+0/-15)
views/budget/bundle_kit_item_list_create.html (+0/-127)
views/budget/bundle_list_create.html (+0/-8)
views/budget/bundle_update.html (+0/-9)
views/budget/index.html (+0/-11)
views/budget/item_create.html (+0/-3)
views/budget/item_list_create.html (+0/-3)
views/budget/item_update.html (+0/-3)
views/budget/items.js (+0/-53)
views/budget/kit_display.html (+0/-7)
views/budget/kit_item_header.html (+0/-3)
views/budget/kit_item_list.html (+0/-15)
views/budget/kit_item_list_create.html (+0/-36)
views/budget/kit_list_create.html (+0/-8)
views/budget/kit_update.html (+0/-8)
views/cr/index.html (+0/-17)
views/cr/shelter_autocompletes.html (+0/-5)
views/cr/shelter_create.html (+0/-9)
views/cr/shelter_list_create.html (+0/-12)
views/cr/shelter_optional_data.js (+0/-37)
views/cr/shelter_popup.html (+0/-9)
views/cr/shelter_update.html (+0/-5)
views/create.html (+0/-2)
views/dataTables.html (+0/-255)
views/default/about.html (+0/-73)
views/default/contact.html (+0/-14)
views/default/header.html (+0/-5)
views/default/help.html (+0/-5)
views/default/index.html (+0/-76)
views/default/list.html (+0/-25)
views/default/menu.html (+0/-6)
views/default/user.html (+0/-41)
views/delete.html (+0/-2)
views/delphi/discuss.html (+0/-51)
views/delphi/group_summary.html (+0/-30)
views/delphi/group_update.html (+0/-10)
views/delphi/index.html (+0/-34)
views/delphi/status.html (+0/-49)
views/delphi/summary.html (+0/-49)
views/delphi/vote.html (+0/-270)
views/display.html (+0/-2)
views/doc/bulk_upload.html (+0/-35)
views/doc/index.html (+0/-12)
views/dvi/index.html (+0/-53)
views/dvr/index.html (+0/-16)
views/errors/index.html (+0/-22)
views/ext.html (+0/-30)
views/extEditorGrid.html (+0/-3)
views/extform.js (+0/-89)
views/extlist.js (+0/-119)
views/extlistcreate.js (+0/-222)
views/flood/index.html (+0/-12)
views/footer.html (+0/-7)
views/form_description.html (+0/-7)
views/form_enabled.html (+0/-12)
views/form_name.html (+0/-8)
views/form_priority.html (+0/-18)
views/formats.html (+0/-13)
views/generic.html (+0/-12)
views/generic.json (+0/-11)
views/generic.rss (+0/-16)
views/generic.xls (+0/-24)
views/generic.xml (+0/-11)
views/gis/about.html (+0/-35)
views/gis/catalogue_toolbar.html (+0/-47)
views/gis/convert_gps.html (+0/-200)
views/gis/create.html (+0/-3)
views/gis/display.html (+0/-3)
views/gis/display_feature.html (+0/-17)
views/gis/display_features.html (+0/-17)
views/gis/ext-dd-mod.js (+0/-215)
views/gis/feature_class.js (+0/-36)
views/gis/feature_class_create.html (+0/-4)
views/gis/feature_class_list.html (+0/-3)
views/gis/feature_class_list_create.html (+0/-6)
views/gis/feature_class_update.html (+0/-4)
views/gis/feature_crud.js (+0/-77)
views/gis/feature_group_contents_list.html (+0/-19)
views/gis/feature_group_contents_list_create.html (+0/-34)
views/gis/feature_group_display.html (+0/-5)
views/gis/feature_group_list.html (+0/-5)
views/gis/feature_group_list_create.html (+0/-6)
views/gis/feature_group_update.html (+0/-5)
views/gis/feature_layer_create.html (+0/-50)
views/gis/feature_layer_update.html (+0/-8)
views/gis/geocoder_results_popup.html (+0/-107)
views/gis/geoexplorer.html (+0/-167)
views/gis/gis_layout.html (+0/-33)
views/gis/gis_scripts_debug.html (+0/-21)
views/gis/gis_scripts_min.html (+0/-19)
views/gis/gis_styles_debug.html (+0/-14)
views/gis/hs.html (+0/-222)
views/gis/index.html (+0/-43)
views/gis/legend.html (+0/-25)
views/gis/list.html (+0/-3)
views/gis/list_create.html (+0/-3)
views/gis/location_autocomplete.js (+0/-144)
views/gis/location_create.html (+0/-45)
views/gis/location_dedup_table.html (+0/-54)
views/gis/location_display.html (+0/-12)
views/gis/location_duplicates.html (+0/-12)
views/gis/location_list_create.html (+0/-4)
views/gis/location_popup.html (+0/-110)
views/gis/location_resolve.html (+0/-289)
views/gis/location_update.html (+0/-40)
views/gis/map_selector.html (+0/-28)
views/gis/map_service_catalogue.html (+0/-23)
views/gis/map_viewer.html (+0/-105)
views/gis/map_viewing_client.html (+0/-2)
views/gis/map_viewing_client_oldHS.html (+0/-113)
views/gis/msgbox-loader.js (+0/-65)
views/gis/ol_controls.js (+0/-76)
views/gis/ol_controls_features.js (+0/-130)
views/gis/ol_controls_features_geometry.js (+0/-112)
views/gis/ol_features_popup.html (+0/-1)
views/gis/ol_features_popup_bak.html (+0/-60)
views/gis/ol_functions.js (+0/-20)
views/gis/ol_js_loaders.html (+0/-30)
views/gis/ol_layers_all.js (+0/-33)
views/gis/ol_layers_bing.js (+0/-16)
views/gis/ol_layers_feature.js (+0/-26)
views/gis/ol_layers_features.js (+0/-48)
views/gis/ol_layers_features2.py (+0/-148)
views/gis/ol_layers_features_all.js (+0/-16)
views/gis/ol_layers_georss.js (+0/-67)
views/gis/ol_layers_google.js (+0/-16)
views/gis/ol_layers_gpx.js (+0/-23)
views/gis/ol_layers_js.js (+0/-3)
views/gis/ol_layers_kml.js (+0/-34)
views/gis/ol_layers_openstreetmap.js (+0/-26)
views/gis/ol_layers_tms.js (+0/-10)
views/gis/ol_layers_wms.js (+0/-70)
views/gis/ol_layers_xyz.js (+0/-29)
views/gis/ol_layers_yahoo.js (+0/-12)
views/gis/ol_start_vars.js (+0/-52)
views/gis/ol_status.html (+0/-15)
views/gis/ol_vector_registerEvents.js (+0/-10)
views/gis/potlatch2.html (+0/-68)
views/gis/test.html (+0/-10)
views/gis/test2.html (+0/-1447)
views/gis/test_analysis.html (+0/-5)
views/gis/toolbar.js (+0/-340)
views/gis/update.html (+0/-3)
views/gis/upload.html (+0/-49)
views/gis/waypoint_upload.html (+0/-247)
views/gis/win/_dropzone.html (+0/-14)
views/gis/win/bridge.html (+0/-284)
views/gis/win/color.html (+0/-30)
views/gis/win/context.html (+0/-71)
views/gis/win/form_panel.html (+0/-99)
views/gis/win/function.html (+0/-156)
views/gis/win/graph_win.html (+0/-13)
views/gis/win/lit.html (+0/-271)
views/gis/win/main.html (+0/-324)
views/gis/win/mgr.html (+0/-17)
views/gis/win/mymaps.html (+0/-21)
views/gis/win/qs.html (+0/-85)
views/gis/win/register_dropzone.html (+0/-21)
views/gis/win/trash.html (+0/-25)
views/gis/win/wms_capabilities.html (+0/-26)
views/gis/wrapup.html (+0/-1)
views/gis/xhs.js (+0/-2402)
views/gis/xhs_old.js (+0/-2164)
views/hms/hospital_display.html (+0/-12)
views/hms/hospital_update.html (+0/-12)
views/hms/index.html (+0/-74)
views/importer/gettoken.html (+0/-5)
views/importer/googledoc.html (+0/-18)
views/importer/index.html (+0/-15)
views/importer/re_import.html (+0/-22)
views/importer/recvdata.html (+0/-5)
views/importer/similar_rows.html (+0/-27)
views/importer/spreadsheet.html (+0/-13)
views/importer/spreadsheetview.html (+0/-63)
views/inventory/index.html (+0/-9)
views/irs/icategory_list_create.html (+0/-3)
views/irs/index.html (+0/-10)
views/irs/maps.html (+0/-2)
views/jquery.html (+0/-16)
views/key.html (+0/-3)
views/l10n.js (+0/-9)
views/layout.html (+0/-146)
views/layout_iframe.html (+0/-17)
views/layout_popup.html (+0/-189)
views/list.html (+0/-2)
views/list_create.html (+0/-2)
views/list_create_ext.html (+0/-20)
views/list_ext.html (+0/-26)
views/lms/index.html (+0/-14)
views/lms/item_create.html (+0/-68)
views/lms/item_list_create.html (+0/-69)
views/lms/items.js (+0/-53)
views/lms/kit_display.html (+0/-3)
views/lms/kit_item_header.html (+0/-3)
views/lms/kit_item_list.html (+0/-15)
views/lms/kit_item_list_create.html (+0/-36)
views/lms/kit_list_create.html (+0/-8)
views/lms/kit_update.html (+0/-8)
views/logs/index.html (+0/-9)
views/mobile/index.html (+0/-4)
views/mobile/settings_update.html (+0/-12)
views/msg/_compose.html (+0/-129)
views/msg/compose.html (+0/-2)
views/msg/contacts.html (+0/-12)
views/msg/email_settings_update.html (+0/-14)
views/msg/gateway_settings_update.html (+0/-12)
views/msg/group_display.html (+0/-3)
views/msg/group_update.html (+0/-3)
views/msg/group_user_header.html (+0/-4)
views/msg/group_user_list.html (+0/-15)
views/msg/group_user_list_create.html (+0/-37)
views/msg/index.html (+0/-15)
views/msg/log_list.html (+0/-3)
views/msg/log_list_create.html (+0/-3)
views/msg/modem_settings_update.html (+0/-12)
views/msg/outbox_create.html (+0/-105)
views/msg/setting_display.html (+0/-23)
views/msg/setting_update.html (+0/-12)
views/msg/tropo_settings_update.html (+0/-12)
views/org/index.html (+0/-16)
views/org/offices_by_org.js (+0/-25)
views/org/organisation_assess_list.html (+0/-6)
views/org/organisation_popup.html (+0/-15)
views/org/staff_autocompletes.html (+0/-36)
views/org/staff_create.html (+0/-3)
views/org/staff_list_create.html (+0/-3)
views/org/staff_popup.html (+0/-3)
views/pagenav.html (+0/-14)
views/pf/index.html (+0/-55)
views/plain.html (+0/-1)
views/popup.html (+0/-2)
views/pr/ajaxtips/head_form_front.html (+0/-1)
views/pr/index.html (+0/-77)
views/pr/person_create.html (+0/-8)
views/pr/person_dedup_table.html (+0/-54)
views/pr/person_duplicates.html (+0/-20)
views/pr/person_popup.html (+0/-138)
views/pr/person_presence_list.html (+0/-36)
views/pr/person_presence_list_create.html (+0/-43)
views/pr/person_resolve.html (+0/-322)
views/pr/person_update.html (+0/-8)
views/project/gap_map.html (+0/-10)
views/project/gap_report.html (+0/-11)
views/project/index.html (+0/-15)
views/project/project_create.html (+0/-3)
views/project/project_list_create.html (+0/-3)
views/project/project_search.html (+0/-30)
views/project/project_update.html (+0/-3)
views/project/project_validation.js (+0/-28)
views/project/task_popup.html (+0/-27)
views/rms/helptext.html (+0/-29)
views/rms/index.html (+0/-63)
views/rms/req_create.html (+0/-3)
views/rms/req_list_create.html (+0/-3)
views/rms/req_popup.html (+0/-42)
views/rssviewer.html (+0/-34)
views/sahana_scripts_debug.html (+0/-141)
views/sahana_scripts_min.html (+0/-110)
views/sahana_styles_debug.html (+0/-40)
views/search.html (+0/-20)
views/search_simple.html (+0/-2)
views/searchbox.html (+0/-14)
views/survey/index.html (+0/-15)
views/survey/layout_popup.html (+0/-101)
views/survey/question_options_create.html (+0/-98)
views/survey/question_options_update.html (+0/-93)
views/survey/question_update.html (+0/-4)
views/survey/questions.html (+0/-78)
views/survey/series_create.html (+0/-3)
views/survey/series_update.html (+0/-3)
views/survey/series_validation.js (+0/-28)
views/survey/table.html (+0/-26)
views/survey/table_create.html (+0/-3)
views/survey/table_update.html (+0/-21)
views/survey/template_create.html (+0/-3)
views/survey/template_update.html (+0/-4)
views/sync/history.html (+0/-43)
views/sync/index.html (+0/-92)
views/sync/now.html (+0/-85)
views/sync/schedule.html (+0/-115)
views/sync/schedule_create.html (+0/-196)
views/tbc.html (+0/-7)
views/test/jquery_upload.html (+0/-39)
views/test/test.html (+0/-97)
views/test/webgrid.html (+0/-7)
views/ticket/index.html (+0/-16)
views/ticket/log_update.html (+0/-35)
views/update.html (+0/-2)
views/vol/compose_group.html (+0/-2)
views/vol/compose_person.html (+0/-2)
views/vol/index.html (+0/-42)
views/vol/person_list_create.html (+0/-3)
views/vol/project_create.html (+0/-3)
views/vol/project_list_create.html (+0/-3)
views/vol/project_update.html (+0/-3)
views/vol/showSkillOptions.html (+0/-10)
views/vol/skillsearch.html (+0/-6)
views/vol/view_map.html (+0/-2)
views/xforms.xml (+0/-21)
views/xml.html (+0/-1)
To merge this branch: bzr merge lp:~zack-krejci/healthscapes/trunk
Reviewer Review Type Date Requested Status
nicopresto Pending
Review via email: mp+47328@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'controllers'
2=== removed directory 'controllers'
3=== added file 'controllers/admin.py'
4--- controllers/admin.py 1970-01-01 00:00:00 +0000
5+++ controllers/admin.py 2011-01-24 22:41:50 +0000
6@@ -0,0 +1,1241 @@
7+# -*- coding: utf-8 -*-
8+
9+"""
10+ Admin Controllers
11+"""
12+
13+import cPickle as pickle
14+import csv
15+from gluon.admin import *
16+from gluon.fileutils import listdir
17+
18+module = "admin"
19+
20+# Options Menu (available in all Functions' Views)
21+# - can Insert/Delete items from default menus within a function, if required.
22+response.menu_options = admin_menu_options
23+
24+# S3 framework functions
25+# -----------------------------------------------------------------------------
26+def index():
27+
28+ """ Module's Home Page """
29+
30+ module_name = deployment_settings.modules[module].name_nice
31+ response.title = module_name
32+ return dict(module_name=module_name)
33+
34+
35+# -----------------------------------------------------------------------------
36+@auth.s3_requires_membership(1)
37+def setting():
38+
39+ """ RESTful CRUD controller """
40+
41+ resourcename = request.function
42+ tablename = "s3_" + resourcename
43+ table = db[tablename]
44+
45+ table.admin_name.label = T("Admin Name")
46+ table.admin_email.label = T("Admin Email")
47+ table.admin_tel.label = T("Admin Tel")
48+ #table.utc_offset.label = T("UTC Offset")
49+ table.theme.label = T("Theme")
50+ table.theme.comment = DIV(A(T("Add Theme"), _class="colorbox", _href=URL(r=request, c="admin", f="theme", args="create", vars=dict(format="popup")), _target="top", _title=T("Add Theme"))),
51+ #table.archive_not_delete.label = T("Archive not Delete")
52+ #table.archive_not_delete.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Archive not Delete") + "|" + T("If this setting is enabled then all deleted records are just flagged as deleted instead of being really deleted. They will appear in the raw database access but won't be visible to normal users."))
53+ #table.debug.label = T("Debug")
54+ #table.debug.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Debug") + "|" + T("Switch this on to use individual CSS/Javascript files for diagnostics during development."))
55+ #table.self_registration.label = T("Self Registration")
56+ #table.self_registration.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Self-registration") + "|" + T("Can users register themselves for authenticated login access?"))
57+ #table.security_policy.label = T("Security Policy")
58+ #table.security_policy.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Security Policy") + "|" + T("The simple policy allows anonymous users to Read & registered users to Edit. The full security policy allows the administrator to set permissions on individual tables or records - see models/zzz.py."))
59+ #table.audit_read.label = T("Audit Read")
60+ #table.audit_read.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Audit Read") + "|" + T("If enabled then a log is maintained of all records a user accesses. If disabled then it can still be enabled on a per-module basis."))
61+ #table.audit_write.label = T("Audit Write")
62+ #table.audit_write.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Audit Write") + "|" + T("If enabled then a log is maintained of all records a user edits. If disabled then it can still be enabled on a per-module basis."))
63+
64+ s3.crud_strings[tablename] = Storage(
65+ title_update = T("Edit Settings"),
66+ msg_record_modified = T("Settings updated"),
67+ label_list_button = None)
68+
69+ s3xrc.model.configure(table,
70+ deletable=False,
71+ listadd=False,
72+ #onvalidation=theme_check,
73+ #update_next = URL(r=request, args=[1, "update"])
74+ onaccept=theme_apply)
75+
76+ output = s3_rest_controller("s3", resourcename, list_btn=None)
77+ return output
78+
79+
80+# -----------------------------------------------------------------------------
81+@auth.s3_requires_membership(1)
82+def theme():
83+ """ RESTful CRUD controller """
84+ resource = "theme"
85+ tablename = module + "_" + resource
86+ table = db[tablename]
87+
88+ # Model options
89+ table.name.label = T("Name")
90+ #table.logo.label = T("Logo")
91+ #table.logo.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Logo") + "|" + T("Name of the file (& optional sub-path) located in static which should be used for the top-left image."))
92+ #table.header_background.label = T("Header Background")
93+ #table.header_background.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Header Background") + "|" + T("Name of the file (& optional sub-path) located in static which should be used for the background of the header."))
94+ #table.footer.label = T("Footer")
95+ #table.footer.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Footer") + "|" + T("Name of the file (& optional sub-path) located in views which should be used for footer."))
96+ table.col_background.label = T("Background Colour")
97+ table.col_txt.label = T("Text Colour for Text blocks")
98+ table.col_txt_background.label = T("Background Colour for Text blocks")
99+ table.col_txt_border.label = T("Border Colour for Text blocks")
100+ table.col_txt_underline.label = T("Colour for Underline of Subheadings")
101+ table.col_menu.label = T("Colour of dropdown menus")
102+ table.col_highlight.label = T("Colour of selected menu items")
103+ table.col_input.label = T("Colour of selected Input fields")
104+ table.col_border_btn_out.label = T("Colour of bottom of Buttons when not pressed")
105+ table.col_border_btn_in.label = T("Colour of bottom of Buttons when pressed")
106+ table.col_btn_hover.label = T("Colour of Buttons when hovering")
107+
108+ # CRUD Strings
109+ ADD_THEME = T("Add Theme")
110+ LIST_THEMES = T("List Themes")
111+ s3.crud_strings[resource] = Storage(
112+ title_create = ADD_THEME,
113+ title_display = T("Theme Details"),
114+ title_list = LIST_THEMES,
115+ title_update = T("Edit Theme"),
116+ title_search = T("Search Themes"),
117+ subtitle_create = T("Add New Theme"),
118+ subtitle_list = T("Themes"),
119+ label_list_button = LIST_THEMES,
120+ label_create_button = ADD_THEME,
121+ msg_record_created = T("Theme added"),
122+ msg_record_modified = T("Theme updated"),
123+ msg_record_deleted = T("Theme deleted"),
124+ msg_list_empty = T("No Themes currently defined"))
125+
126+ s3xrc.model.configure(table,
127+ #onvalidation=theme_check,
128+ #list_fields=["id", "name", "logo", "footer", "col_background"],
129+ list_fields=["id", "name", "col_background"],
130+ )
131+
132+ return s3_rest_controller(module, resource)
133+ s3xrc.model.clear_config(table, "onvalidation")
134+
135+
136+# -----------------------------------------------------------------------------
137+def theme_apply(form):
138+ "Apply the Theme specified by Form"
139+ if form.vars.theme:
140+ # Valid form
141+ # Relevant paths
142+ template = os.path.join(request.folder, "static", "styles", "S3", "template.css")
143+ tmp_folder = os.path.join(request.folder, "static", "scripts", "tools")
144+ out_file = os.path.join(request.folder, "static", "styles", "S3", "sahana.css")
145+ out_file2 = os.path.join(request.folder, "static", "styles", "S3", "sahana.min.css")
146+ # Check permissions
147+ if not os.access(template, os.R_OK):
148+ session.error = T("Template file %s not readable - unable to apply theme!" % template)
149+ redirect(URL(r=request, args=request.args))
150+ if not os.access(tmp_folder, os.W_OK):
151+ session.error = T("Temp folder %s not writable - unable to apply theme!" % tmp_folder)
152+ redirect(URL(r=request, args=request.args))
153+ if not os.access(out_file, os.W_OK):
154+ session.error = T("CSS file %s not writable - unable to apply theme!" % out_file)
155+ redirect(URL(r=request, args=request.args))
156+ if not os.access(out_file2, os.W_OK):
157+ session.error = T("CSS file %s not writable - unable to apply theme!" % out_file2)
158+ redirect(URL(r=request, args=request.args))
159+ # Read in Template
160+ inpfile = open(template, "r")
161+ lines = inpfile.readlines()
162+ inpfile.close()
163+ # Read settings from Database
164+ theme = db(db.admin_theme.id == form.vars.theme).select(limitby=(0, 1)).first()
165+ default_theme = db(db.admin_theme.id == 1).select(limitby=(0, 1)).first()
166+ #if theme.logo:
167+ # logo = theme.logo
168+ #else:
169+ # logo = default_theme.logo
170+ #if theme.header_background:
171+ # header_background = theme.header_background
172+ #else:
173+ # header_background = default_theme.header_background
174+ # Write out CSS
175+ ofile = open(out_file, "w")
176+ for line in lines:
177+ #line = line.replace("YOURLOGOHERE", logo)
178+ #line = line.replace("HEADERBACKGROUND", header_background )
179+ # Iterate through Colours
180+ for key in theme.keys():
181+ if key[:4] == "col_":
182+ if theme[key]:
183+ line = line.replace(key, theme[key])
184+ else:
185+ line = line.replace(key, default_theme[key])
186+ ofile.write(line)
187+ ofile.close()
188+
189+ # Minify
190+ from subprocess import PIPE, check_call
191+ currentdir = os.getcwd()
192+ os.chdir(os.path.join(currentdir, request.folder, "static", "scripts", "tools"))
193+ import sys
194+ # If started as a Windows service, os.sys.executable is no longer python
195+ if ("win" in sys.platform):
196+ pythonpath = os.path.join(sys.prefix, "python.exe")
197+ else:
198+ pythonpath = os.sys.executable
199+ try:
200+ proc = check_call([pythonpath, "build.sahana.py", "CSS", "NOGIS"], stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=False)
201+ except:
202+ session.error = T("Error encountered while applying the theme.")
203+ redirect(URL(r=request, args=request.args))
204+ os.chdir(currentdir)
205+
206+ # Don't do standard redirect to List view as we only want this option available
207+ redirect(URL(r=request, args=[1, "update"]))
208+ else:
209+ session.error = INVALIDREQUEST
210+ redirect(URL(r=request))
211+
212+
213+# -----------------------------------------------------------------------------
214+def theme_check(form):
215+ "Check the Theme has valid files available. Deprecated"
216+ # Check which form we're called by
217+ if form.vars.theme:
218+ # Called from Settings
219+ theme = db(db.admin_theme.id == form.vars.theme).select(db.admin_theme.logo, limitby=(0, 1)).first()
220+ logo = theme.logo
221+ #header_background = theme.header_background
222+ #footer = theme.footer
223+ #elif form.vars.logo and form.vars.footer:
224+ elif form.vars.logo:
225+ # Called from Theme
226+ logo = form.vars.logo
227+ #header_background = form.vars.header_background
228+ #footer = form.vars.footer
229+ else:
230+ session.error = INVALIDREQUEST
231+ redirect(URL(r=request))
232+
233+ _logo = os.path.join(request.folder, "static", logo)
234+ #_header_background = os.path.join(request.folder, "static", header_background)
235+ #_footer = os.path.join(request.folder, "views", footer)
236+ if not os.access(_logo, os.R_OK):
237+ form.errors["logo"] = T("Logo file %s missing!" % logo)
238+ return
239+ #if not os.access(_header_background, os.R_OK):
240+ # form.errors["header_background"] = T("Header background file %s missing!" % logo)
241+ # return
242+ #if not os.access(_footer, os.R_OK):
243+ # form.errors["footer"] = T("Footer file %s missing!" % footer)
244+ # return
245+ # Validation passed
246+ return
247+
248+
249+# -----------------------------------------------------------------------------
250+@auth.s3_requires_membership(1)
251+def user():
252+ """ RESTful CRUD controller """
253+ module = "auth"
254+ resource = "user"
255+ tablename = module + "_" + resource
256+ table = db[tablename]
257+
258+ # Model options
259+ role_manager = s3base.S3RoleManager()
260+ s3xrc.model.set_method(module, resource, method="roles", action=role_manager)
261+
262+ # CRUD Strings
263+ ADD_USER = T("Add User")
264+ LIST_USERS = T("List Users")
265+ s3.crud_strings[tablename] = Storage(
266+ title_create = ADD_USER,
267+ title_display = T("User Details"),
268+ title_list = LIST_USERS,
269+ title_update = T("Edit User"),
270+ title_search = T("Search Users"),
271+ subtitle_create = T("Add New User"),
272+ subtitle_list = T("Users"),
273+ label_list_button = LIST_USERS,
274+ label_create_button = ADD_USER,
275+ label_delete_button = T("Delete User"),
276+ msg_record_created = T("User added"),
277+ msg_record_modified = T("User updated"),
278+ msg_record_deleted = T("User deleted"),
279+ msg_list_empty = T("No Users currently registered"))
280+
281+ # Allow the ability for admin to Disable logins
282+ db.auth_user.registration_key.writable = True
283+ db.auth_user.registration_key.readable = True
284+ db.auth_user.registration_key.label = T("Disabled?")
285+
286+ # In Controller to allow registration to work with UUIDs - only manual edits need this setting
287+ db.auth_user.registration_key.requires = IS_NULL_OR(IS_IN_SET(["disabled", "pending"]))
288+
289+ # Pre-processor
290+ def user_prep(jr):
291+ if jr.method == "delete" and jr.http=="GET":
292+ if jr.id == jr.session.auth.user.id: # we're trying to delete ourself
293+ request.get_vars.update({"user.id":str(jr.id)})
294+ jr.id = None
295+ s3xrc.model.configure(table,
296+ delete_next = URL(r=request, c="default", f="user/logout"))
297+ s3.crud.confirm_delete = T("You are attempting to delete your own account - are you sure you want to proceed?")
298+
299+ elif jr.method == "update":
300+ # Send an email to user if their account is approved
301+ # (=moved from 'pending' to 'blank'(i.e. enabled))
302+ s3xrc.model.configure(table,
303+ onvalidation = lambda form: user_approve(form))
304+ return True
305+ response.s3.prep = user_prep
306+
307+ s3xrc.model.configure(table,
308+ main="first_name",
309+ # Add users to Person Registry & 'Authenticated' role:
310+ create_onaccept = lambda form: auth.s3_register(form),
311+ create_onvalidation = lambda form: user_create_onvalidation(form))
312+ output = s3_rest_controller(module, resource)
313+
314+ if response.s3.actions:
315+ response.s3.actions.insert(1,
316+ dict(label=str(T("Roles")), _class="action-btn",
317+ url=str(URL(r=request, c="admin", f="user", args=["[id]", "roles"]))))
318+ return output
319+
320+
321+# -----------------------------------------------------------------------------
322+def user_create_onvalidation (form):
323+ if (form.request_vars.has_key("password_two") and \
324+ form.request_vars.password != form.request_vars.password_two):
325+ form.errors.password = T("Password fields don't match")
326+ return True
327+
328+
329+# -----------------------------------------------------------------------------
330+def user_approve(form):
331+ "Send an email to user if their account is approved (moved from 'pending' to 'blank'(i.e. enabled))"
332+ if form.vars.registration_key:
333+ # Now non-blank
334+ return
335+ else:
336+ # Now blank - lookup old value
337+ status = db(db.auth_user.id == request.vars.id).select(db.auth_user.registration_key, limitby=(0, 1)).first().registration_key
338+ if status == "pending":
339+ # Send email to user confirming that they are now able to login
340+ if not auth.settings.mailer or \
341+ not auth.settings.mailer.send(to=form.vars.email,
342+ subject=s3.messages.confirmation_email_subject,
343+ message=s3.messages.confirmation_email):
344+ session.warning = auth.messages.unable_send_email
345+ return
346+ else:
347+ return
348+
349+
350+# -----------------------------------------------------------------------------
351+@auth.s3_requires_membership(1)
352+def usergroup():
353+ """
354+ User update form with groups
355+ - NB This is currently unused & has no custom view
356+ """
357+ user = request.vars.user
358+
359+ # redirect to the user list if user id is not given
360+ if user is None:
361+ redirect(URL(r=request, f="user"))
362+ return
363+
364+ # gather common variables
365+ data = {}
366+ data["user_id"] = user
367+ data["username"] = db.auth_user[user].first_name + " " + \
368+ db.auth_user[user].last_name
369+ data["role"] = db.auth_group[user].role
370+
371+ # display the standard user details
372+ record = db(db.auth_user.id == user).select().first()
373+ db.auth_user.id.readable = False
374+
375+ # Let admin view and modify the registration key
376+ db.auth_user.registration_key.writable = True
377+ db.auth_user.registration_key.readable = True
378+ db.auth_user.registration_key.label = T("Disabled?")
379+ db.auth_user.registration_key.requires = IS_NULL_OR(IS_IN_SET(["disabled", "pending"]))
380+
381+ form = SQLFORM(db.auth_user, record, deletable=True)
382+
383+ # find all groups user belongs to
384+ query = (db.auth_membership.user_id == user)
385+ allgroups = db().select(db.auth_group.ALL)
386+ user_membership = db(query).select(db.auth_membership.ALL)
387+
388+ # db.auth_group[row.group_id].role
389+ #records = SQLTABLE(db(query).select(db.auth_membership.ALL))
390+
391+ # handle the M to M of user to group membership for display
392+ records = []
393+ for group in allgroups:
394+
395+ user_group_count = 0
396+
397+ for row in user_membership:
398+
399+ if (row.group_id == group.id):
400+ records.append([group.role, "on", group.id])
401+ user_group_count += 1
402+
403+ if (user_group_count == 0):
404+ # if the group does not exist currently and is enabled
405+ #if request.has_key(group.id):
406+ if (group.id == 6):
407+ db.auth_membership.insert(user_id = user, group_id = group.id)
408+ records.append([group.role, "on", group.id])
409+ data["heehe"] = "yes %d" % group.id
410+
411+ records.append([group.role, "", group.id])
412+
413+ # Update records for user details
414+ if form.accepts(request.vars): \
415+ response.flash="User " + data["username"] + " Updated"
416+ elif form.errors: \
417+ response.flash="There were errors in the form"
418+
419+ # Update records for group membership details
420+ for key in request.vars.keys():
421+ data["m_" + key] = request.vars[key]
422+
423+ return dict(data=data, records=records, form=form)
424+
425+
426+# -----------------------------------------------------------------------------
427+@auth.s3_requires_membership(1)
428+def group():
429+
430+ """ RESTful CRUD controller """
431+
432+ prefix = "auth"
433+ resourcename = "group"
434+ tablename = "%s_%s" % (prefix, resourcename)
435+ table = db[tablename]
436+
437+ # Model options
438+
439+ # CRUD Strings
440+ ADD_ROLE = T("Add Role")
441+ LIST_ROLES = T("List Roles")
442+ s3.crud_strings[tablename] = Storage(
443+ title_create = ADD_ROLE,
444+ title_display = T("Role Details"),
445+ title_list = LIST_ROLES,
446+ title_update = T("Edit Role"),
447+ title_search = T("Search Roles"),
448+ subtitle_create = T("Add New Role"),
449+ subtitle_list = T("Roles"),
450+ label_list_button = LIST_ROLES,
451+ label_create_button = ADD_ROLE,
452+ msg_record_created = T("Role added"),
453+ msg_record_modified = T("Role updated"),
454+ msg_record_deleted = T("Role deleted"),
455+ msg_list_empty = T("No Roles currently defined"))
456+
457+ s3xrc.model.configure(table, main="role")
458+ return s3_rest_controller(prefix, resourcename)
459+
460+
461+# -----------------------------------------------------------------------------
462+@auth.s3_requires_membership(1)
463+def membership():
464+
465+ """ RESTful CRUD controller """
466+
467+ prefix = "auth"
468+ resourcename = "membership"
469+ tablename = prefix + "_" + resourcename
470+ table = db[tablename]
471+
472+ # Model options
473+ db.auth_membership.group_id.represent = shn_role_represent
474+ db.auth_membership.user_id.represent = shn_user_represent
475+
476+ # CRUD Strings
477+ ADD_MEMBERSHIP = T("Add Membership")
478+ LIST_MEMBERSHIPS = T("List Memberships")
479+ s3.crud_strings[tablename] = Storage(
480+ title_create = ADD_MEMBERSHIP,
481+ title_display = T("Membership Details"),
482+ title_list = LIST_MEMBERSHIPS,
483+ title_update = T("Edit Membership"),
484+ title_search = T("Search Memberships"),
485+ subtitle_create = T("Add New Membership"),
486+ subtitle_list = T("Memberships"),
487+ label_list_button = LIST_MEMBERSHIPS,
488+ label_create_button = ADD_MEMBERSHIP,
489+ msg_record_created = T("Membership added"),
490+ msg_record_modified = T("Membership updated"),
491+ msg_record_deleted = T("Membership deleted"),
492+ msg_list_empty = T("No Memberships currently defined"))
493+
494+ s3xrc.model.configure(table, main="user_id")
495+ return s3_rest_controller(prefix, resourcename)
496+
497+
498+# -----------------------------------------------------------------------------
499+@auth.s3_requires_membership(1)
500+def users():
501+ """
502+ List/amend which users are in a Group
503+
504+ @deprecated
505+
506+ """
507+
508+ try:
509+ group = int(request.args(0))
510+ except TypeError, ValueError:
511+ session.error = T("Need to specify a role!")
512+ redirect(URL(r=request, f="group"))
513+
514+ table = db.auth_membership
515+ query = table.group_id == group
516+ title = T("Role") + ": " + db.auth_group[group].role
517+ description = db.auth_group[group].description
518+ # Start building the Return
519+ output = dict(title=title, description=description, group=group)
520+
521+ if auth.settings.username:
522+ username = "username"
523+ else:
524+ username = "email"
525+
526+ # Audit
527+ crud.settings.create_onaccept = lambda form: s3_audit("create", module, "membership",
528+ form=form,
529+ representation="html")
530+ crud.settings.create_onvalidation = lambda form: group_dupes(form, "users", [group])
531+ # Many<>Many selection (Deletable, no Quantity)
532+ item_list = []
533+ sqlrows = db(query).select()
534+ even = True
535+ for row in sqlrows:
536+ if even:
537+ theclass = "even"
538+ even = False
539+ else:
540+ theclass = "odd"
541+ even = True
542+ id = row.user_id
543+ _user = db.auth_user[id]
544+ item_first = _user.first_name
545+ item_second = _user.last_name
546+ item_description = _user[username]
547+ id_link = A(id, _href=URL(r=request, f="user", args=[id, "read"]))
548+ checkbox = INPUT(_type="checkbox", _value="on", _name=id, _class="remove_item")
549+ item_list.append(TR(TD(id_link), TD(item_first), TD(item_second), TD(item_description), TD(checkbox), _class=theclass))
550+
551+ if auth.settings.username:
552+ username_label = T("Username")
553+ else:
554+ username_label = T("Email")
555+ table_header = THEAD(TR(TH("ID"), TH(T("First Name")), TH(T("Last Name")), TH(username_label), TH(T("Remove"))))
556+ table_footer = TFOOT(TR(TD(_colspan=4), TD(INPUT(_id="submit_delete_button", _type="submit", _value=T("Remove")))))
557+ items = DIV(FORM(
558+ TABLE(table_header,
559+ TBODY(item_list),
560+ table_footer, _id="list", _class="display"), _name="custom", _method="post", _enctype="multipart/form-data", _action=URL(r=request, f="group_remove_users", args=[group])))
561+
562+ subtitle = T("Users")
563+ crud.messages.submit_button = T("Add")
564+ crud.messages.record_created = T("Role Updated")
565+ form = crud.create(table, next=URL(r=request, args=[group]))
566+ addtitle = T("Add New User to Role")
567+ output.update(dict(subtitle=subtitle, items=items, addtitle=addtitle, form=form))
568+ return output
569+
570+
571+# -----------------------------------------------------------------------------
572+def group_dupes(form, page, arg):
573+ """
574+ Onvalidation check for duplicate user roles
575+
576+ @deprecated
577+
578+ """
579+
580+ user = form.latest["user_id"]
581+ group = form.latest["group_id"]
582+ query = (form.table.user_id == user) & (form.table.group_id == group)
583+ items = db(query).select()
584+ if items:
585+ session.error = T("User already has this role")
586+ redirect(URL(r=request, f=page, args=arg))
587+
588+
589+# -----------------------------------------------------------------------------
590+@auth.s3_requires_membership(1)
591+def group_remove_users():
592+ """
593+ Remove users from a group
594+ """
595+ if len(request.args) == 0:
596+ session.error = T("Need to specify a group!")
597+ redirect(URL(r=request, f="group"))
598+ group = request.args(0)
599+ table = db.auth_membership
600+ for var in request.vars:
601+ if str(var).isdigit():
602+ user = var
603+ query = (table.group_id == group) & (table.user_id == user)
604+ db(query).delete()
605+ # Audit
606+ #crud.settings.update_onaccept = lambda form: shn_audit_update(form, "membership", "html")
607+ session.flash = T("Users removed")
608+ redirect(URL(r=request, f="users", args=[group]))
609+
610+
611+# -----------------------------------------------------------------------------
612+@auth.s3_requires_membership(1)
613+def groups():
614+ """
615+ List/amend which groups a User is in
616+ """
617+
618+ try:
619+ user = int(request.args(0))
620+ except TypeError, ValueError:
621+ session.error = T("Need to specify a user!")
622+ redirect(URL(r=request, f="user"))
623+
624+ table = db.auth_membership
625+ query = table.user_id == user
626+ title = db.auth_user[user].first_name + " " + db.auth_user[user].last_name
627+ description = db.auth_user[user].email
628+ # Start building the Return
629+ output = dict(title=title, description=description, user=user)
630+
631+ # Audit
632+ crud.settings.create_onaccept = lambda form: s3_audit("create", module, "membership",
633+ form=form,
634+ representation="html")
635+
636+
637+ crud.settings.create_onvalidation = lambda form: group_dupes(form, "groups", [user])
638+ # Many<>Many selection (Deletable, no Quantity)
639+ item_list = []
640+ sqlrows = db(query).select()
641+ even = True
642+ for row in sqlrows:
643+ if even:
644+ theclass = "even"
645+ even = False
646+ else:
647+ theclass = "odd"
648+ even = True
649+ id = row.group_id
650+ _group = db.auth_group[id]
651+ item_first = _group.role
652+ item_description = _group.description
653+ id_link = A(id, _href=URL(r=request, f="group", args=[id, "read"]))
654+ checkbox = INPUT(_type="checkbox", _value="on", _name=id, _class="remove_item")
655+ item_list.append(TR(TD(id_link), TD(item_first), TD(item_description), TD(checkbox), _class=theclass))
656+
657+ table_header = THEAD(TR(TH("ID"), TH(T("Role")), TH(T("Description")), TH(T("Remove"))))
658+ table_footer = TFOOT(TR(TD(_colspan=3), TD(INPUT(_id="submit_delete_button", _type="submit", _value=T("Remove")))))
659+ items = DIV(FORM(TABLE(table_header, TBODY(item_list), table_footer, _id="table-container"), _name="custom", _method="post", _enctype="multipart/form-data", _action=URL(r=request, f="user_remove_groups", args=[user])))
660+
661+ subtitle = T("Roles")
662+ crud.messages.submit_button = T("Add")
663+ crud.messages.record_created = T("User Updated")
664+ form = crud.create(table, next=URL(r=request, args=[user]))
665+ addtitle = T("Add New Role to User")
666+ output.update(dict(subtitle=subtitle, items=items, addtitle=addtitle, form=form))
667+ return output
668+
669+
670+# -----------------------------------------------------------------------------
671+@auth.s3_requires_membership(1)
672+def user_remove_groups():
673+ """ Remove groups from a user """
674+ if len(request.args) == 0:
675+ session.error = T("Need to specify a user!")
676+ redirect(URL(r=request, f="user"))
677+ user = request.args(0)
678+ table = db.auth_membership
679+ for var in request.vars:
680+ if str(var).isdigit():
681+ group = var
682+ query = (table.group_id == group) & (table.user_id == user)
683+ db(query).delete()
684+ # Audit
685+ #crud.settings.update_onaccept = lambda form: shn_audit_update(form, "membership", "html")
686+ session.flash = T("Groups removed")
687+ redirect(URL(r=request, f="groups", args=[user]))
688+
689+
690+# -----------------------------------------------------------------------------
691+@auth.s3_requires_membership(1)
692+def import_data():
693+ """
694+ Import data via POST upload to CRUD controller. Old - being replaced by Sync/Importer.
695+ """
696+ title = T("Import Data")
697+ crud.messages.submit_button = "Upload"
698+
699+ # Deprecated
700+ import_job_form = crud.create(db.admin_import_job)
701+ # Tell the CRUD create form to post to a different location
702+ import_job_form.custom.begin.text = str(import_job_form.custom.begin).replace(
703+ 'action=""',
704+ 'action="%s"' % URL(r=request, f="import_job", args=["create"]))
705+
706+ return dict(title=title,
707+ import_job_form=import_job_form)
708+
709+
710+# -----------------------------------------------------------------------------
711+@auth.s3_requires_membership(1)
712+def import_csv_data():
713+ """
714+ Import CSV data via POST upload to Database.
715+ """
716+ file = request.vars.multifile.file
717+ try:
718+ # Assumes that it is a concatenation of tables
719+ import_csv(file)
720+ session.flash = T("Data uploaded")
721+ except Exception, e:
722+ session.error = T("Unable to parse CSV file!")
723+ redirect(URL(r=request, f="import_data"))
724+
725+
726+# -----------------------------------------------------------------------------
727+@auth.requires_login()
728+def export_data():
729+ """
730+ Export data via CRUD controller. Old - being replaced by Sync.
731+ """
732+ title = T("Export Data")
733+ return dict(title=title)
734+
735+
736+# -----------------------------------------------------------------------------
737+@auth.s3_requires_membership(1)
738+def export_csv():
739+ """
740+ Export entire database as CSV. Old - being replaced by Sync.
741+ """
742+ import StringIO
743+ output = StringIO.StringIO()
744+
745+ db.export_to_csv_file(output)
746+
747+ output.seek(0)
748+ import gluon.contenttype
749+ response.headers["Content-Type"] = gluon.contenttype.contenttype(".csv")
750+ filename = "%s_database.csv" % (request.env.server_name)
751+ response.headers["Content-disposition"] = "attachment; filename=%s" % filename
752+ return output.read()
753+
754+
755+# -----------------------------------------------------------------------------
756+# Unstructured Data Import
757+# Deprecated - being replaced by Importer
758+@auth.s3_requires_membership(1)
759+def import_job():
760+ "RESTful CRUD controller to handle 'jobs' for importing unstructured data."
761+ # CRUD Strings
762+ module = "admin"
763+ resource = "import_job"
764+ table = "%s_%s" % (module, resource)
765+ # This breaks!
766+ jr = s3xrc.request(module, resource, request, session=session)
767+ CREATE_NEW_IMPORT_JOB = T("Create New Import Job")
768+ LIST_IMPORT_JOBS = ("List Import Jobs")
769+ s3.crud_strings[table] = Storage(
770+ title_create=CREATE_NEW_IMPORT_JOB,
771+ title_display=T("Import Job"),
772+ title_list=LIST_IMPORT_JOBS,
773+ title_update=T("Update Import Job"),
774+ subtitle_create=CREATE_NEW_IMPORT_JOB,
775+ subtitle_list=T("Import Jobs"),
776+ label_list_button=LIST_IMPORT_JOBS,
777+ label_create_button=T("Create Import Job"),
778+ msg_record_created=T("Import job created"),
779+ msg_list_empty=T("No import jobs")
780+ )
781+
782+ if len(request.args) == 0:
783+ return _import_job_list(jr)
784+ action = request.args(0)
785+ if action == "create":
786+ return _import_job_create(jr)
787+ if action == "update":
788+ return _import_job_update(jr)
789+
790+
791+# -----------------------------------------------------------------------------
792+def _import_job_list(jr):
793+ return shn_list(jr, listadd=False)
794+
795+
796+# -----------------------------------------------------------------------------
797+def _import_job_create(jr):
798+ if jr.http != "POST":
799+ redirect(jr.there())
800+
801+ def process_new_file_and_redirect(form):
802+ filename = form.vars.source_file_newfilename
803+ filepath = os.path.join(request.folder, "uploads", filename)
804+ query = (jr.table.id == form.vars.id)
805+ column_map = []
806+ model_fields = dict(map(
807+ lambda x:(x.lower(), x),
808+ get_matchable_fields(form.vars.module, form.vars.resource)))
809+ try:
810+ reader = csv.reader(open(filepath, "r"))
811+ for line in reader:
812+ for col in line:
813+ field = None
814+ col_match = col.lower()
815+ if col_match in model_fields:
816+ # Explicit name match.
817+ field = model_fields.pop(col_match)
818+ if not field:
819+ # Partial name patch.
820+ for field_name in model_fields:
821+ if col_match in field_name or field_name in col_match:
822+ field = model_fields.pop(field_name)
823+ break
824+ column_map.append((col, field))
825+ break
826+ pickled_map = pickle.dumps(column_map, pickle.HIGHEST_PROTOCOL)
827+ db(query).update(column_map=pickled_map)
828+ except:
829+ db(query).update(status="failed")
830+ redirect(URL(r=request, f="import_job", args=[form.vars.id, "update"]))
831+
832+ form = crud.create(jr.table, onaccept=process_new_file_and_redirect)
833+ response.flash = "Form errors!"
834+ redirect(URL(r=request, f="import_data"))
835+
836+
837+# -----------------------------------------------------------------------------
838+def _import_job_update(jr):
839+ if len(request.args) < 2:
840+ redirect(jr.there())
841+ id = request.args[1]
842+ query = (jr.table.id == id)
843+ job = db(query).select()
844+ if not job:
845+ raise HTTP(404, body=s3xrc.xml.json_message(False, 404, session.error))
846+ job = job[0]
847+
848+ if jr.http == "GET":
849+ output = _import_job_update_GET(jr, job)
850+ elif jr.http == "POST":
851+ output = _import_job_update_POST(jr, job)
852+ else:
853+ raise HTTP(400, body=INVALIDREQUEST)
854+
855+ title = "%s - %s" % (T("Input Job"), job.description)
856+ output.update(dict(title=title, job=job))
857+ response.view = "admin/import_job_update.html"
858+ return output
859+
860+
861+# -----------------------------------------------------------------------------
862+def _import_job_update_GET(jr, job):
863+ table = db.admin_import_line
864+ query = (table.import_job == job.id)
865+
866+ if job.status == "new":
867+ try:
868+ job.column_map = pickle.loads(job.column_map)
869+ except pickle.UnpicklingError:
870+ job.column_map = []
871+ model_fields = get_matchable_fields(job.module, job.resource)
872+ return dict(model_fields=model_fields)
873+
874+ if job.status == "processing":
875+ num_lines = db(query).count()
876+ return dict(num_lines=num_lines, update_speed=60)
877+
878+ if job.status in ["processed", "failed", "imported"]:
879+ def _include_field(f):
880+ if f in ["import_job"]:
881+ return False
882+ return table[f].readable
883+
884+ fields = [table[f] for f in table.fields if _include_field(f)]
885+ headers = dict(map(lambda f: (str(f), f.label), fields))
886+ items = crud.select(
887+ db["admin_import_line"],
888+ query=query,
889+ fields=fields,
890+ headers=headers,
891+ truncate=48, _id="list", _class="display")
892+ response.extra_styles = ["admin/import_job.css"]
893+ return dict(items=items)
894+
895+ if job.status == "import":
896+ query = (table.import_job == job.id) & (table.status == "imported")
897+ num_lines = db(query).count()
898+ return dict(num_lines=num_lines, update_speed=60)
899+
900+ return {}
901+
902+
903+# -----------------------------------------------------------------------------
904+def _import_job_update_POST(jr, job):
905+ if job.status == "new":
906+ # Update column map.
907+ try:
908+ column_map = pickle.loads(job.column_map)
909+ except pickle.UnpicklingError:
910+ column_map = []
911+ for key, value in request.vars.iteritems():
912+ if not key.startswith("column_map_"):
913+ continue
914+ try:
915+ idx = int(key.split("_")[-1])
916+ except ValueError:
917+ continue
918+ if value != "None (Ignore)":
919+ column_map[idx] = (column_map[idx][0], value)
920+ else:
921+ column_map[idx] = (column_map[idx][0], None)
922+ jr.table[job.id] = dict(
923+ column_map=pickle.dumps(column_map, pickle.HIGHEST_PROTOCOL),
924+ status="processing")
925+ job.status = "processing"
926+
927+ if job.status == "processed":
928+ query = db.admin_import_line.id
929+ for var, status in request.vars.iteritems():
930+ if not var.startswith("status_"):
931+ continue
932+ try:
933+ import_line_id = int(var.split("_")[-1])
934+ except ValueError:
935+ continue
936+ db(db.admin_import_line.id == import_line_id).update(status=status)
937+ jr.table[job.id] = dict(status="import")
938+ job.status = "import"
939+
940+ return _import_job_update_GET(jr, job)
941+
942+
943+# -----------------------------------------------------------------------------
944+def get_matchable_fields(module, resource):
945+ model_fields = getattr(db, "%s_%s" % (module, resource)).fields
946+ for name in ["created_on", "modified_on", "id", "uuid", "deleted"]:
947+ model_fields.remove(name)
948+ model_fields.insert(0, "None (Ignore)")
949+ return model_fields
950+
951+
952+
953+# -----------------------------------------------------------------------------
954+# Functional Testing
955+# Deprecated: Use static/selenium/scripts/regressionTests.py with it's Tk UI
956+def handleResults():
957+ """
958+ Process the POST data returned from Selenium TestRunner.
959+ The data is written out to 2 files. The overall results are written to
960+ date-time-browserName-metadata.txt as a list of key: value, one per line. The
961+ suiteTable and testTables are written to date-time-browserName-results.html.
962+ """
963+
964+ if not request.vars.result:
965+ # No results
966+ return
967+
968+ # Read in results
969+ result = request.vars.result
970+ totalTime = request.vars.totalTime
971+ numberOfSuccesses = request.vars.numTestPasses
972+ numberOfFailures = request.vars.numTestFailures
973+ numberOfCommandSuccesses = request.vars.numCommandPasses
974+ numberOfCommandFailures = request.vars.numCommandFailures
975+ numberOfCommandErrors = request.vars.numCommandErrors
976+
977+ suiteTable = ""
978+ if request.vars.suite:
979+ suiteTable = request.vars.suite
980+
981+ testTables = []
982+ testTableNum = 1
983+ while request.vars["testTable.%s" % testTableNum]:
984+ testTable = request.vars["testTable.%s" % testTableNum]
985+ testTables.append(testTable)
986+ testTableNum += 1
987+ try:
988+ request.vars["testTable.%s" % testTableNum]
989+ pass
990+ except:
991+ break
992+
993+ # Unescape the HTML tables
994+ import urllib
995+ suiteTable = urllib.unquote(suiteTable)
996+ testTables = map(urllib.unquote, testTables)
997+
998+ # We want to store results separately for each browser
999+ browserName = getBrowserName(request.env.http_user_agent)
1000+ date = str(request.utcnow)[:-16]
1001+ time = str(request.utcnow)[11:-10]
1002+ time = time.replace(":", "-")
1003+
1004+ # Write out results
1005+ outputDir = os.path.join(request.folder, "static", "selenium", "results")
1006+ metadataFile = "%s-%s-%s-metadata.txt" % (date, time, browserName)
1007+ dataFile = "%s-%s-%s-results.html" % (date, time, browserName)
1008+
1009+ #xmlText = '<selenium result="' + result + '" totalTime="' + totalTime + '" successes="' + numberOfCommandSuccesses + '" failures="' + numberOfCommandFailures + '" errors="' + numberOfCommandErrors + '" />'
1010+ f = open(os.path.join(outputDir, metadataFile), "w")
1011+ for key in request.vars.keys():
1012+ if "testTable" in key or key in ["log", "suite"]:
1013+ pass
1014+ else:
1015+ print >> f, "%s: %s" % (key, request.vars[key])
1016+ f.close()
1017+
1018+ f = open(os.path.join(outputDir, dataFile), "w")
1019+ print >> f, suiteTable
1020+ for testTable in testTables:
1021+ print >> f, "<br/><br/>"
1022+ print >> f, testTable
1023+ f.close()
1024+
1025+ message = DIV(P("Results have been successfully posted to the server here:"),
1026+ P(A(metadataFile, _href=URL(r=request, c="static", f="selenium", args=["results", metadataFile]))),
1027+ P(A(dataFile, _href=URL(r=request, c="static", f="selenium", args=["results", dataFile]))))
1028+
1029+ response.view = "display.html"
1030+ title = T("Test Results")
1031+ return dict(title=title, item=message)
1032+
1033+
1034+# -----------------------------------------------------------------------------
1035+# Ticket Viewer functions Borrowed from admin application of web2py
1036+@auth.s3_requires_membership(1)
1037+def errors():
1038+ """ Error handler """
1039+
1040+ app = request.application
1041+
1042+ for item in request.vars:
1043+ if item[:7] == "delete_":
1044+ os.unlink(apath("%s/errors/%s" % (app, item[7:]), r=request))
1045+
1046+ func = lambda p: os.stat(apath("%s/errors/%s" % (app, p), r=request)).st_mtime
1047+ tickets = sorted(listdir(apath("%s/errors/" % app, r=request), "^\w.*"),
1048+ key=func,
1049+ reverse=True)
1050+
1051+ return dict(app=app, tickets=tickets)
1052+
1053+
1054+# -----------------------------------------------------------------------------
1055+def make_link(path):
1056+ """ Create a link from a path """
1057+ tryFile = path.replace("\\", "/")
1058+
1059+ if os.path.isabs(tryFile) and os.path.isfile(tryFile):
1060+ (folder, filename) = os.path.split(tryFile)
1061+ (base, ext) = os.path.splitext(filename)
1062+ app = request.args[0]
1063+
1064+ editable = {"controllers": ".py", "models": ".py", "views": ".html"}
1065+ for key in editable.keys():
1066+ check_extension = folder.endswith("%s/%s" % (app, key))
1067+ if ext.lower() == editable[key] and check_extension:
1068+ return A('"' + tryFile + '"',
1069+ _href=URL(r=request,
1070+ f="edit/%s/%s/%s" % (app, key, filename))).xml()
1071+ return ""
1072+
1073+
1074+# -----------------------------------------------------------------------------
1075+def make_links(traceback):
1076+ """ Make links using the given traceback """
1077+
1078+ lwords = traceback.split('"')
1079+
1080+ # Make the short circuit compatible with <= python2.4
1081+ result = (len(lwords) != 0) and lwords[0] or ""
1082+
1083+ i = 1
1084+
1085+ while i < len(lwords):
1086+ link = make_link(lwords[i])
1087+
1088+ if link == "":
1089+ result += '"' + lwords[i]
1090+ else:
1091+ result += link
1092+
1093+ if i + 1 < len(lwords):
1094+ result += lwords[i + 1]
1095+ i = i + 1
1096+
1097+ i = i + 1
1098+
1099+ return result
1100+
1101+
1102+# -----------------------------------------------------------------------------
1103+class TRACEBACK(object):
1104+ """ Generate the traceback """
1105+
1106+ def __init__(self, text):
1107+ """ TRACEBACK constructor """
1108+
1109+ self.s = make_links(CODE(text).xml())
1110+
1111+ def xml(self):
1112+ """ Returns the xml """
1113+
1114+ return self.s
1115+
1116+
1117+# -----------------------------------------------------------------------------
1118+# Ticket viewing
1119+@auth.s3_requires_membership(1)
1120+def ticket():
1121+ """ Ticket handler """
1122+
1123+ if len(request.args) != 2:
1124+ session.flash = T("Invalid ticket")
1125+ redirect(URL(r=request))
1126+
1127+ app = request.args[0]
1128+ ticket = request.args[1]
1129+ e = RestrictedError()
1130+ e.load(request, app, ticket)
1131+
1132+ return dict(app=app,
1133+ ticket=ticket,
1134+ traceback=TRACEBACK(e.traceback),
1135+ code=e.code,
1136+ layer=e.layer)
1137+
1138+
1139+# -----------------------------------------------------------------------------
1140+@auth.s3_requires_membership(1)
1141+def role():
1142+ """
1143+ Role Manager
1144+
1145+ @author: Dominic König <dominic@aidiq.com>
1146+
1147+ """
1148+
1149+ prefix = "auth"
1150+ name = "group"
1151+
1152+ # ACLs as component of roles
1153+ s3xrc.model.add_component("s3", "permission",
1154+ joinby = dict(auth_group="group_id"),
1155+ multiple=True)
1156+
1157+ def prep(r):
1158+ if r.representation not in ("html",):
1159+ return False
1160+
1161+ handler = s3base.S3RoleManager()
1162+ modules = deployment_settings.modules
1163+ handler.controllers = Storage([(m, modules[m]) for m in modules
1164+ if modules[m].restricted])
1165+
1166+ # Configure REST methods
1167+ resource = r.resource
1168+ resource.add_method("users", handler)
1169+ resource.set_handler("read", handler)
1170+ resource.set_handler("list", handler)
1171+ resource.set_handler("copy", handler)
1172+ resource.set_handler("create", handler)
1173+ resource.set_handler("update", handler)
1174+ resource.set_handler("delete", handler)
1175+ return True
1176+ response.s3.prep = prep
1177+
1178+ response.s3.no_sspag = True
1179+ response.extra_styles = ["S3/role.css"]
1180+
1181+ output = s3_rest_controller(prefix, name)
1182+ return output
1183+
1184+
1185+# -----------------------------------------------------------------------------
1186+@auth.s3_requires_membership(1)
1187+def acl():
1188+ """
1189+ Preliminary controller for ACLs
1190+ for testing purposes, not for production use!
1191+
1192+ """
1193+
1194+ prefix = "s3"
1195+ name = "permission"
1196+
1197+ table = auth.permission.table
1198+ table.group_id.requires = IS_ONE_OF(db, "auth_group.id", "%(role)s")
1199+ table.group_id.represent = lambda opt: opt and db.auth_group[opt].role or opt
1200+
1201+ table.controller.requires = IS_EMPTY_OR(IS_IN_SET(auth.permission.modules.keys(), zero="ANY"))
1202+ table.controller.represent = lambda opt: opt and "%s (%s)" % (opt, auth.permission.modules.get(opt, {}).get("name_nice", opt)) or "ANY"
1203+
1204+ table.function.represent = lambda val: val and val or T("ANY")
1205+
1206+ table.tablename.requires = IS_EMPTY_OR(IS_IN_SET([t._tablename for t in db], zero=T("ANY")))
1207+ table.tablename.represent = lambda val: val and val or T("ANY")
1208+
1209+ table.uacl.label = T("All Resources")
1210+ table.uacl.widget = S3ACLWidget.widget
1211+ table.uacl.requires = IS_ACL(auth.permission.PERMISSION_OPTS)
1212+ table.uacl.represent = lambda val: acl_represent(val, auth.permission.PERMISSION_OPTS)
1213+
1214+ table.oacl.label = T("Owned Resources")
1215+ table.oacl.widget = S3ACLWidget.widget
1216+ table.oacl.requires = IS_ACL(auth.permission.PERMISSION_OPTS)
1217+ table.oacl.represent = lambda val: acl_represent(val, auth.permission.PERMISSION_OPTS)
1218+
1219+ s3xrc.model.configure(table,
1220+ create_next = URL(r=request),
1221+ update_next = URL(r=request))
1222+
1223+ output = s3_rest_controller(prefix, name)
1224+ return output
1225+
1226+
1227+# -----------------------------------------------------------------------------
1228+def acl_represent(acl, options):
1229+ """
1230+ Represent ACLs in tables
1231+ for testing purposes, not for production use!
1232+
1233+ """
1234+
1235+ values = []
1236+
1237+ for o in options.keys():
1238+ if o == 0 and acl == 0:
1239+ values.append("%s" % options[o][0])
1240+ elif acl and acl & o == o:
1241+ values.append("%s" % options[o][0])
1242+ else:
1243+ values.append("_")
1244+
1245+ return " ".join(values)
1246+
1247+# -----------------------------------------------------------------------------
1248
1249=== removed file 'controllers/admin.py'
1250--- controllers/admin.py 2011-01-12 00:45:29 +0000
1251+++ controllers/admin.py 1970-01-01 00:00:00 +0000
1252@@ -1,1241 +0,0 @@
1253-# -*- coding: utf-8 -*-
1254-
1255-"""
1256- Admin Controllers
1257-"""
1258-
1259-import cPickle as pickle
1260-import csv
1261-from gluon.admin import *
1262-from gluon.fileutils import listdir
1263-
1264-module = "admin"
1265-
1266-# Options Menu (available in all Functions' Views)
1267-# - can Insert/Delete items from default menus within a function, if required.
1268-response.menu_options = admin_menu_options
1269-
1270-# S3 framework functions
1271-# -----------------------------------------------------------------------------
1272-def index():
1273-
1274- """ Module's Home Page """
1275-
1276- module_name = deployment_settings.modules[module].name_nice
1277- response.title = module_name
1278- return dict(module_name=module_name)
1279-
1280-
1281-# -----------------------------------------------------------------------------
1282-@auth.s3_requires_membership(1)
1283-def setting():
1284-
1285- """ RESTful CRUD controller """
1286-
1287- resourcename = request.function
1288- tablename = "s3_" + resourcename
1289- table = db[tablename]
1290-
1291- table.admin_name.label = T("Admin Name")
1292- table.admin_email.label = T("Admin Email")
1293- table.admin_tel.label = T("Admin Tel")
1294- #table.utc_offset.label = T("UTC Offset")
1295- table.theme.label = T("Theme")
1296- table.theme.comment = DIV(A(T("Add Theme"), _class="colorbox", _href=URL(r=request, c="admin", f="theme", args="create", vars=dict(format="popup")), _target="top", _title=T("Add Theme"))),
1297- #table.archive_not_delete.label = T("Archive not Delete")
1298- #table.archive_not_delete.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Archive not Delete") + "|" + T("If this setting is enabled then all deleted records are just flagged as deleted instead of being really deleted. They will appear in the raw database access but won't be visible to normal users."))
1299- #table.debug.label = T("Debug")
1300- #table.debug.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Debug") + "|" + T("Switch this on to use individual CSS/Javascript files for diagnostics during development."))
1301- #table.self_registration.label = T("Self Registration")
1302- #table.self_registration.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Self-registration") + "|" + T("Can users register themselves for authenticated login access?"))
1303- #table.security_policy.label = T("Security Policy")
1304- #table.security_policy.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Security Policy") + "|" + T("The simple policy allows anonymous users to Read & registered users to Edit. The full security policy allows the administrator to set permissions on individual tables or records - see models/zzz.py."))
1305- #table.audit_read.label = T("Audit Read")
1306- #table.audit_read.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Audit Read") + "|" + T("If enabled then a log is maintained of all records a user accesses. If disabled then it can still be enabled on a per-module basis."))
1307- #table.audit_write.label = T("Audit Write")
1308- #table.audit_write.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Audit Write") + "|" + T("If enabled then a log is maintained of all records a user edits. If disabled then it can still be enabled on a per-module basis."))
1309-
1310- s3.crud_strings[tablename] = Storage(
1311- title_update = T("Edit Settings"),
1312- msg_record_modified = T("Settings updated"),
1313- label_list_button = None)
1314-
1315- s3xrc.model.configure(table,
1316- deletable=False,
1317- listadd=False,
1318- #onvalidation=theme_check,
1319- #update_next = URL(r=request, args=[1, "update"])
1320- onaccept=theme_apply)
1321-
1322- output = s3_rest_controller("s3", resourcename, list_btn=None)
1323- return output
1324-
1325-
1326-# -----------------------------------------------------------------------------
1327-@auth.s3_requires_membership(1)
1328-def theme():
1329- """ RESTful CRUD controller """
1330- resource = "theme"
1331- tablename = module + "_" + resource
1332- table = db[tablename]
1333-
1334- # Model options
1335- table.name.label = T("Name")
1336- #table.logo.label = T("Logo")
1337- #table.logo.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Logo") + "|" + T("Name of the file (& optional sub-path) located in static which should be used for the top-left image."))
1338- #table.header_background.label = T("Header Background")
1339- #table.header_background.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Header Background") + "|" + T("Name of the file (& optional sub-path) located in static which should be used for the background of the header."))
1340- #table.footer.label = T("Footer")
1341- #table.footer.comment = A(SPAN("[Help]"), _class="tooltip", _title=T("Footer") + "|" + T("Name of the file (& optional sub-path) located in views which should be used for footer."))
1342- table.col_background.label = T("Background Colour")
1343- table.col_txt.label = T("Text Colour for Text blocks")
1344- table.col_txt_background.label = T("Background Colour for Text blocks")
1345- table.col_txt_border.label = T("Border Colour for Text blocks")
1346- table.col_txt_underline.label = T("Colour for Underline of Subheadings")
1347- table.col_menu.label = T("Colour of dropdown menus")
1348- table.col_highlight.label = T("Colour of selected menu items")
1349- table.col_input.label = T("Colour of selected Input fields")
1350- table.col_border_btn_out.label = T("Colour of bottom of Buttons when not pressed")
1351- table.col_border_btn_in.label = T("Colour of bottom of Buttons when pressed")
1352- table.col_btn_hover.label = T("Colour of Buttons when hovering")
1353-
1354- # CRUD Strings
1355- ADD_THEME = T("Add Theme")
1356- LIST_THEMES = T("List Themes")
1357- s3.crud_strings[resource] = Storage(
1358- title_create = ADD_THEME,
1359- title_display = T("Theme Details"),
1360- title_list = LIST_THEMES,
1361- title_update = T("Edit Theme"),
1362- title_search = T("Search Themes"),
1363- subtitle_create = T("Add New Theme"),
1364- subtitle_list = T("Themes"),
1365- label_list_button = LIST_THEMES,
1366- label_create_button = ADD_THEME,
1367- msg_record_created = T("Theme added"),
1368- msg_record_modified = T("Theme updated"),
1369- msg_record_deleted = T("Theme deleted"),
1370- msg_list_empty = T("No Themes currently defined"))
1371-
1372- s3xrc.model.configure(table,
1373- #onvalidation=theme_check,
1374- #list_fields=["id", "name", "logo", "footer", "col_background"],
1375- list_fields=["id", "name", "col_background"],
1376- )
1377-
1378- return s3_rest_controller(module, resource)
1379- s3xrc.model.clear_config(table, "onvalidation")
1380-
1381-
1382-# -----------------------------------------------------------------------------
1383-def theme_apply(form):
1384- "Apply the Theme specified by Form"
1385- if form.vars.theme:
1386- # Valid form
1387- # Relevant paths
1388- template = os.path.join(request.folder, "static", "styles", "S3", "template.css")
1389- tmp_folder = os.path.join(request.folder, "static", "scripts", "tools")
1390- out_file = os.path.join(request.folder, "static", "styles", "S3", "sahana.css")
1391- out_file2 = os.path.join(request.folder, "static", "styles", "S3", "sahana.min.css")
1392- # Check permissions
1393- if not os.access(template, os.R_OK):
1394- session.error = T("Template file %s not readable - unable to apply theme!" % template)
1395- redirect(URL(r=request, args=request.args))
1396- if not os.access(tmp_folder, os.W_OK):
1397- session.error = T("Temp folder %s not writable - unable to apply theme!" % tmp_folder)
1398- redirect(URL(r=request, args=request.args))
1399- if not os.access(out_file, os.W_OK):
1400- session.error = T("CSS file %s not writable - unable to apply theme!" % out_file)
1401- redirect(URL(r=request, args=request.args))
1402- if not os.access(out_file2, os.W_OK):
1403- session.error = T("CSS file %s not writable - unable to apply theme!" % out_file2)
1404- redirect(URL(r=request, args=request.args))
1405- # Read in Template
1406- inpfile = open(template, "r")
1407- lines = inpfile.readlines()
1408- inpfile.close()
1409- # Read settings from Database
1410- theme = db(db.admin_theme.id == form.vars.theme).select(limitby=(0, 1)).first()
1411- default_theme = db(db.admin_theme.id == 1).select(limitby=(0, 1)).first()
1412- #if theme.logo:
1413- # logo = theme.logo
1414- #else:
1415- # logo = default_theme.logo
1416- #if theme.header_background:
1417- # header_background = theme.header_background
1418- #else:
1419- # header_background = default_theme.header_background
1420- # Write out CSS
1421- ofile = open(out_file, "w")
1422- for line in lines:
1423- #line = line.replace("YOURLOGOHERE", logo)
1424- #line = line.replace("HEADERBACKGROUND", header_background )
1425- # Iterate through Colours
1426- for key in theme.keys():
1427- if key[:4] == "col_":
1428- if theme[key]:
1429- line = line.replace(key, theme[key])
1430- else:
1431- line = line.replace(key, default_theme[key])
1432- ofile.write(line)
1433- ofile.close()
1434-
1435- # Minify
1436- from subprocess import PIPE, check_call
1437- currentdir = os.getcwd()
1438- os.chdir(os.path.join(currentdir, request.folder, "static", "scripts", "tools"))
1439- import sys
1440- # If started as a Windows service, os.sys.executable is no longer python
1441- if ("win" in sys.platform):
1442- pythonpath = os.path.join(sys.prefix, "python.exe")
1443- else:
1444- pythonpath = os.sys.executable
1445- try:
1446- proc = check_call([pythonpath, "build.sahana.py", "CSS", "NOGIS"], stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=False)
1447- except:
1448- session.error = T("Error encountered while applying the theme.")
1449- redirect(URL(r=request, args=request.args))
1450- os.chdir(currentdir)
1451-
1452- # Don't do standard redirect to List view as we only want this option available
1453- redirect(URL(r=request, args=[1, "update"]))
1454- else:
1455- session.error = INVALIDREQUEST
1456- redirect(URL(r=request))
1457-
1458-
1459-# -----------------------------------------------------------------------------
1460-def theme_check(form):
1461- "Check the Theme has valid files available. Deprecated"
1462- # Check which form we're called by
1463- if form.vars.theme:
1464- # Called from Settings
1465- theme = db(db.admin_theme.id == form.vars.theme).select(db.admin_theme.logo, limitby=(0, 1)).first()
1466- logo = theme.logo
1467- #header_background = theme.header_background
1468- #footer = theme.footer
1469- #elif form.vars.logo and form.vars.footer:
1470- elif form.vars.logo:
1471- # Called from Theme
1472- logo = form.vars.logo
1473- #header_background = form.vars.header_background
1474- #footer = form.vars.footer
1475- else:
1476- session.error = INVALIDREQUEST
1477- redirect(URL(r=request))
1478-
1479- _logo = os.path.join(request.folder, "static", logo)
1480- #_header_background = os.path.join(request.folder, "static", header_background)
1481- #_footer = os.path.join(request.folder, "views", footer)
1482- if not os.access(_logo, os.R_OK):
1483- form.errors["logo"] = T("Logo file %s missing!" % logo)
1484- return
1485- #if not os.access(_header_background, os.R_OK):
1486- # form.errors["header_background"] = T("Header background file %s missing!" % logo)
1487- # return
1488- #if not os.access(_footer, os.R_OK):
1489- # form.errors["footer"] = T("Footer file %s missing!" % footer)
1490- # return
1491- # Validation passed
1492- return
1493-
1494-
1495-# -----------------------------------------------------------------------------
1496-@auth.s3_requires_membership(1)
1497-def user():
1498- """ RESTful CRUD controller """
1499- module = "auth"
1500- resource = "user"
1501- tablename = module + "_" + resource
1502- table = db[tablename]
1503-
1504- # Model options
1505- role_manager = s3base.S3RoleManager()
1506- s3xrc.model.set_method(module, resource, method="roles", action=role_manager)
1507-
1508- # CRUD Strings
1509- ADD_USER = T("Add User")
1510- LIST_USERS = T("List Users")
1511- s3.crud_strings[tablename] = Storage(
1512- title_create = ADD_USER,
1513- title_display = T("User Details"),
1514- title_list = LIST_USERS,
1515- title_update = T("Edit User"),
1516- title_search = T("Search Users"),
1517- subtitle_create = T("Add New User"),
1518- subtitle_list = T("Users"),
1519- label_list_button = LIST_USERS,
1520- label_create_button = ADD_USER,
1521- label_delete_button = T("Delete User"),
1522- msg_record_created = T("User added"),
1523- msg_record_modified = T("User updated"),
1524- msg_record_deleted = T("User deleted"),
1525- msg_list_empty = T("No Users currently registered"))
1526-
1527- # Allow the ability for admin to Disable logins
1528- db.auth_user.registration_key.writable = True
1529- db.auth_user.registration_key.readable = True
1530- db.auth_user.registration_key.label = T("Disabled?")
1531-
1532- # In Controller to allow registration to work with UUIDs - only manual edits need this setting
1533- db.auth_user.registration_key.requires = IS_NULL_OR(IS_IN_SET(["disabled", "pending"]))
1534-
1535- # Pre-processor
1536- def user_prep(jr):
1537- if jr.method == "delete" and jr.http=="GET":
1538- if jr.id == jr.session.auth.user.id: # we're trying to delete ourself
1539- request.get_vars.update({"user.id":str(jr.id)})
1540- jr.id = None
1541- s3xrc.model.configure(table,
1542- delete_next = URL(r=request, c="default", f="user/logout"))
1543- s3.crud.confirm_delete = T("You are attempting to delete your own account - are you sure you want to proceed?")
1544-
1545- elif jr.method == "update":
1546- # Send an email to user if their account is approved
1547- # (=moved from 'pending' to 'blank'(i.e. enabled))
1548- s3xrc.model.configure(table,
1549- onvalidation = lambda form: user_approve(form))
1550- return True
1551- response.s3.prep = user_prep
1552-
1553- s3xrc.model.configure(table,
1554- main="first_name",
1555- # Add users to Person Registry & 'Authenticated' role:
1556- create_onaccept = lambda form: auth.s3_register(form),
1557- create_onvalidation = lambda form: user_create_onvalidation(form))
1558- output = s3_rest_controller(module, resource)
1559-
1560- if response.s3.actions:
1561- response.s3.actions.insert(1,
1562- dict(label=str(T("Roles")), _class="action-btn",
1563- url=str(URL(r=request, c="admin", f="user", args=["[id]", "roles"]))))
1564- return output
1565-
1566-
1567-# -----------------------------------------------------------------------------
1568-def user_create_onvalidation (form):
1569- if (form.request_vars.has_key("password_two") and \
1570- form.request_vars.password != form.request_vars.password_two):
1571- form.errors.password = T("Password fields don't match")
1572- return True
1573-
1574-
1575-# -----------------------------------------------------------------------------
1576-def user_approve(form):
1577- "Send an email to user if their account is approved (moved from 'pending' to 'blank'(i.e. enabled))"
1578- if form.vars.registration_key:
1579- # Now non-blank
1580- return
1581- else:
1582- # Now blank - lookup old value
1583- status = db(db.auth_user.id == request.vars.id).select(db.auth_user.registration_key, limitby=(0, 1)).first().registration_key
1584- if status == "pending":
1585- # Send email to user confirming that they are now able to login
1586- if not auth.settings.mailer or \
1587- not auth.settings.mailer.send(to=form.vars.email,
1588- subject=s3.messages.confirmation_email_subject,
1589- message=s3.messages.confirmation_email):
1590- session.warning = auth.messages.unable_send_email
1591- return
1592- else:
1593- return
1594-
1595-
1596-# -----------------------------------------------------------------------------
1597-@auth.s3_requires_membership(1)
1598-def usergroup():
1599- """
1600- User update form with groups
1601- - NB This is currently unused & has no custom view
1602- """
1603- user = request.vars.user
1604-
1605- # redirect to the user list if user id is not given
1606- if user is None:
1607- redirect(URL(r=request, f="user"))
1608- return
1609-
1610- # gather common variables
1611- data = {}
1612- data["user_id"] = user
1613- data["username"] = db.auth_user[user].first_name + " " + \
1614- db.auth_user[user].last_name
1615- data["role"] = db.auth_group[user].role
1616-
1617- # display the standard user details
1618- record = db(db.auth_user.id == user).select().first()
1619- db.auth_user.id.readable = False
1620-
1621- # Let admin view and modify the registration key
1622- db.auth_user.registration_key.writable = True
1623- db.auth_user.registration_key.readable = True
1624- db.auth_user.registration_key.label = T("Disabled?")
1625- db.auth_user.registration_key.requires = IS_NULL_OR(IS_IN_SET(["disabled", "pending"]))
1626-
1627- form = SQLFORM(db.auth_user, record, deletable=True)
1628-
1629- # find all groups user belongs to
1630- query = (db.auth_membership.user_id == user)
1631- allgroups = db().select(db.auth_group.ALL)
1632- user_membership = db(query).select(db.auth_membership.ALL)
1633-
1634- # db.auth_group[row.group_id].role
1635- #records = SQLTABLE(db(query).select(db.auth_membership.ALL))
1636-
1637- # handle the M to M of user to group membership for display
1638- records = []
1639- for group in allgroups:
1640-
1641- user_group_count = 0
1642-
1643- for row in user_membership:
1644-
1645- if (row.group_id == group.id):
1646- records.append([group.role, "on", group.id])
1647- user_group_count += 1
1648-
1649- if (user_group_count == 0):
1650- # if the group does not exist currently and is enabled
1651- #if request.has_key(group.id):
1652- if (group.id == 6):
1653- db.auth_membership.insert(user_id = user, group_id = group.id)
1654- records.append([group.role, "on", group.id])
1655- data["heehe"] = "yes %d" % group.id
1656-
1657- records.append([group.role, "", group.id])
1658-
1659- # Update records for user details
1660- if form.accepts(request.vars): \
1661- response.flash="User " + data["username"] + " Updated"
1662- elif form.errors: \
1663- response.flash="There were errors in the form"
1664-
1665- # Update records for group membership details
1666- for key in request.vars.keys():
1667- data["m_" + key] = request.vars[key]
1668-
1669- return dict(data=data, records=records, form=form)
1670-
1671-
1672-# -----------------------------------------------------------------------------
1673-@auth.s3_requires_membership(1)
1674-def group():
1675-
1676- """ RESTful CRUD controller """
1677-
1678- prefix = "auth"
1679- resourcename = "group"
1680- tablename = "%s_%s" % (prefix, resourcename)
1681- table = db[tablename]
1682-
1683- # Model options
1684-
1685- # CRUD Strings
1686- ADD_ROLE = T("Add Role")
1687- LIST_ROLES = T("List Roles")
1688- s3.crud_strings[tablename] = Storage(
1689- title_create = ADD_ROLE,
1690- title_display = T("Role Details"),
1691- title_list = LIST_ROLES,
1692- title_update = T("Edit Role"),
1693- title_search = T("Search Roles"),
1694- subtitle_create = T("Add New Role"),
1695- subtitle_list = T("Roles"),
1696- label_list_button = LIST_ROLES,
1697- label_create_button = ADD_ROLE,
1698- msg_record_created = T("Role added"),
1699- msg_record_modified = T("Role updated"),
1700- msg_record_deleted = T("Role deleted"),
1701- msg_list_empty = T("No Roles currently defined"))
1702-
1703- s3xrc.model.configure(table, main="role")
1704- return s3_rest_controller(prefix, resourcename)
1705-
1706-
1707-# -----------------------------------------------------------------------------
1708-@auth.s3_requires_membership(1)
1709-def membership():
1710-
1711- """ RESTful CRUD controller """
1712-
1713- prefix = "auth"
1714- resourcename = "membership"
1715- tablename = prefix + "_" + resourcename
1716- table = db[tablename]
1717-
1718- # Model options
1719- db.auth_membership.group_id.represent = shn_role_represent
1720- db.auth_membership.user_id.represent = shn_user_represent
1721-
1722- # CRUD Strings
1723- ADD_MEMBERSHIP = T("Add Membership")
1724- LIST_MEMBERSHIPS = T("List Memberships")
1725- s3.crud_strings[tablename] = Storage(
1726- title_create = ADD_MEMBERSHIP,
1727- title_display = T("Membership Details"),
1728- title_list = LIST_MEMBERSHIPS,
1729- title_update = T("Edit Membership"),
1730- title_search = T("Search Memberships"),
1731- subtitle_create = T("Add New Membership"),
1732- subtitle_list = T("Memberships"),
1733- label_list_button = LIST_MEMBERSHIPS,
1734- label_create_button = ADD_MEMBERSHIP,
1735- msg_record_created = T("Membership added"),
1736- msg_record_modified = T("Membership updated"),
1737- msg_record_deleted = T("Membership deleted"),
1738- msg_list_empty = T("No Memberships currently defined"))
1739-
1740- s3xrc.model.configure(table, main="user_id")
1741- return s3_rest_controller(prefix, resourcename)
1742-
1743-
1744-# -----------------------------------------------------------------------------
1745-@auth.s3_requires_membership(1)
1746-def users():
1747- """
1748- List/amend which users are in a Group
1749-
1750- @deprecated
1751-
1752- """
1753-
1754- try:
1755- group = int(request.args(0))
1756- except TypeError, ValueError:
1757- session.error = T("Need to specify a role!")
1758- redirect(URL(r=request, f="group"))
1759-
1760- table = db.auth_membership
1761- query = table.group_id == group
1762- title = T("Role") + ": " + db.auth_group[group].role
1763- description = db.auth_group[group].description
1764- # Start building the Return
1765- output = dict(title=title, description=description, group=group)
1766-
1767- if auth.settings.username:
1768- username = "username"
1769- else:
1770- username = "email"
1771-
1772- # Audit
1773- crud.settings.create_onaccept = lambda form: s3_audit("create", module, "membership",
1774- form=form,
1775- representation="html")
1776- crud.settings.create_onvalidation = lambda form: group_dupes(form, "users", [group])
1777- # Many<>Many selection (Deletable, no Quantity)
1778- item_list = []
1779- sqlrows = db(query).select()
1780- even = True
1781- for row in sqlrows:
1782- if even:
1783- theclass = "even"
1784- even = False
1785- else:
1786- theclass = "odd"
1787- even = True
1788- id = row.user_id
1789- _user = db.auth_user[id]
1790- item_first = _user.first_name
1791- item_second = _user.last_name
1792- item_description = _user[username]
1793- id_link = A(id, _href=URL(r=request, f="user", args=[id, "read"]))
1794- checkbox = INPUT(_type="checkbox", _value="on", _name=id, _class="remove_item")
1795- item_list.append(TR(TD(id_link), TD(item_first), TD(item_second), TD(item_description), TD(checkbox), _class=theclass))
1796-
1797- if auth.settings.username:
1798- username_label = T("Username")
1799- else:
1800- username_label = T("Email")
1801- table_header = THEAD(TR(TH("ID"), TH(T("First Name")), TH(T("Last Name")), TH(username_label), TH(T("Remove"))))
1802- table_footer = TFOOT(TR(TD(_colspan=4), TD(INPUT(_id="submit_delete_button", _type="submit", _value=T("Remove")))))
1803- items = DIV(FORM(
1804- TABLE(table_header,
1805- TBODY(item_list),
1806- table_footer, _id="list", _class="display"), _name="custom", _method="post", _enctype="multipart/form-data", _action=URL(r=request, f="group_remove_users", args=[group])))
1807-
1808- subtitle = T("Users")
1809- crud.messages.submit_button = T("Add")
1810- crud.messages.record_created = T("Role Updated")
1811- form = crud.create(table, next=URL(r=request, args=[group]))
1812- addtitle = T("Add New User to Role")
1813- output.update(dict(subtitle=subtitle, items=items, addtitle=addtitle, form=form))
1814- return output
1815-
1816-
1817-# -----------------------------------------------------------------------------
1818-def group_dupes(form, page, arg):
1819- """
1820- Onvalidation check for duplicate user roles
1821-
1822- @deprecated
1823-
1824- """
1825-
1826- user = form.latest["user_id"]
1827- group = form.latest["group_id"]
1828- query = (form.table.user_id == user) & (form.table.group_id == group)
1829- items = db(query).select()
1830- if items:
1831- session.error = T("User already has this role")
1832- redirect(URL(r=request, f=page, args=arg))
1833-
1834-
1835-# -----------------------------------------------------------------------------
1836-@auth.s3_requires_membership(1)
1837-def group_remove_users():
1838- """
1839- Remove users from a group
1840- """
1841- if len(request.args) == 0:
1842- session.error = T("Need to specify a group!")
1843- redirect(URL(r=request, f="group"))
1844- group = request.args(0)
1845- table = db.auth_membership
1846- for var in request.vars:
1847- if str(var).isdigit():
1848- user = var
1849- query = (table.group_id == group) & (table.user_id == user)
1850- db(query).delete()
1851- # Audit
1852- #crud.settings.update_onaccept = lambda form: shn_audit_update(form, "membership", "html")
1853- session.flash = T("Users removed")
1854- redirect(URL(r=request, f="users", args=[group]))
1855-
1856-
1857-# -----------------------------------------------------------------------------
1858-@auth.s3_requires_membership(1)
1859-def groups():
1860- """
1861- List/amend which groups a User is in
1862- """
1863-
1864- try:
1865- user = int(request.args(0))
1866- except TypeError, ValueError:
1867- session.error = T("Need to specify a user!")
1868- redirect(URL(r=request, f="user"))
1869-
1870- table = db.auth_membership
1871- query = table.user_id == user
1872- title = db.auth_user[user].first_name + " " + db.auth_user[user].last_name
1873- description = db.auth_user[user].email
1874- # Start building the Return
1875- output = dict(title=title, description=description, user=user)
1876-
1877- # Audit
1878- crud.settings.create_onaccept = lambda form: s3_audit("create", module, "membership",
1879- form=form,
1880- representation="html")
1881-
1882-
1883- crud.settings.create_onvalidation = lambda form: group_dupes(form, "groups", [user])
1884- # Many<>Many selection (Deletable, no Quantity)
1885- item_list = []
1886- sqlrows = db(query).select()
1887- even = True
1888- for row in sqlrows:
1889- if even:
1890- theclass = "even"
1891- even = False
1892- else:
1893- theclass = "odd"
1894- even = True
1895- id = row.group_id
1896- _group = db.auth_group[id]
1897- item_first = _group.role
1898- item_description = _group.description
1899- id_link = A(id, _href=URL(r=request, f="group", args=[id, "read"]))
1900- checkbox = INPUT(_type="checkbox", _value="on", _name=id, _class="remove_item")
1901- item_list.append(TR(TD(id_link), TD(item_first), TD(item_description), TD(checkbox), _class=theclass))
1902-
1903- table_header = THEAD(TR(TH("ID"), TH(T("Role")), TH(T("Description")), TH(T("Remove"))))
1904- table_footer = TFOOT(TR(TD(_colspan=3), TD(INPUT(_id="submit_delete_button", _type="submit", _value=T("Remove")))))
1905- items = DIV(FORM(TABLE(table_header, TBODY(item_list), table_footer, _id="table-container"), _name="custom", _method="post", _enctype="multipart/form-data", _action=URL(r=request, f="user_remove_groups", args=[user])))
1906-
1907- subtitle = T("Roles")
1908- crud.messages.submit_button = T("Add")
1909- crud.messages.record_created = T("User Updated")
1910- form = crud.create(table, next=URL(r=request, args=[user]))
1911- addtitle = T("Add New Role to User")
1912- output.update(dict(subtitle=subtitle, items=items, addtitle=addtitle, form=form))
1913- return output
1914-
1915-
1916-# -----------------------------------------------------------------------------
1917-@auth.s3_requires_membership(1)
1918-def user_remove_groups():
1919- """ Remove groups from a user """
1920- if len(request.args) == 0:
1921- session.error = T("Need to specify a user!")
1922- redirect(URL(r=request, f="user"))
1923- user = request.args(0)
1924- table = db.auth_membership
1925- for var in request.vars:
1926- if str(var).isdigit():
1927- group = var
1928- query = (table.group_id == group) & (table.user_id == user)
1929- db(query).delete()
1930- # Audit
1931- #crud.settings.update_onaccept = lambda form: shn_audit_update(form, "membership", "html")
1932- session.flash = T("Groups removed")
1933- redirect(URL(r=request, f="groups", args=[user]))
1934-
1935-
1936-# -----------------------------------------------------------------------------
1937-@auth.s3_requires_membership(1)
1938-def import_data():
1939- """
1940- Import data via POST upload to CRUD controller. Old - being replaced by Sync/Importer.
1941- """
1942- title = T("Import Data")
1943- crud.messages.submit_button = "Upload"
1944-
1945- # Deprecated
1946- import_job_form = crud.create(db.admin_import_job)
1947- # Tell the CRUD create form to post to a different location
1948- import_job_form.custom.begin.text = str(import_job_form.custom.begin).replace(
1949- 'action=""',
1950- 'action="%s"' % URL(r=request, f="import_job", args=["create"]))
1951-
1952- return dict(title=title,
1953- import_job_form=import_job_form)
1954-
1955-
1956-# -----------------------------------------------------------------------------
1957-@auth.s3_requires_membership(1)
1958-def import_csv_data():
1959- """
1960- Import CSV data via POST upload to Database.
1961- """
1962- file = request.vars.multifile.file
1963- try:
1964- # Assumes that it is a concatenation of tables
1965- import_csv(file)
1966- session.flash = T("Data uploaded")
1967- except Exception, e:
1968- session.error = T("Unable to parse CSV file!")
1969- redirect(URL(r=request, f="import_data"))
1970-
1971-
1972-# -----------------------------------------------------------------------------
1973-@auth.requires_login()
1974-def export_data():
1975- """
1976- Export data via CRUD controller. Old - being replaced by Sync.
1977- """
1978- title = T("Export Data")
1979- return dict(title=title)
1980-
1981-
1982-# -----------------------------------------------------------------------------
1983-@auth.s3_requires_membership(1)
1984-def export_csv():
1985- """
1986- Export entire database as CSV. Old - being replaced by Sync.
1987- """
1988- import StringIO
1989- output = StringIO.StringIO()
1990-
1991- db.export_to_csv_file(output)
1992-
1993- output.seek(0)
1994- import gluon.contenttype
1995- response.headers["Content-Type"] = gluon.contenttype.contenttype(".csv")
1996- filename = "%s_database.csv" % (request.env.server_name)
1997- response.headers["Content-disposition"] = "attachment; filename=%s" % filename
1998- return output.read()
1999-
2000-
2001-# -----------------------------------------------------------------------------
2002-# Unstructured Data Import
2003-# Deprecated - being replaced by Importer
2004-@auth.s3_requires_membership(1)
2005-def import_job():
2006- "RESTful CRUD controller to handle 'jobs' for importing unstructured data."
2007- # CRUD Strings
2008- module = "admin"
2009- resource = "import_job"
2010- table = "%s_%s" % (module, resource)
2011- # This breaks!
2012- jr = s3xrc.request(module, resource, request, session=session)
2013- CREATE_NEW_IMPORT_JOB = T("Create New Import Job")
2014- LIST_IMPORT_JOBS = ("List Import Jobs")
2015- s3.crud_strings[table] = Storage(
2016- title_create=CREATE_NEW_IMPORT_JOB,
2017- title_display=T("Import Job"),
2018- title_list=LIST_IMPORT_JOBS,
2019- title_update=T("Update Import Job"),
2020- subtitle_create=CREATE_NEW_IMPORT_JOB,
2021- subtitle_list=T("Import Jobs"),
2022- label_list_button=LIST_IMPORT_JOBS,
2023- label_create_button=T("Create Import Job"),
2024- msg_record_created=T("Import job created"),
2025- msg_list_empty=T("No import jobs")
2026- )
2027-
2028- if len(request.args) == 0:
2029- return _import_job_list(jr)
2030- action = request.args(0)
2031- if action == "create":
2032- return _import_job_create(jr)
2033- if action == "update":
2034- return _import_job_update(jr)
2035-
2036-
2037-# -----------------------------------------------------------------------------
2038-def _import_job_list(jr):
2039- return shn_list(jr, listadd=False)
2040-
2041-
2042-# -----------------------------------------------------------------------------
2043-def _import_job_create(jr):
2044- if jr.http != "POST":
2045- redirect(jr.there())
2046-
2047- def process_new_file_and_redirect(form):
2048- filename = form.vars.source_file_newfilename
2049- filepath = os.path.join(request.folder, "uploads", filename)
2050- query = (jr.table.id == form.vars.id)
2051- column_map = []
2052- model_fields = dict(map(
2053- lambda x:(x.lower(), x),
2054- get_matchable_fields(form.vars.module, form.vars.resource)))
2055- try:
2056- reader = csv.reader(open(filepath, "r"))
2057- for line in reader:
2058- for col in line:
2059- field = None
2060- col_match = col.lower()
2061- if col_match in model_fields:
2062- # Explicit name match.
2063- field = model_fields.pop(col_match)
2064- if not field:
2065- # Partial name patch.
2066- for field_name in model_fields:
2067- if col_match in field_name or field_name in col_match:
2068- field = model_fields.pop(field_name)
2069- break
2070- column_map.append((col, field))
2071- break
2072- pickled_map = pickle.dumps(column_map, pickle.HIGHEST_PROTOCOL)
2073- db(query).update(column_map=pickled_map)
2074- except:
2075- db(query).update(status="failed")
2076- redirect(URL(r=request, f="import_job", args=[form.vars.id, "update"]))
2077-
2078- form = crud.create(jr.table, onaccept=process_new_file_and_redirect)
2079- response.flash = "Form errors!"
2080- redirect(URL(r=request, f="import_data"))
2081-
2082-
2083-# -----------------------------------------------------------------------------
2084-def _import_job_update(jr):
2085- if len(request.args) < 2:
2086- redirect(jr.there())
2087- id = request.args[1]
2088- query = (jr.table.id == id)
2089- job = db(query).select()
2090- if not job:
2091- raise HTTP(404, body=s3xrc.xml.json_message(False, 404, session.error))
2092- job = job[0]
2093-
2094- if jr.http == "GET":
2095- output = _import_job_update_GET(jr, job)
2096- elif jr.http == "POST":
2097- output = _import_job_update_POST(jr, job)
2098- else:
2099- raise HTTP(400, body=INVALIDREQUEST)
2100-
2101- title = "%s - %s" % (T("Input Job"), job.description)
2102- output.update(dict(title=title, job=job))
2103- response.view = "admin/import_job_update.html"
2104- return output
2105-
2106-
2107-# -----------------------------------------------------------------------------
2108-def _import_job_update_GET(jr, job):
2109- table = db.admin_import_line
2110- query = (table.import_job == job.id)
2111-
2112- if job.status == "new":
2113- try:
2114- job.column_map = pickle.loads(job.column_map)
2115- except pickle.UnpicklingError:
2116- job.column_map = []
2117- model_fields = get_matchable_fields(job.module, job.resource)
2118- return dict(model_fields=model_fields)
2119-
2120- if job.status == "processing":
2121- num_lines = db(query).count()
2122- return dict(num_lines=num_lines, update_speed=60)
2123-
2124- if job.status in ["processed", "failed", "imported"]:
2125- def _include_field(f):
2126- if f in ["import_job"]:
2127- return False
2128- return table[f].readable
2129-
2130- fields = [table[f] for f in table.fields if _include_field(f)]
2131- headers = dict(map(lambda f: (str(f), f.label), fields))
2132- items = crud.select(
2133- db["admin_import_line"],
2134- query=query,
2135- fields=fields,
2136- headers=headers,
2137- truncate=48, _id="list", _class="display")
2138- response.extra_styles = ["admin/import_job.css"]
2139- return dict(items=items)
2140-
2141- if job.status == "import":
2142- query = (table.import_job == job.id) & (table.status == "imported")
2143- num_lines = db(query).count()
2144- return dict(num_lines=num_lines, update_speed=60)
2145-
2146- return {}
2147-
2148-
2149-# -----------------------------------------------------------------------------
2150-def _import_job_update_POST(jr, job):
2151- if job.status == "new":
2152- # Update column map.
2153- try:
2154- column_map = pickle.loads(job.column_map)
2155- except pickle.UnpicklingError:
2156- column_map = []
2157- for key, value in request.vars.iteritems():
2158- if not key.startswith("column_map_"):
2159- continue
2160- try:
2161- idx = int(key.split("_")[-1])
2162- except ValueError:
2163- continue
2164- if value != "None (Ignore)":
2165- column_map[idx] = (column_map[idx][0], value)
2166- else:
2167- column_map[idx] = (column_map[idx][0], None)
2168- jr.table[job.id] = dict(
2169- column_map=pickle.dumps(column_map, pickle.HIGHEST_PROTOCOL),
2170- status="processing")
2171- job.status = "processing"
2172-
2173- if job.status == "processed":
2174- query = db.admin_import_line.id
2175- for var, status in request.vars.iteritems():
2176- if not var.startswith("status_"):
2177- continue
2178- try:
2179- import_line_id = int(var.split("_")[-1])
2180- except ValueError:
2181- continue
2182- db(db.admin_import_line.id == import_line_id).update(status=status)
2183- jr.table[job.id] = dict(status="import")
2184- job.status = "import"
2185-
2186- return _import_job_update_GET(jr, job)
2187-
2188-
2189-# -----------------------------------------------------------------------------
2190-def get_matchable_fields(module, resource):
2191- model_fields = getattr(db, "%s_%s" % (module, resource)).fields
2192- for name in ["created_on", "modified_on", "id", "uuid", "deleted"]:
2193- model_fields.remove(name)
2194- model_fields.insert(0, "None (Ignore)")
2195- return model_fields
2196-
2197-
2198-
2199-# -----------------------------------------------------------------------------
2200-# Functional Testing
2201-# Deprecated: Use static/selenium/scripts/regressionTests.py with it's Tk UI
2202-def handleResults():
2203- """
2204- Process the POST data returned from Selenium TestRunner.
2205- The data is written out to 2 files. The overall results are written to
2206- date-time-browserName-metadata.txt as a list of key: value, one per line. The
2207- suiteTable and testTables are written to date-time-browserName-results.html.
2208- """
2209-
2210- if not request.vars.result:
2211- # No results
2212- return
2213-
2214- # Read in results
2215- result = request.vars.result
2216- totalTime = request.vars.totalTime
2217- numberOfSuccesses = request.vars.numTestPasses
2218- numberOfFailures = request.vars.numTestFailures
2219- numberOfCommandSuccesses = request.vars.numCommandPasses
2220- numberOfCommandFailures = request.vars.numCommandFailures
2221- numberOfCommandErrors = request.vars.numCommandErrors
2222-
2223- suiteTable = ""
2224- if request.vars.suite:
2225- suiteTable = request.vars.suite
2226-
2227- testTables = []
2228- testTableNum = 1
2229- while request.vars["testTable.%s" % testTableNum]:
2230- testTable = request.vars["testTable.%s" % testTableNum]
2231- testTables.append(testTable)
2232- testTableNum += 1
2233- try:
2234- request.vars["testTable.%s" % testTableNum]
2235- pass
2236- except:
2237- break
2238-
2239- # Unescape the HTML tables
2240- import urllib
2241- suiteTable = urllib.unquote(suiteTable)
2242- testTables = map(urllib.unquote, testTables)
2243-
2244- # We want to store results separately for each browser
2245- browserName = getBrowserName(request.env.http_user_agent)
2246- date = str(request.utcnow)[:-16]
2247- time = str(request.utcnow)[11:-10]
2248- time = time.replace(":", "-")
2249-
2250- # Write out results
2251- outputDir = os.path.join(request.folder, "static", "selenium", "results")
2252- metadataFile = "%s-%s-%s-metadata.txt" % (date, time, browserName)
2253- dataFile = "%s-%s-%s-results.html" % (date, time, browserName)
2254-
2255- #xmlText = '<selenium result="' + result + '" totalTime="' + totalTime + '" successes="' + numberOfCommandSuccesses + '" failures="' + numberOfCommandFailures + '" errors="' + numberOfCommandErrors + '" />'
2256- f = open(os.path.join(outputDir, metadataFile), "w")
2257- for key in request.vars.keys():
2258- if "testTable" in key or key in ["log", "suite"]:
2259- pass
2260- else:
2261- print >> f, "%s: %s" % (key, request.vars[key])
2262- f.close()
2263-
2264- f = open(os.path.join(outputDir, dataFile), "w")
2265- print >> f, suiteTable
2266- for testTable in testTables:
2267- print >> f, "<br/><br/>"
2268- print >> f, testTable
2269- f.close()
2270-
2271- message = DIV(P("Results have been successfully posted to the server here:"),
2272- P(A(metadataFile, _href=URL(r=request, c="static", f="selenium", args=["results", metadataFile]))),
2273- P(A(dataFile, _href=URL(r=request, c="static", f="selenium", args=["results", dataFile]))))
2274-
2275- response.view = "display.html"
2276- title = T("Test Results")
2277- return dict(title=title, item=message)
2278-
2279-
2280-# -----------------------------------------------------------------------------
2281-# Ticket Viewer functions Borrowed from admin application of web2py
2282-@auth.s3_requires_membership(1)
2283-def errors():
2284- """ Error handler """
2285-
2286- app = request.application
2287-
2288- for item in request.vars:
2289- if item[:7] == "delete_":
2290- os.unlink(apath("%s/errors/%s" % (app, item[7:]), r=request))
2291-
2292- func = lambda p: os.stat(apath("%s/errors/%s" % (app, p), r=request)).st_mtime
2293- tickets = sorted(listdir(apath("%s/errors/" % app, r=request), "^\w.*"),
2294- key=func,
2295- reverse=True)
2296-
2297- return dict(app=app, tickets=tickets)
2298-
2299-
2300-# -----------------------------------------------------------------------------
2301-def make_link(path):
2302- """ Create a link from a path """
2303- tryFile = path.replace("\\", "/")
2304-
2305- if os.path.isabs(tryFile) and os.path.isfile(tryFile):
2306- (folder, filename) = os.path.split(tryFile)
2307- (base, ext) = os.path.splitext(filename)
2308- app = request.args[0]
2309-
2310- editable = {"controllers": ".py", "models": ".py", "views": ".html"}
2311- for key in editable.keys():
2312- check_extension = folder.endswith("%s/%s" % (app, key))
2313- if ext.lower() == editable[key] and check_extension:
2314- return A('"' + tryFile + '"',
2315- _href=URL(r=request,
2316- f="edit/%s/%s/%s" % (app, key, filename))).xml()
2317- return ""
2318-
2319-
2320-# -----------------------------------------------------------------------------
2321-def make_links(traceback):
2322- """ Make links using the given traceback """
2323-
2324- lwords = traceback.split('"')
2325-
2326- # Make the short circuit compatible with <= python2.4
2327- result = (len(lwords) != 0) and lwords[0] or ""
2328-
2329- i = 1
2330-
2331- while i < len(lwords):
2332- link = make_link(lwords[i])
2333-
2334- if link == "":
2335- result += '"' + lwords[i]
2336- else:
2337- result += link
2338-
2339- if i + 1 < len(lwords):
2340- result += lwords[i + 1]
2341- i = i + 1
2342-
2343- i = i + 1
2344-
2345- return result
2346-
2347-
2348-# -----------------------------------------------------------------------------
2349-class TRACEBACK(object):
2350- """ Generate the traceback """
2351-
2352- def __init__(self, text):
2353- """ TRACEBACK constructor """
2354-
2355- self.s = make_links(CODE(text).xml())
2356-
2357- def xml(self):
2358- """ Returns the xml """
2359-
2360- return self.s
2361-
2362-
2363-# -----------------------------------------------------------------------------
2364-# Ticket viewing
2365-@auth.s3_requires_membership(1)
2366-def ticket():
2367- """ Ticket handler """
2368-
2369- if len(request.args) != 2:
2370- session.flash = T("Invalid ticket")
2371- redirect(URL(r=request))
2372-
2373- app = request.args[0]
2374- ticket = request.args[1]
2375- e = RestrictedError()
2376- e.load(request, app, ticket)
2377-
2378- return dict(app=app,
2379- ticket=ticket,
2380- traceback=TRACEBACK(e.traceback),
2381- code=e.code,
2382- layer=e.layer)
2383-
2384-
2385-# -----------------------------------------------------------------------------
2386-@auth.s3_requires_membership(1)
2387-def role():
2388- """
2389- Role Manager
2390-
2391- @author: Dominic König <dominic@aidiq.com>
2392-
2393- """
2394-
2395- prefix = "auth"
2396- name = "group"
2397-
2398- # ACLs as component of roles
2399- s3xrc.model.add_component("s3", "permission",
2400- joinby = dict(auth_group="group_id"),
2401- multiple=True)
2402-
2403- def prep(r):
2404- if r.representation not in ("html",):
2405- return False
2406-
2407- handler = s3base.S3RoleManager()
2408- modules = deployment_settings.modules
2409- handler.controllers = Storage([(m, modules[m]) for m in modules
2410- if modules[m].restricted])
2411-
2412- # Configure REST methods
2413- resource = r.resource
2414- resource.add_method("users", handler)
2415- resource.set_handler("read", handler)
2416- resource.set_handler("list", handler)
2417- resource.set_handler("copy", handler)
2418- resource.set_handler("create", handler)
2419- resource.set_handler("update", handler)
2420- resource.set_handler("delete", handler)
2421- return True
2422- response.s3.prep = prep
2423-
2424- response.s3.no_sspag = True
2425- response.extra_styles = ["S3/role.css"]
2426-
2427- output = s3_rest_controller(prefix, name)
2428- return output
2429-
2430-
2431-# -----------------------------------------------------------------------------
2432-@auth.s3_requires_membership(1)
2433-def acl():
2434- """
2435- Preliminary controller for ACLs
2436- for testing purposes, not for production use!
2437-
2438- """
2439-
2440- prefix = "s3"
2441- name = "permission"
2442-
2443- table = auth.permission.table
2444- table.group_id.requires = IS_ONE_OF(db, "auth_group.id", "%(role)s")
2445- table.group_id.represent = lambda opt: opt and db.auth_group[opt].role or opt
2446-
2447- table.controller.requires = IS_EMPTY_OR(IS_IN_SET(auth.permission.modules.keys(), zero="ANY"))
2448- table.controller.represent = lambda opt: opt and "%s (%s)" % (opt, auth.permission.modules.get(opt, {}).get("name_nice", opt)) or "ANY"
2449-
2450- table.function.represent = lambda val: val and val or T("ANY")
2451-
2452- table.tablename.requires = IS_EMPTY_OR(IS_IN_SET([t._tablename for t in db], zero=T("ANY")))
2453- table.tablename.represent = lambda val: val and val or T("ANY")
2454-
2455- table.uacl.label = T("All Resources")
2456- table.uacl.widget = S3ACLWidget.widget
2457- table.uacl.requires = IS_ACL(auth.permission.PERMISSION_OPTS)
2458- table.uacl.represent = lambda val: acl_represent(val, auth.permission.PERMISSION_OPTS)
2459-
2460- table.oacl.label = T("Owned Resources")
2461- table.oacl.widget = S3ACLWidget.widget
2462- table.oacl.requires = IS_ACL(auth.permission.PERMISSION_OPTS)
2463- table.oacl.represent = lambda val: acl_represent(val, auth.permission.PERMISSION_OPTS)
2464-
2465- s3xrc.model.configure(table,
2466- create_next = URL(r=request),
2467- update_next = URL(r=request))
2468-
2469- output = s3_rest_controller(prefix, name)
2470- return output
2471-
2472-
2473-# -----------------------------------------------------------------------------
2474-def acl_represent(acl, options):
2475- """
2476- Represent ACLs in tables
2477- for testing purposes, not for production use!
2478-
2479- """
2480-
2481- values = []
2482-
2483- for o in options.keys():
2484- if o == 0 and acl == 0:
2485- values.append("%s" % options[o][0])
2486- elif acl and acl & o == o:
2487- values.append("%s" % options[o][0])
2488- else:
2489- values.append("_")
2490-
2491- return " ".join(values)
2492-
2493-# -----------------------------------------------------------------------------
2494
2495=== added file 'controllers/appadmin.py'
2496--- controllers/appadmin.py 1970-01-01 00:00:00 +0000
2497+++ controllers/appadmin.py 2011-01-24 22:41:50 +0000
2498@@ -0,0 +1,268 @@
2499+# -*- coding: utf-8 -*-
2500+
2501+"""
2502+ Application Admin Controllers
2503+"""
2504+
2505+import os
2506+#import socket
2507+import datetime
2508+import copy
2509+import gluon.contenttype
2510+import gluon.fileutils
2511+
2512+# ## crytical --- make a copy of the environment
2513+
2514+global_env = copy.copy(globals())
2515+global_env['datetime'] = datetime
2516+
2517+#
2518+# Native Web2Py Auth (localhost & site password)
2519+#
2520+#http_host = request.env.http_host.split(':')[0]
2521+#remote_addr = request.env.remote_addr
2522+#try:
2523+# hosts = (http_host, socket.gethostbyname(remote_addr))
2524+#except:
2525+# hosts = (http_host, )
2526+#if remote_addr not in hosts:
2527+# raise HTTP(400)
2528+#if not gluon.fileutils.check_credentials(request):
2529+# redirect('/admin')
2530+
2531+#
2532+# S3 Auth
2533+#
2534+if not s3_has_role(1):
2535+ unauthorised()
2536+
2537+module = "admin"
2538+
2539+# Options Menu (available in all Functions' Views)
2540+response.menu_options = admin_menu_options
2541+
2542+ignore_rw = True
2543+response.view = "admin/appadmin.html"
2544+#response.menu = [[T("design"), False, URL("admin", "default", "design",
2545+# args=[request.application])], [T("db"), False,
2546+# URL(r=request, f="index")], [T("state"), False,
2547+# URL(r=request, f="state")]]
2548+
2549+
2550+# ##########################################################
2551+# ## auxiliary functions
2552+# ###########################################################
2553+
2554+
2555+def get_databases(request):
2556+ dbs = {}
2557+ for (key, value) in global_env.items():
2558+ cond = False
2559+ try:
2560+ cond = isinstance(value, GQLDB)
2561+ except:
2562+ cond = isinstance(value, SQLDB)
2563+ if cond:
2564+ dbs[key] = value
2565+ return dbs
2566+
2567+
2568+databases = get_databases(None)
2569+
2570+
2571+def eval_in_global_env(text):
2572+ exec ('_ret=%s' % text, {}, global_env)
2573+ return global_env['_ret']
2574+
2575+
2576+def get_database(request):
2577+ if request.args and request.args(0) in databases:
2578+ return eval_in_global_env(request.args(0))
2579+ else:
2580+ session.flash = T('invalid request')
2581+ redirect(URL(r=request, f='index'))
2582+
2583+
2584+def get_table(request):
2585+ db = get_database(request)
2586+ if len(request.args) > 1 and request.args[1] in db.tables:
2587+ return (db, request.args[1])
2588+ else:
2589+ session.flash = T('invalid request')
2590+ redirect(URL(r=request, f='index'))
2591+
2592+
2593+def get_query(request):
2594+ try:
2595+ return eval_in_global_env(request.vars.query)
2596+ except Exception:
2597+ return None
2598+
2599+
2600+# ##########################################################
2601+# ## list all databases and tables
2602+# ###########################################################
2603+
2604+
2605+def index():
2606+ return dict(databases=databases)
2607+
2608+
2609+# ##########################################################
2610+# ## insert a new record
2611+# ###########################################################
2612+
2613+
2614+def insert():
2615+ (db, table) = get_table(request)
2616+ form = SQLFORM(db[table], ignore_rw=ignore_rw)
2617+ if form.accepts(request.vars, session):
2618+ response.flash = T('new record inserted')
2619+ return dict(form=form)
2620+
2621+
2622+# ##########################################################
2623+# ## list all records in table and insert new record
2624+# ###########################################################
2625+
2626+
2627+def download():
2628+ import os
2629+ db = get_database(request)
2630+ return response.download(request,db)
2631+
2632+def csv():
2633+ import gluon.contenttype
2634+ response.headers['Content-Type'] = \
2635+ gluon.contenttype.contenttype('.csv')
2636+ db = get_database(request)
2637+ query = get_query(request)
2638+ if not query:
2639+ return None
2640+ response.headers['Content-disposition'] = 'attachment; filename=%s_%s.csv'\
2641+ % tuple(request.vars.query.split('.')[:2])
2642+ return str(db(query).select())
2643+
2644+
2645+def import_csv(table, file):
2646+ table.import_from_csv_file(file)
2647+
2648+def select():
2649+ import re
2650+ db = get_database(request)
2651+ dbname = request.args(0)
2652+ regex = re.compile('(?P<table>\w+)\.(?P<field>\w+)=(?P<value>\d+)')
2653+ if request.vars.query:
2654+ match = regex.match(request.vars.query)
2655+ if match:
2656+ request.vars.query = '%s.%s.%s==%s' % (request.args(0),
2657+ match.group('table'), match.group('field'),
2658+ match.group('value'))
2659+ else:
2660+ request.vars.query = session.last_query
2661+ query = get_query(request)
2662+ if request.vars.start:
2663+ start = int(request.vars.start)
2664+ else:
2665+ start = 0
2666+ nrows = 0
2667+ stop = start + 100
2668+ table = None
2669+ rows = []
2670+ orderby = request.vars.orderby
2671+ if orderby:
2672+ orderby = dbname + '.' + orderby
2673+ if orderby == session.last_orderby:
2674+ if orderby[0] == '~':
2675+ orderby = orderby[1:]
2676+ else:
2677+ orderby = '~' + orderby
2678+ session.last_orderby = orderby
2679+ session.last_query = request.vars.query
2680+ form = FORM(TABLE(TR(T('Query') + ':', '', INPUT(_style='width:400px',
2681+ _name='query', _value=request.vars.query or '',
2682+ requires=IS_NOT_EMPTY(error_message=T("Cannot be empty")))), TR(T('Update') + ':',
2683+ INPUT(_name='update_check', _type='checkbox',
2684+ value=False), INPUT(_style='width:400px',
2685+ _name='update_fields', _value=request.vars.update_fields
2686+ or '')), TR(T('Delete') + ":", INPUT(_name='delete_check',
2687+ _class='delete', _type='checkbox', value=False), ''),
2688+ TR('', '', INPUT(_type='submit', _value='submit'))),
2689+ _action=URL(r=request,args=request.args))
2690+ if request.vars.csvfile != None:
2691+ try:
2692+ import_csv(db[request.vars.table],
2693+ request.vars.csvfile.file)
2694+ response.flash = T('data uploaded')
2695+ except:
2696+ response.flash = T('unable to parse csv file')
2697+ if form.accepts(request.vars, formname=None):
2698+ regex = re.compile(request.args(0) + '\.(?P<table>\w+)\.id\>0')
2699+ match = regex.match(form.vars.query.strip())
2700+ if match:
2701+ table = match.group('table')
2702+ try:
2703+ nrows = db(query).count()
2704+ if form.vars.update_check and form.vars.update_fields:
2705+ db(query).update(**eval_in_global_env('dict(%s)'
2706+ % form.vars.update_fields))
2707+ response.flash = T('%s rows updated', nrows)
2708+ elif form.vars.delete_check:
2709+ db(query).delete()
2710+ response.flash = T('%s rows deleted', nrows)
2711+ nrows = db(query).count()
2712+ if orderby:
2713+ rows = db(query).select(limitby=(start, stop),
2714+ orderby=eval_in_global_env(orderby))
2715+ else:
2716+ rows = db(query).select(limitby=(start, stop))
2717+ except:
2718+ (rows, nrows) = ([], 0)
2719+ response.flash = T('Invalid Query')
2720+ return dict(
2721+ form=form,
2722+ table=table,
2723+ start=start,
2724+ stop=stop,
2725+ nrows=nrows,
2726+ rows=rows,
2727+ query=request.vars.query
2728+ )
2729+
2730+
2731+# ##########################################################
2732+# ## edit delete one record
2733+# ###########################################################
2734+
2735+
2736+def update():
2737+ (db, table) = get_table(request)
2738+ try:
2739+ id = int(request.args[2])
2740+ record = db(db[table].id == id).select().first()
2741+ except:
2742+ session.flash = T('record does not exist')
2743+ redirect(URL(r=request, f='select', args=request.args[:1],
2744+ vars=dict(query='%s.%s.id>0'
2745+ % tuple(request.args[:2]))))
2746+ form = SQLFORM(db[table], record, deletable=True, delete_label=T('Check to delete'), ignore_rw=ignore_rw,
2747+ linkto=URL(r=request, f='select',
2748+ args=request.args[:1]), upload=URL(r=request,
2749+ f='download', args=request.args[:1]))
2750+ if form.accepts(request.vars, session):
2751+ response.flash = T('done!')
2752+ redirect(URL(r=request, f='select', args=request.args[:1],
2753+ vars=dict(query='%s.%s.id>0'
2754+ % tuple(request.args[:2]))))
2755+ return dict(form=form)
2756+
2757+
2758+# ##########################################################
2759+# ## get global variables
2760+# ###########################################################
2761+
2762+
2763+def state():
2764+ return dict()
2765+
2766+
2767
2768=== removed file 'controllers/appadmin.py'
2769--- controllers/appadmin.py 2011-01-11 21:17:57 +0000
2770+++ controllers/appadmin.py 1970-01-01 00:00:00 +0000
2771@@ -1,268 +0,0 @@
2772-# -*- coding: utf-8 -*-
2773-
2774-"""
2775- Application Admin Controllers
2776-"""
2777-
2778-import os
2779-#import socket
2780-import datetime
2781-import copy
2782-import gluon.contenttype
2783-import gluon.fileutils
2784-
2785-# ## crytical --- make a copy of the environment
2786-
2787-global_env = copy.copy(globals())
2788-global_env['datetime'] = datetime
2789-
2790-#
2791-# Native Web2Py Auth (localhost & site password)
2792-#
2793-#http_host = request.env.http_host.split(':')[0]
2794-#remote_addr = request.env.remote_addr
2795-#try:
2796-# hosts = (http_host, socket.gethostbyname(remote_addr))
2797-#except:
2798-# hosts = (http_host, )
2799-#if remote_addr not in hosts:
2800-# raise HTTP(400)
2801-#if not gluon.fileutils.check_credentials(request):
2802-# redirect('/admin')
2803-
2804-#
2805-# S3 Auth
2806-#
2807-if not s3_has_role(1):
2808- unauthorised()
2809-
2810-module = "admin"
2811-
2812-# Options Menu (available in all Functions' Views)
2813-response.menu_options = admin_menu_options
2814-
2815-ignore_rw = True
2816-response.view = "admin/appadmin.html"
2817-#response.menu = [[T("design"), False, URL("admin", "default", "design",
2818-# args=[request.application])], [T("db"), False,
2819-# URL(r=request, f="index")], [T("state"), False,
2820-# URL(r=request, f="state")]]
2821-
2822-
2823-# ##########################################################
2824-# ## auxiliary functions
2825-# ###########################################################
2826-
2827-
2828-def get_databases(request):
2829- dbs = {}
2830- for (key, value) in global_env.items():
2831- cond = False
2832- try:
2833- cond = isinstance(value, GQLDB)
2834- except:
2835- cond = isinstance(value, SQLDB)
2836- if cond:
2837- dbs[key] = value
2838- return dbs
2839-
2840-
2841-databases = get_databases(None)
2842-
2843-
2844-def eval_in_global_env(text):
2845- exec ('_ret=%s' % text, {}, global_env)
2846- return global_env['_ret']
2847-
2848-
2849-def get_database(request):
2850- if request.args and request.args(0) in databases:
2851- return eval_in_global_env(request.args(0))
2852- else:
2853- session.flash = T('invalid request')
2854- redirect(URL(r=request, f='index'))
2855-
2856-
2857-def get_table(request):
2858- db = get_database(request)
2859- if len(request.args) > 1 and request.args[1] in db.tables:
2860- return (db, request.args[1])
2861- else:
2862- session.flash = T('invalid request')
2863- redirect(URL(r=request, f='index'))
2864-
2865-
2866-def get_query(request):
2867- try:
2868- return eval_in_global_env(request.vars.query)
2869- except Exception:
2870- return None
2871-
2872-
2873-# ##########################################################
2874-# ## list all databases and tables
2875-# ###########################################################
2876-
2877-
2878-def index():
2879- return dict(databases=databases)
2880-
2881-
2882-# ##########################################################
2883-# ## insert a new record
2884-# ###########################################################
2885-
2886-
2887-def insert():
2888- (db, table) = get_table(request)
2889- form = SQLFORM(db[table], ignore_rw=ignore_rw)
2890- if form.accepts(request.vars, session):
2891- response.flash = T('new record inserted')
2892- return dict(form=form)
2893-
2894-
2895-# ##########################################################
2896-# ## list all records in table and insert new record
2897-# ###########################################################
2898-
2899-
2900-def download():
2901- import os
2902- db = get_database(request)
2903- return response.download(request,db)
2904-
2905-def csv():
2906- import gluon.contenttype
2907- response.headers['Content-Type'] = \
2908- gluon.contenttype.contenttype('.csv')
2909- db = get_database(request)
2910- query = get_query(request)
2911- if not query:
2912- return None
2913- response.headers['Content-disposition'] = 'attachment; filename=%s_%s.csv'\
2914- % tuple(request.vars.query.split('.')[:2])
2915- return str(db(query).select())
2916-
2917-
2918-def import_csv(table, file):
2919- table.import_from_csv_file(file)
2920-
2921-def select():
2922- import re
2923- db = get_database(request)
2924- dbname = request.args(0)
2925- regex = re.compile('(?P<table>\w+)\.(?P<field>\w+)=(?P<value>\d+)')
2926- if request.vars.query:
2927- match = regex.match(request.vars.query)
2928- if match:
2929- request.vars.query = '%s.%s.%s==%s' % (request.args(0),
2930- match.group('table'), match.group('field'),
2931- match.group('value'))
2932- else:
2933- request.vars.query = session.last_query
2934- query = get_query(request)
2935- if request.vars.start:
2936- start = int(request.vars.start)
2937- else:
2938- start = 0
2939- nrows = 0
2940- stop = start + 100
2941- table = None
2942- rows = []
2943- orderby = request.vars.orderby
2944- if orderby:
2945- orderby = dbname + '.' + orderby
2946- if orderby == session.last_orderby:
2947- if orderby[0] == '~':
2948- orderby = orderby[1:]
2949- else:
2950- orderby = '~' + orderby
2951- session.last_orderby = orderby
2952- session.last_query = request.vars.query
2953- form = FORM(TABLE(TR(T('Query') + ':', '', INPUT(_style='width:400px',
2954- _name='query', _value=request.vars.query or '',
2955- requires=IS_NOT_EMPTY(error_message=T("Cannot be empty")))), TR(T('Update') + ':',
2956- INPUT(_name='update_check', _type='checkbox',
2957- value=False), INPUT(_style='width:400px',
2958- _name='update_fields', _value=request.vars.update_fields
2959- or '')), TR(T('Delete') + ":", INPUT(_name='delete_check',
2960- _class='delete', _type='checkbox', value=False), ''),
2961- TR('', '', INPUT(_type='submit', _value='submit'))),
2962- _action=URL(r=request,args=request.args))
2963- if request.vars.csvfile != None:
2964- try:
2965- import_csv(db[request.vars.table],
2966- request.vars.csvfile.file)
2967- response.flash = T('data uploaded')
2968- except:
2969- response.flash = T('unable to parse csv file')
2970- if form.accepts(request.vars, formname=None):
2971- regex = re.compile(request.args(0) + '\.(?P<table>\w+)\.id\>0')
2972- match = regex.match(form.vars.query.strip())
2973- if match:
2974- table = match.group('table')
2975- try:
2976- nrows = db(query).count()
2977- if form.vars.update_check and form.vars.update_fields:
2978- db(query).update(**eval_in_global_env('dict(%s)'
2979- % form.vars.update_fields))
2980- response.flash = T('%s rows updated', nrows)
2981- elif form.vars.delete_check:
2982- db(query).delete()
2983- response.flash = T('%s rows deleted', nrows)
2984- nrows = db(query).count()
2985- if orderby:
2986- rows = db(query).select(limitby=(start, stop),
2987- orderby=eval_in_global_env(orderby))
2988- else:
2989- rows = db(query).select(limitby=(start, stop))
2990- except:
2991- (rows, nrows) = ([], 0)
2992- response.flash = T('Invalid Query')
2993- return dict(
2994- form=form,
2995- table=table,
2996- start=start,
2997- stop=stop,
2998- nrows=nrows,
2999- rows=rows,
3000- query=request.vars.query
3001- )
3002-
3003-
3004-# ##########################################################
3005-# ## edit delete one record
3006-# ###########################################################
3007-
3008-
3009-def update():
3010- (db, table) = get_table(request)
3011- try:
3012- id = int(request.args[2])
3013- record = db(db[table].id == id).select().first()
3014- except:
3015- session.flash = T('record does not exist')
3016- redirect(URL(r=request, f='select', args=request.args[:1],
3017- vars=dict(query='%s.%s.id>0'
3018- % tuple(request.args[:2]))))
3019- form = SQLFORM(db[table], record, deletable=True, delete_label=T('Check to delete'), ignore_rw=ignore_rw,
3020- linkto=URL(r=request, f='select',
3021- args=request.args[:1]), upload=URL(r=request,
3022- f='download', args=request.args[:1]))
3023- if form.accepts(request.vars, session):
3024- response.flash = T('done!')
3025- redirect(URL(r=request, f='select', args=request.args[:1],
3026- vars=dict(query='%s.%s.id>0'
3027- % tuple(request.args[:2]))))
3028- return dict(form=form)
3029-
3030-
3031-# ##########################################################
3032-# ## get global variables
3033-# ###########################################################
3034-
3035-
3036-def state():
3037- return dict()
3038-
3039-
3040
3041=== added file 'controllers/assess.py'
3042--- controllers/assess.py 1970-01-01 00:00:00 +0000
3043+++ controllers/assess.py 2011-01-24 22:41:50 +0000
3044@@ -0,0 +1,789 @@
3045+# -*- coding: utf-8 -*-
3046+
3047+""" Assessments - Controller
3048+
3049+ @author: Fran Boon
3050+ @author: Dominic König
3051+ @author: Michael Howden (michael@sahanafoundation.org)
3052+ @date-created: 2010-08-25
3053+
3054+"""
3055+
3056+prefix = request.controller
3057+resourcename = request.function
3058+
3059+if prefix not in deployment_settings.modules:
3060+ session.error = T("Module disabled!")
3061+ redirect(URL(r=request, c="default", f="index"))
3062+
3063+# Options Menu (available in all Functions' Views)
3064+def shn_menu():
3065+ menu = [
3066+ [T("Rapid Assessments"), False, aURL(r=request, f="rat"), [
3067+ [T("List"), False, aURL(r=request, f="rat")],
3068+ [T("Add"), False, aURL(p="create", r=request, f="rat", args="create")],
3069+ #[T("Search"), False, URL(r=request, f="rat", args="search")],
3070+ ]],
3071+ [T("Impact Assessments"), False, aURL(r=request, f="assess"), [
3072+ [T("List"), False, aURL(r=request, f="assess")],
3073+ #[T("Add"), False, aURL(p="create", r=request, f="assess", args="create")],
3074+ [T("Add"), False, aURL(r=request, f="basic_assess")],
3075+ [T("Mobile"), False, aURL(r=request, f="mobile_basic_assess")],
3076+ #[T("Search"), False, aURL(r=request, f="assess", args="search")],
3077+ ]],
3078+ ]
3079+ if s3_has_role(1):
3080+ menu_editor = [
3081+ [T("Edit Options"), False, URL(r=request, f="#"), [
3082+ [T("List / Add Baseline Types"), False, URL(r=request, f="baseline_type")],
3083+ [T("List / Add Impact Types"), False, URL(r=request, f="impact_type")],
3084+ ]],
3085+ ]
3086+ menu.extend(menu_editor)
3087+ response.menu_options = menu
3088+
3089+shn_menu()
3090+
3091+#==============================================================================
3092+def index():
3093+
3094+ """ Module's Home Page """
3095+
3096+ module_name = deployment_settings.modules[prefix].name_nice
3097+ response.title = module_name
3098+ return dict(module_name=module_name)
3099+
3100+
3101+# -----------------------------------------------------------------------------
3102+def maps():
3103+
3104+ """ Show a Map of all Rapid Assessments """
3105+
3106+ reports = db(db.gis_location.id == db.assess_rat.location_id).select()
3107+ report_popup_url = URL(r=request, f="rat", args="read.popup?rat.location_id=")
3108+ map = gis.show_map(feature_queries = [{"name":T("Rapid Assessments"), "query":reports, "active":True, "popup_url": report_popup_url}], window=True)
3109+
3110+ return dict(map=map)
3111+
3112+
3113+# -----------------------------------------------------------------------------
3114+def rat():
3115+
3116+ """ Rapid Assessments, RESTful controller """
3117+
3118+ tablename = "%s_%s" % (prefix, resourcename)
3119+ table = db[tablename]
3120+
3121+ # Don't send the locations list to client (pulled by AJAX instead)
3122+ table.location_id.requires = IS_NULL_OR(IS_ONE_OF_EMPTY(db, "gis_location.id"))
3123+
3124+ # Villages only
3125+ #table.location_id.requires = IS_NULL_OR(IS_ONE_OF(db(db.gis_location.level == "L5"),
3126+ # "gis_location.id",
3127+ # repr_select, sort=True))
3128+
3129+ # Pre-populate staff ID
3130+ if auth.is_logged_in():
3131+ staff_id = db((db.pr_person.uuid == session.auth.user.person_uuid) & \
3132+ (db.org_staff.person_id == db.pr_person.id)).select(
3133+ db.org_staff.id, limitby=(0, 1)).first()
3134+ if staff_id:
3135+ table.staff_id.default = staff_id.id
3136+
3137+ # Subheadings in forms:
3138+ s3xrc.model.configure(db.assess_section2,
3139+ subheadings = {
3140+ "Population and number of households": "population_total",
3141+ "Fatalities": "dead_women",
3142+ "Casualties": "injured_women",
3143+ "Missing Persons": "missing_women",
3144+ "General information on demographics": "household_head_elderly",
3145+ "Comments": "comments"})
3146+ s3xrc.model.configure(db.assess_section3,
3147+ subheadings = {
3148+ "Access to Shelter": "houses_total",
3149+ "Water storage containers in households": "water_containers_available",
3150+ "Other non-food items": "cooking_equipment_available",
3151+ "Shelter/NFI Assistance": "nfi_assistance_available",
3152+ "Comments": "comments"})
3153+ s3xrc.model.configure(db.assess_section4,
3154+ subheadings = {
3155+ "Water supply": "water_source_pre_disaster_type",
3156+ "Water collection": "water_coll_time",
3157+ "Places for defecation": "defec_place_type",
3158+ "Environment": "close_industry",
3159+ "Latrines": "latrines_number",
3160+ "Comments": "comments"})
3161+ s3xrc.model.configure(db.assess_section5,
3162+ subheadings = {
3163+ "Health services status": "health_services_pre_disaster",
3164+ "Current health problems": "health_problems_adults",
3165+ "Nutrition problems": "malnutrition_present_pre_disaster",
3166+ "Comments": "comments"})
3167+ s3xrc.model.configure(db.assess_section6,
3168+ subheadings = {
3169+ "Existing food stocks": "food_stocks_main_dishes",
3170+ "food_sources" : "Food sources",
3171+ "Food assistance": "food_assistance_available",
3172+ "Comments": "comments"})
3173+ s3xrc.model.configure(db.assess_section7,
3174+ subheadings = {
3175+ "Sources of income / Major expenses": "income_sources_pre_disaster",
3176+ "business_damaged" : "Access to cash",
3177+ "Current community priorities": "rank_reconstruction_assistance",
3178+ "Comments": "comments"})
3179+ s3xrc.model.configure(db.assess_section8,
3180+ subheadings = {
3181+ "Access to education services": "schools_total",
3182+ "Alternative places for studying": "alternative_study_places_available",
3183+ "School activities": "schools_open_pre_disaster",
3184+ "School attendance": "children_0612_female",
3185+ "School assistance": "school_assistance_available",
3186+ "Comments": "comments"})
3187+ s3xrc.model.configure(db.assess_section9,
3188+ subheadings = {
3189+ "Physical Safety": "vulnerable_groups_safe_env",
3190+ "Separated children, caregiving arrangements": "children_separated",
3191+ "Persons in institutions": "children_in_disabled_homes",
3192+ "Activities of children": "child_activities_u12f_pre_disaster",
3193+ "Coping Activities": "coping_activities_elderly",
3194+ "Current general needs": "current_general_needs",
3195+ "Comments": "comments"})
3196+
3197+ # @ToDo Generalize this and make it available as a function that other
3198+ # component prep methods can call to set the default for a join field.
3199+ def prep(r):
3200+ if r.representation=="html" and r.http=="GET" and r.method=="create":
3201+ # If this assessment is being created as a component of a shelter,
3202+ # it will have the shelter id in its vars.
3203+ shelter_id = r.request.get_vars.get("rat.shelter_id", None)
3204+ if shelter_id:
3205+ try:
3206+ shelter_id = int(shelter_id)
3207+ except ValueError:
3208+ pass
3209+ else:
3210+ db.assess_rat.shelter_id.default = shelter_id
3211+ # If this assessment is being created as a component of a document,
3212+ # it will have the document id in its vars.
3213+ document_id = r.request.get_vars.get("rat.document_id", None)
3214+ if document_id:
3215+ try:
3216+ document_id = int(document_id)
3217+ except ValueError:
3218+ pass
3219+ else:
3220+ db.assess_rat.document_id.default = document_id
3221+ return True
3222+ response.s3.prep = prep
3223+
3224+ # Post-processor
3225+ def postp(r, output):
3226+ shn_action_buttons(r, deletable=False)
3227+ # Redirect to read/edit view rather than list view
3228+ if r.representation == "html" and r.method == "create":
3229+ r.next = r.other(method="",
3230+ record_id=s3xrc.get_session("assess", "rat"))
3231+ return output
3232+ response.s3.postp = postp
3233+
3234+ # Over-ride the listadd since we're not a component here
3235+ s3xrc.model.configure(table, create_next="", listadd=True)
3236+
3237+ rheader = lambda r: shn_rat_rheader(r,
3238+ tabs = [(T("Identification"), None),
3239+ (T("Demographic"), "section2"),
3240+ (T("Shelter & Essential NFIs"), "section3"),
3241+ (T("WatSan"), "section4"),
3242+ (T("Health"), "section5"),
3243+ (T("Nutrition"), "section6"),
3244+ (T("Livelihood"), "section7"),
3245+ (T("Education"), "section8"),
3246+ (T("Protection"), "section9") ])
3247+
3248+ output = s3_rest_controller(prefix, resourcename, rheader=rheader)
3249+
3250+ response.extra_styles = ["S3/rat.css"]
3251+ return output
3252+
3253+
3254+# -----------------------------------------------------------------------------
3255+def shn_rat_rheader(r, tabs=[]):
3256+
3257+ """ Resource Headers """
3258+
3259+ if r.representation == "html":
3260+ if r.name == "rat":
3261+ report = r.record
3262+ if report:
3263+ rheader_tabs = shn_rheader_tabs(r, tabs, paging=True)
3264+ location = report.location_id
3265+ if location:
3266+ location = shn_gis_location_represent(location)
3267+ staff = report.staff_id
3268+ if staff:
3269+ organisation_id = db(db.org_staff.id == staff).select(db.org_staff.organisation_id).first().organisation_id
3270+ organisation = shn_organisation_represent(organisation_id)
3271+ else:
3272+ organisation = None
3273+ staff = report.staff2_id
3274+ if staff:
3275+ organisation_id = db(db.org_staff.id == staff).select(db.org_staff.organisation_id).first().organisation_id
3276+ organisation2 = shn_organisation_represent(organisation_id)
3277+ else:
3278+ organisation2 = None
3279+ if organisation2:
3280+ orgs = organisation + ", " + organisation2
3281+ else:
3282+ orgs = organisation
3283+ doc_name = doc_url = None
3284+ document = db(db.doc_document.id == report.document_id).select(db.doc_document.name, db.doc_document.file, limitby=(0, 1)).first()
3285+ if document:
3286+ doc_name = document.name
3287+ doc_url = URL(r=request, c="default", f="download", args=[document.file])
3288+ rheader = DIV(TABLE(
3289+ TR(
3290+ TH(T("Location") + ": "), location,
3291+ TH(T("Date") + ": "), report.date
3292+ ),
3293+ TR(
3294+ TH(T("Organizations") + ": "), orgs,
3295+ TH(T("Document") + ": "), A(doc_name, _href=doc_url)
3296+ )
3297+ ),
3298+ rheader_tabs)
3299+
3300+ return rheader
3301+ return None
3302+
3303+#==============================================================================
3304+# Flexible Impact Assessments
3305+#==============================================================================
3306+def shn_assess_rheader(r, tabs=[]):
3307+
3308+ """ Resource Headers for Flexible Impact Assessments """
3309+
3310+ if r.representation == "html":
3311+
3312+ rheader_tabs = shn_rheader_tabs(r, tabs)
3313+
3314+ assess = r.record
3315+
3316+ if assess:
3317+ rheader = DIV(TABLE(TR(
3318+ TH(T("Date & Time") + ": "), assess.datetime,
3319+ TH(T("Location") + ": "), shn_gis_location_represent(assess.location_id),
3320+ TH(T("Assessor") + ": "), shn_pr_person_represent(assess.assessor_person_id),
3321+ ),
3322+ ),
3323+ rheader_tabs
3324+ )
3325+ return rheader
3326+
3327+ return None
3328+
3329+
3330+#==============================================================================
3331+def assess():
3332+
3333+ """ RESTful CRUD controller """
3334+
3335+ tablename = "%s_%s" % (prefix, resourcename)
3336+ table = db[tablename]
3337+
3338+ # Pre-processor
3339+ def shn_assess_prep(r):
3340+ if session.s3.mobile and r.method == "create" and r.representation in shn_interactive_view_formats:
3341+ # redirect to mobile-specific form:
3342+ redirect(URL(r=request, f="assess_short_mobile"))
3343+ return True
3344+ response.s3.prep = shn_assess_prep
3345+
3346+ table.incident_id.comment = DIV(_class="tooltip",
3347+ _title=T("Incident") + "|" + T("Optional link to an Incident which this Assessment was triggered by."))
3348+
3349+ tabs = [
3350+ (T("Edit Details"), None),
3351+ (T("Baselines"), "baseline"),
3352+ (T("Impacts"), "impact"),
3353+ (T("Summary"), "summary"),
3354+ #(T("Requested"), "ritem"),
3355+ ]
3356+
3357+ rheader = lambda r: shn_assess_rheader(r, tabs)
3358+
3359+ return s3_rest_controller(prefix, resourcename, rheader=rheader)
3360+
3361+
3362+#==============================================================================
3363+def impact_type():
3364+
3365+ """ RESTful CRUD controller """
3366+
3367+ prefix = "impact"
3368+ resourcename = "type"
3369+
3370+ tablename = "%s_%s" % (prefix, resourcename)
3371+ table = db[tablename]
3372+
3373+ return s3_rest_controller(prefix, resourcename)
3374+
3375+
3376+#==============================================================================
3377+def baseline_type():
3378+
3379+ """ RESTful CRUD controller """
3380+
3381+ tablename = "%s_%s" % (prefix, resourcename)
3382+ table = db[tablename]
3383+
3384+ return s3_rest_controller(prefix, resourcename)
3385+
3386+
3387+#==============================================================================
3388+def baseline():
3389+
3390+ """ RESTful CRUD controller """
3391+
3392+ tablename = "%s_%s" % (prefix, resourcename)
3393+ table = db[tablename]
3394+
3395+ return s3_rest_controller(prefix, resourcename)
3396+
3397+
3398+#==============================================================================
3399+def summary():
3400+
3401+ """ RESTful CRUD controller """
3402+
3403+ tablename = "%s_%s" % (prefix, resourcename)
3404+ table = db[tablename]
3405+
3406+ return s3_rest_controller(prefix, resourcename)
3407+
3408+
3409+#==============================================================================
3410+def basic_assess():
3411+ ireport_id = request.vars.get("ireport_id")
3412+ location = None
3413+ if incident_id:
3414+ irs_location_id = shn_get_db_field_value(db = db,
3415+ table = "irs_ireport",
3416+ field = "location_id",
3417+ look_up = ireport_id
3418+ )
3419+ location = shn_gis_location_represent(irs_location_id)
3420+ custom_assess_fields = (
3421+ ("impact", 1),
3422+ ("impact", 2),
3423+ ("impact", 3),
3424+ ("impact", 4),
3425+ ("impact", 5),
3426+ ("impact", 6),
3427+ ("impact", 7),
3428+ ("assess", "comments"),
3429+ )
3430+ form, form_accepted, assess_id = custom_assess(custom_assess_fields, location_id = irs_location_id)
3431+ else:
3432+ custom_assess_fields = (("assess", "location_id", "selector"),
3433+ ("impact", 1),
3434+ ("impact", 2),
3435+ ("impact", 3),
3436+ ("impact", 4),
3437+ ("impact", 5),
3438+ ("impact", 6),
3439+ ("impact", 7),
3440+ ("assess", "comments"),
3441+ )
3442+ form, form_accepted, assess_id = custom_assess(custom_assess_fields)
3443+
3444+
3445+
3446+ if form_accepted:
3447+ response.confirmation = T("Basic Assessment Reported")
3448+ redirect(URL(r = request, f = "assess", args = [assess_id, "impact"]))
3449+ return dict(title = T("Basic Assessment"),
3450+ location = location,
3451+ form = form)
3452+
3453+def mobile_basic_assess():
3454+ custom_assess_fields = (("assess", "location_id", "auto"),
3455+ ("impact", 1),
3456+ ("impact", 2),
3457+ ("impact", 3),
3458+ ("impact", 4),
3459+ ("impact", 5),
3460+ ("impact", 6),
3461+ ("impact", 7),
3462+ ("assess", "comments"),
3463+ )
3464+
3465+ form, form_accepted, assess_id = custom_assess(custom_assess_fields)
3466+
3467+ if form_accepted:
3468+ form = FORM(H1("Sahana Eden"),
3469+ H2(T("Short Assessment")),
3470+ P(T("Assessment Reported")),
3471+ A(T("Report Another Assessment..."),
3472+ _href = URL(r=request)
3473+ ),
3474+ _class = "mobile",
3475+ )
3476+ return dict(form = form)
3477+
3478+def color_code_severity_widget(widget, name):
3479+ for option, color in zip(widget, ["green", "yellow", "orange", "red"]):
3480+ option[0].__setitem__("_style", "background-color:%s;" % color)
3481+ option[0][0].__setitem__("_name", name)
3482+ return widget
3483+
3484+def custom_assess(custom_assess_fields, location_id = None):
3485+ """ Custom page to hide the complexity of the Assessments/Impacts/Summary model for a Mobile device """
3486+ form_row = []
3487+ comment = ""
3488+ for field in custom_assess_fields:
3489+ name = "custom_%s_%s" % (field[0], field[1])
3490+ id = name
3491+ if field[0] == "assess":
3492+ if field[1] == "comments":
3493+ label = "%s:" % db.assess_assess[ field[1] ].label
3494+ #widget = db.assess_assess[ field[1] ].widget
3495+ widget = TEXTAREA(_name = id,
3496+ _class = "double",
3497+ _type = "text")
3498+
3499+ elif field[1] == "location_id":
3500+ if field[2] == "auto":
3501+ #HTML5 Geo-Locate
3502+ label = "Location:"
3503+ #widget = db.assess_assess[ field[1] ].widget
3504+ widget = DIV(INPUT(_name = id,
3505+ _type = "text"),
3506+ INPUT(_name = "gis_location_lat",
3507+ _id = "gis_location_lat",
3508+ _type = "text"),
3509+ INPUT(_name = "gis_location_lon",
3510+ _id = "gis_location_lon",
3511+ _type = "text"))
3512+ else:
3513+ #Locaton Selector
3514+ label = "Location:"
3515+ widget = SELECT(_id = id,
3516+ _class = "reference gis_location",
3517+ _name = "location_id")
3518+ response.s3.gis.location_id = "custom_assess_location_id"
3519+ elif field[0] == "baseline":
3520+ label = shn_get_db_field_value(db = db,
3521+ table = "assess_baseline_type",
3522+ field = "name",
3523+ look_up = field[1]
3524+ )
3525+ widget = INPUT(_name = id,
3526+ _class = "double",
3527+ _type = "text")
3528+
3529+ elif field[0] == "impact":
3530+ label = "%s:" % shn_get_db_field_value(db = db,
3531+ table = "impact_type",
3532+ field = "name",
3533+ look_up = field[1]
3534+ )
3535+ value_widget = INPUT(_name = id,
3536+ _class = "double",
3537+ _type = "text")
3538+ severity_widget = db.assess_summary.value.widget(db.impact_impact.severity,
3539+ 0,
3540+ _name = name + "_severity"
3541+ )
3542+ severity_widget = color_code_severity_widget(severity_widget, name + "_severity")
3543+
3544+ widget = DIV(value_widget,
3545+ DIV(T("Severity:")),
3546+ severity_widget,
3547+ XML("&nbsp"))
3548+
3549+
3550+ elif field[0] == "summary":
3551+ label = "%s:" % shn_org_cluster_subsector_represent( field[1] )
3552+ widget = db.assess_summary.value.widget(db.assess_summary.value,
3553+ 0,
3554+ _name = name
3555+ )
3556+ widget = color_code_severity_widget(widget)
3557+
3558+ #Add the field components to the form_rows
3559+ if field[0] == "title":
3560+ form_row.append(TR(H3( field[1] )))
3561+ else:
3562+ form_row = form_row + list( s3_formstyle(id + "__row", label, widget, comment) )
3563+
3564+ form = FORM(TABLE(*form_row),
3565+ INPUT(_value = T("Save"),
3566+ _type = "submit"
3567+ ),
3568+ )
3569+ assess_id = None
3570+ if auth.is_logged_in():
3571+ form_accepted = form.accepts(request.vars, session)
3572+ if form_accepted:
3573+ record_dict = {"organisation_id" : session.s3.organisation_id}
3574+
3575+ #Add Assess (must happen first)
3576+ for field in custom_assess_fields:
3577+ if field[0] != "assess" or field[1] == "location":
3578+ continue
3579+ name = "custom__assess_%s" % field[1]
3580+ if name in request.vars:
3581+ record_dict[field[1]] = request.vars[name]
3582+ if "custom_assess_location_id" in request.vars:
3583+ #Auto
3584+ if "gis_location_lat" in request.vars:
3585+ location_dict = {}
3586+ location_dict["lat"] = request.vars["gis_location_lat"]
3587+ if "gis_location_lon" in request.vars:
3588+ location_dict["lon"] = request.vars["gis_location_lon"]
3589+ location_dict["name"] = request.vars["custom_assess_location_id"]
3590+ record_dict["location_id"] = db.gis_location.insert(**location_dict)
3591+ if "location_id" in request.vars:
3592+ #Location Select
3593+ record_dict["location_id"] = request.vars["location_id"]
3594+
3595+ if location_id:
3596+ #Location_id was passed to function
3597+ record_dict["location_id"] =location_id
3598+
3599+ assess_id = db.assess_assess.insert(**record_dict)
3600+
3601+ fk_dict = dict(baseline = "baseline_type_id",
3602+ impact = "impact_type_id",
3603+ summary = "cluster_subsector_id"
3604+ )
3605+
3606+ component_dict = dict(baseline = "assess_baseline",
3607+ impact = "impact_impact",
3608+ summary = "assess_summary"
3609+ )
3610+
3611+ # Add Assess Components
3612+ cluster_summary = {}
3613+ for field in custom_assess_fields:
3614+ if field[0] == "assess":
3615+ continue
3616+ record_dict = {}
3617+ name = "custom_%s_%s" % (field[0], field[1])
3618+ if name in request.vars:
3619+ record_dict["assess_id"] = assess_id
3620+ record_dict[fk_dict[ field[0] ] ] = field[1]
3621+ record_dict["value"] = request.vars[name]
3622+ if field[0] == "impact":
3623+ severity = int(request.vars[name + "_severity"])
3624+ record_dict["severity"] = severity
3625+
3626+ if not record_dict["value"] and not record_dict["severity"]:
3627+ #Do not record impact if there is no data for it.
3628+ #Should we still average severity though? Now not doing this
3629+ continue
3630+
3631+ #record the Severity per cluster
3632+ cluster_id = \
3633+ shn_get_db_field_value(db = db,
3634+ table = "impact_type",
3635+ field = "cluster_id",
3636+ look_up = field[1])
3637+ if cluster_id in cluster_summary.keys():
3638+ cluster_summary[cluster_id].append(severity)
3639+ elif cluster_id:
3640+ cluster_summary[cluster_id] = [severity]
3641+
3642+ db[component_dict[ field[0] ] ].insert(**record_dict)
3643+
3644+ #Add cluster summaries @TODO - make sure that this doesn't happen if there are clusters in the assess
3645+ for cluster_id in cluster_summary.keys():
3646+ severity_values = cluster_summary[cluster_id]
3647+ db.assess_summary.insert(assess_id = assess_id,
3648+ cluster_id = cluster_id,
3649+ #Average severity
3650+ value =sum(severity_values)/len(severity_values)
3651+ )
3652+
3653+ # Send Out Notification SMS
3654+ #message = "Sahana: " + T("New Assessment reported from") + " %s by %s %s" % ( location_dict["name"],
3655+ # session.auth.user.first_name,
3656+ # session.auth.user.last_name
3657+ # )
3658+ # Hard coded notification message for Demo
3659+ #msg.send_by_pe_id( 3,
3660+ # subject="",
3661+ # message=message,
3662+ # sender_pe_id = None,
3663+ # pr_message_method = 2,
3664+ # sender="",
3665+ # fromaddress="")
3666+
3667+ else:
3668+ redirect(URL(r=request, c = "default", f = "index"))
3669+
3670+ return form, form_accepted, assess_id
3671+
3672+#==============================================================================
3673+def assess_short_mobile():
3674+
3675+ """ Custom page to hide the complexity of the Assessments/Impacts/Summary model for a Mobile device """
3676+
3677+ assess_short_fields = (("assess", "location"),
3678+ ("baseline", 1),
3679+ ("baseline", 2),
3680+ ("baseline", 4),
3681+ ("baseline", 3),
3682+ ("impact", 3),
3683+ ("impact", 4),
3684+ ("title", "Cluster Indicators:"),
3685+ ("summary", 4),
3686+ ("summary", 3),
3687+ ("summary", 10),
3688+ ("summary", 11),
3689+ ("summary", 9),
3690+ ("assess", "comments"),
3691+ )
3692+ form_row = []
3693+ comment = ""
3694+ for field in assess_short_fields:
3695+ name = "assess_short_%s_%s" % (field[0], field[1])
3696+ id = name
3697+ if field[0] == "assess":
3698+ if field[1] == "comments":
3699+ label = "%s:" % db.assess_assess[ field[1] ].label
3700+ #widget = db.assess_assess[ field[1] ].widget
3701+ widget = TEXTAREA(_name = id,
3702+ _class = "double",
3703+ _type = "text")
3704+
3705+ elif field[1] == "location":
3706+ label = "Location:"
3707+ #widget = db.assess_assess[ field[1] ].widget
3708+ widget = DIV(INPUT(_name = id,
3709+ _type = "text"),
3710+ INPUT(_name = "gis_location_lat",
3711+ _id = "gis_location_lat",
3712+ _type = "text"),
3713+ INPUT(_name = "gis_location_lon",
3714+ _id = "gis_location_lon",
3715+ _type = "text"))
3716+
3717+ elif field[0] == "baseline":
3718+ label = shn_get_db_field_value(db = db,
3719+ table = "assess_baseline_type",
3720+ field = "name",
3721+ look_up = field[1]
3722+ )
3723+ widget = INPUT(_name = id,
3724+ _class = "double",
3725+ _type = "text")
3726+
3727+ elif field[0] == "impact":
3728+ label = "%s:" % shn_get_db_field_value(db = db,
3729+ table = "impact_type",
3730+ field = "name",
3731+ look_up = field[1]
3732+ )
3733+ widget = INPUT(_name = id,
3734+ _class = "double",
3735+ _type = "text")
3736+
3737+ elif field[0] == "summary":
3738+ label = "%s:" % shn_org_cluster_subsector_represent( field[1] )
3739+ widget = db.assess_summary.value.widget(db.assess_summary.value,
3740+ 0,
3741+ _name = name
3742+ )
3743+ for option, color in zip(widget, ["green", "yellow", "orange", "red"]):
3744+ option[0].__setitem__("_style", "background-color:%s;" % color)
3745+ option[0][0].__setitem__("_name", name)
3746+
3747+ #Add the field components to the form_rows
3748+ if field[0] == "title":
3749+ form_row.append(TR(H3( field[1] )))
3750+ else:
3751+ form_row = form_row + list( s3_formstyle(id, label, widget, comment) )
3752+
3753+ form = FORM(H1("Sahana Eden"),
3754+ H2(T("Short Assessment")),
3755+ TABLE(*form_row),
3756+ INPUT(_value = T("Save"),
3757+ _type = "submit"
3758+ ),
3759+ _class = "mobile",
3760+ )
3761+
3762+ if auth.is_logged_in():
3763+ if form.accepts(request.vars, session):
3764+ record_dict = {}
3765+
3766+ #Add Assess (must happen first)
3767+ for field in assess_short_fields:
3768+ if field[0] != "assess" or field[1] == "location":
3769+ continue
3770+ name = "assess_short_assess_%s" % field[1]
3771+ if name in request.vars:
3772+ record_dict[field[1]] = request.vars[name]
3773+ if "assess_short_assess_location" in request.vars:
3774+ location_dict = {}
3775+ location_dict["name"] = request.vars["assess_short_assess_location"]
3776+ if "gis_location_lat" in request.vars:
3777+ location_dict["lat"] = request.vars["gis_location_lat"]
3778+ if "gis_location_lon" in request.vars:
3779+ location_dict["lon"] = request.vars["gis_location_lon"]
3780+ location_id = db.gis_location.insert(**location_dict)
3781+ record_dict["location_id"] = location_id
3782+ assess_id = db.assess_assess.insert(**record_dict)
3783+
3784+ fk_dict = dict(baseline = "baseline_type_id",
3785+ impact = "impact_type_id",
3786+ summary = "cluster_subsector_id"
3787+ )
3788+
3789+ component_dict = dict(baseline = "assess_baseline",
3790+ impact = "impact_impact",
3791+ summary = "assess_summary"
3792+ )
3793+
3794+ # Add Assess Components
3795+ for field in assess_short_fields:
3796+ if field[0] == "assess":
3797+ continue
3798+ record_dict = {}
3799+ name = "assess_short_%s_%s" % (field[0], field[1])
3800+ if name in request.vars:
3801+ record_dict["assess_id"] = assess_id
3802+ record_dict[fk_dict[ field[0] ] ] = field[1]
3803+ record_dict["value"] = request.vars[name]
3804+ db[component_dict[ field[0] ] ].insert(**record_dict)
3805+
3806+ # Send Out Notification SMS
3807+ message = "Sahana: " + T("New Assessment reported from") + " %s by %s %s" % ( location_dict["name"],
3808+ session.auth.user.first_name,
3809+ session.auth.user.last_name
3810+ )
3811+ # Hard coded notification message for Demo
3812+ #msg.send_by_pe_id( 3,
3813+ # subject="",
3814+ # message=message,
3815+ # sender_pe_id = None,
3816+ # pr_message_method = 2,
3817+ # sender="",
3818+ # fromaddress="")
3819+
3820+ form = FORM(H1("Sahana Eden"),
3821+ H2(T("Short Assessment")),
3822+ P(T("Assessment Reported")),
3823+ A(T("Report Another Assessment..."),
3824+ _href = URL(r=request)
3825+ ),
3826+ _class = "mobile",
3827+ )
3828+ else:
3829+ redirect(URL(r=request, c = "default", f = "index"))
3830+
3831+ return dict(form = form)
3832+
3833+#==============================================================================
3834
3835=== removed file 'controllers/assess.py'
3836--- controllers/assess.py 2011-01-18 14:42:34 +0000
3837+++ controllers/assess.py 1970-01-01 00:00:00 +0000
3838@@ -1,789 +0,0 @@
3839-# -*- coding: utf-8 -*-
3840-
3841-""" Assessments - Controller
3842-
3843- @author: Fran Boon
3844- @author: Dominic König
3845- @author: Michael Howden (michael@sahanafoundation.org)
3846- @date-created: 2010-08-25
3847-
3848-"""
3849-
3850-prefix = request.controller
3851-resourcename = request.function
3852-
3853-if prefix not in deployment_settings.modules:
3854- session.error = T("Module disabled!")
3855- redirect(URL(r=request, c="default", f="index"))
3856-
3857-# Options Menu (available in all Functions' Views)
3858-def shn_menu():
3859- menu = [
3860- [T("Rapid Assessments"), False, aURL(r=request, f="rat"), [
3861- [T("List"), False, aURL(r=request, f="rat")],
3862- [T("Add"), False, aURL(p="create", r=request, f="rat", args="create")],
3863- #[T("Search"), False, URL(r=request, f="rat", args="search")],
3864- ]],
3865- [T("Impact Assessments"), False, aURL(r=request, f="assess"), [
3866- [T("List"), False, aURL(r=request, f="assess")],
3867- #[T("Add"), False, aURL(p="create", r=request, f="assess", args="create")],
3868- [T("Add"), False, aURL(r=request, f="basic_assess")],
3869- [T("Mobile"), False, aURL(r=request, f="mobile_basic_assess")],
3870- #[T("Search"), False, aURL(r=request, f="assess", args="search")],
3871- ]],
3872- ]
3873- if s3_has_role(1):
3874- menu_editor = [
3875- [T("Edit Options"), False, URL(r=request, f="#"), [
3876- [T("List / Add Baseline Types"), False, URL(r=request, f="baseline_type")],
3877- [T("List / Add Impact Types"), False, URL(r=request, f="impact_type")],
3878- ]],
3879- ]
3880- menu.extend(menu_editor)
3881- response.menu_options = menu
3882-
3883-shn_menu()
3884-
3885-#==============================================================================
3886-def index():
3887-
3888- """ Module's Home Page """
3889-
3890- module_name = deployment_settings.modules[prefix].name_nice
3891- response.title = module_name
3892- return dict(module_name=module_name)
3893-
3894-
3895-# -----------------------------------------------------------------------------
3896-def maps():
3897-
3898- """ Show a Map of all Rapid Assessments """
3899-
3900- reports = db(db.gis_location.id == db.assess_rat.location_id).select()
3901- report_popup_url = URL(r=request, f="rat", args="read.popup?rat.location_id=")
3902- map = gis.show_map(feature_queries = [{"name":T("Rapid Assessments"), "query":reports, "active":True, "popup_url": report_popup_url}], window=True)
3903-
3904- return dict(map=map)
3905-
3906-
3907-# -----------------------------------------------------------------------------
3908-def rat():
3909-
3910- """ Rapid Assessments, RESTful controller """
3911-
3912- tablename = "%s_%s" % (prefix, resourcename)
3913- table = db[tablename]
3914-
3915- # Don't send the locations list to client (pulled by AJAX instead)
3916- table.location_id.requires = IS_NULL_OR(IS_ONE_OF_EMPTY(db, "gis_location.id"))
3917-
3918- # Villages only
3919- #table.location_id.requires = IS_NULL_OR(IS_ONE_OF(db(db.gis_location.level == "L5"),
3920- # "gis_location.id",
3921- # repr_select, sort=True))
3922-
3923- # Pre-populate staff ID
3924- if auth.is_logged_in():
3925- staff_id = db((db.pr_person.uuid == session.auth.user.person_uuid) & \
3926- (db.org_staff.person_id == db.pr_person.id)).select(
3927- db.org_staff.id, limitby=(0, 1)).first()
3928- if staff_id:
3929- table.staff_id.default = staff_id.id
3930-
3931- # Subheadings in forms:
3932- s3xrc.model.configure(db.assess_section2,
3933- subheadings = {
3934- "Population and number of households": "population_total",
3935- "Fatalities": "dead_women",
3936- "Casualties": "injured_women",
3937- "Missing Persons": "missing_women",
3938- "General information on demographics": "household_head_elderly",
3939- "Comments": "comments"})
3940- s3xrc.model.configure(db.assess_section3,
3941- subheadings = {
3942- "Access to Shelter": "houses_total",
3943- "Water storage containers in households": "water_containers_available",
3944- "Other non-food items": "cooking_equipment_available",
3945- "Shelter/NFI Assistance": "nfi_assistance_available",
3946- "Comments": "comments"})
3947- s3xrc.model.configure(db.assess_section4,
3948- subheadings = {
3949- "Water supply": "water_source_pre_disaster_type",
3950- "Water collection": "water_coll_time",
3951- "Places for defecation": "defec_place_type",
3952- "Environment": "close_industry",
3953- "Latrines": "latrines_number",
3954- "Comments": "comments"})
3955- s3xrc.model.configure(db.assess_section5,
3956- subheadings = {
3957- "Health services status": "health_services_pre_disaster",
3958- "Current health problems": "health_problems_adults",
3959- "Nutrition problems": "malnutrition_present_pre_disaster",
3960- "Comments": "comments"})
3961- s3xrc.model.configure(db.assess_section6,
3962- subheadings = {
3963- "Existing food stocks": "food_stocks_main_dishes",
3964- "food_sources" : "Food sources",
3965- "Food assistance": "food_assistance_available",
3966- "Comments": "comments"})
3967- s3xrc.model.configure(db.assess_section7,
3968- subheadings = {
3969- "Sources of income / Major expenses": "income_sources_pre_disaster",
3970- "business_damaged" : "Access to cash",
3971- "Current community priorities": "rank_reconstruction_assistance",
3972- "Comments": "comments"})
3973- s3xrc.model.configure(db.assess_section8,
3974- subheadings = {
3975- "Access to education services": "schools_total",
3976- "Alternative places for studying": "alternative_study_places_available",
3977- "School activities": "schools_open_pre_disaster",
3978- "School attendance": "children_0612_female",
3979- "School assistance": "school_assistance_available",
3980- "Comments": "comments"})
3981- s3xrc.model.configure(db.assess_section9,
3982- subheadings = {
3983- "Physical Safety": "vulnerable_groups_safe_env",
3984- "Separated children, caregiving arrangements": "children_separated",
3985- "Persons in institutions": "children_in_disabled_homes",
3986- "Activities of children": "child_activities_u12f_pre_disaster",
3987- "Coping Activities": "coping_activities_elderly",
3988- "Current general needs": "current_general_needs",
3989- "Comments": "comments"})
3990-
3991- # @ToDo Generalize this and make it available as a function that other
3992- # component prep methods can call to set the default for a join field.
3993- def prep(r):
3994- if r.representation=="html" and r.http=="GET" and r.method=="create":
3995- # If this assessment is being created as a component of a shelter,
3996- # it will have the shelter id in its vars.
3997- shelter_id = r.request.get_vars.get("rat.shelter_id", None)
3998- if shelter_id:
3999- try:
4000- shelter_id = int(shelter_id)
4001- except ValueError:
4002- pass
4003- else:
4004- db.assess_rat.shelter_id.default = shelter_id
4005- # If this assessment is being created as a component of a document,
4006- # it will have the document id in its vars.
4007- document_id = r.request.get_vars.get("rat.document_id", None)
4008- if document_id:
4009- try:
4010- document_id = int(document_id)
4011- except ValueError:
4012- pass
4013- else:
4014- db.assess_rat.document_id.default = document_id
4015- return True
4016- response.s3.prep = prep
4017-
4018- # Post-processor
4019- def postp(r, output):
4020- shn_action_buttons(r, deletable=False)
4021- # Redirect to read/edit view rather than list view
4022- if r.representation == "html" and r.method == "create":
4023- r.next = r.other(method="",
4024- record_id=s3xrc.get_session("assess", "rat"))
4025- return output
4026- response.s3.postp = postp
4027-
4028- # Over-ride the listadd since we're not a component here
4029- s3xrc.model.configure(table, create_next="", listadd=True)
4030-
4031- rheader = lambda r: shn_rat_rheader(r,
4032- tabs = [(T("Identification"), None),
4033- (T("Demographic"), "section2"),
4034- (T("Shelter & Essential NFIs"), "section3"),
4035- (T("WatSan"), "section4"),
4036- (T("Health"), "section5"),
4037- (T("Nutrition"), "section6"),
4038- (T("Livelihood"), "section7"),
4039- (T("Education"), "section8"),
4040- (T("Protection"), "section9") ])
4041-
4042- output = s3_rest_controller(prefix, resourcename, rheader=rheader)
4043-
4044- response.extra_styles = ["S3/rat.css"]
4045- return output
4046-
4047-
4048-# -----------------------------------------------------------------------------
4049-def shn_rat_rheader(r, tabs=[]):
4050-
4051- """ Resource Headers """
4052-
4053- if r.representation == "html":
4054- if r.name == "rat":
4055- report = r.record
4056- if report:
4057- rheader_tabs = shn_rheader_tabs(r, tabs, paging=True)
4058- location = report.location_id
4059- if location:
4060- location = shn_gis_location_represent(location)
4061- staff = report.staff_id
4062- if staff:
4063- organisation_id = db(db.org_staff.id == staff).select(db.org_staff.organisation_id).first().organisation_id
4064- organisation = shn_organisation_represent(organisation_id)
4065- else:
4066- organisation = None
4067- staff = report.staff2_id
4068- if staff:
4069- organisation_id = db(db.org_staff.id == staff).select(db.org_staff.organisation_id).first().organisation_id
4070- organisation2 = shn_organisation_represent(organisation_id)
4071- else:
4072- organisation2 = None
4073- if organisation2:
4074- orgs = organisation + ", " + organisation2
4075- else:
4076- orgs = organisation
4077- doc_name = doc_url = None
4078- document = db(db.doc_document.id == report.document_id).select(db.doc_document.name, db.doc_document.file, limitby=(0, 1)).first()
4079- if document:
4080- doc_name = document.name
4081- doc_url = URL(r=request, c="default", f="download", args=[document.file])
4082- rheader = DIV(TABLE(
4083- TR(
4084- TH(T("Location") + ": "), location,
4085- TH(T("Date") + ": "), report.date
4086- ),
4087- TR(
4088- TH(T("Organizations") + ": "), orgs,
4089- TH(T("Document") + ": "), A(doc_name, _href=doc_url)
4090- )
4091- ),
4092- rheader_tabs)
4093-
4094- return rheader
4095- return None
4096-
4097-#==============================================================================
4098-# Flexible Impact Assessments
4099-#==============================================================================
4100-def shn_assess_rheader(r, tabs=[]):
4101-
4102- """ Resource Headers for Flexible Impact Assessments """
4103-
4104- if r.representation == "html":
4105-
4106- rheader_tabs = shn_rheader_tabs(r, tabs)
4107-
4108- assess = r.record
4109-
4110- if assess:
4111- rheader = DIV(TABLE(TR(
4112- TH(T("Date & Time") + ": "), assess.datetime,
4113- TH(T("Location") + ": "), shn_gis_location_represent(assess.location_id),
4114- TH(T("Assessor") + ": "), shn_pr_person_represent(assess.assessor_person_id),
4115- ),
4116- ),
4117- rheader_tabs
4118- )
4119- return rheader
4120-
4121- return None
4122-
4123-
4124-#==============================================================================
4125-def assess():
4126-
4127- """ RESTful CRUD controller """
4128-
4129- tablename = "%s_%s" % (prefix, resourcename)
4130- table = db[tablename]
4131-
4132- # Pre-processor
4133- def shn_assess_prep(r):
4134- if session.s3.mobile and r.method == "create" and r.representation in shn_interactive_view_formats:
4135- # redirect to mobile-specific form:
4136- redirect(URL(r=request, f="assess_short_mobile"))
4137- return True
4138- response.s3.prep = shn_assess_prep
4139-
4140- table.incident_id.comment = DIV(_class="tooltip",
4141- _title=T("Incident") + "|" + T("Optional link to an Incident which this Assessment was triggered by."))
4142-
4143- tabs = [
4144- (T("Edit Details"), None),
4145- (T("Baselines"), "baseline"),
4146- (T("Impacts"), "impact"),
4147- (T("Summary"), "summary"),
4148- #(T("Requested"), "ritem"),
4149- ]
4150-
4151- rheader = lambda r: shn_assess_rheader(r, tabs)
4152-
4153- return s3_rest_controller(prefix, resourcename, rheader=rheader)
4154-
4155-
4156-#==============================================================================
4157-def impact_type():
4158-
4159- """ RESTful CRUD controller """
4160-
4161- prefix = "impact"
4162- resourcename = "type"
4163-
4164- tablename = "%s_%s" % (prefix, resourcename)
4165- table = db[tablename]
4166-
4167- return s3_rest_controller(prefix, resourcename)
4168-
4169-
4170-#==============================================================================
4171-def baseline_type():
4172-
4173- """ RESTful CRUD controller """
4174-
4175- tablename = "%s_%s" % (prefix, resourcename)
4176- table = db[tablename]
4177-
4178- return s3_rest_controller(prefix, resourcename)
4179-
4180-
4181-#==============================================================================
4182-def baseline():
4183-
4184- """ RESTful CRUD controller """
4185-
4186- tablename = "%s_%s" % (prefix, resourcename)
4187- table = db[tablename]
4188-
4189- return s3_rest_controller(prefix, resourcename)
4190-
4191-
4192-#==============================================================================
4193-def summary():
4194-
4195- """ RESTful CRUD controller """
4196-
4197- tablename = "%s_%s" % (prefix, resourcename)
4198- table = db[tablename]
4199-
4200- return s3_rest_controller(prefix, resourcename)
4201-
4202-
4203-#==============================================================================
4204-def basic_assess():
4205- ireport_id = request.vars.get("ireport_id")
4206- location = None
4207- if incident_id:
4208- irs_location_id = shn_get_db_field_value(db = db,
4209- table = "irs_ireport",
4210- field = "location_id",
4211- look_up = ireport_id
4212- )
4213- location = shn_gis_location_represent(irs_location_id)
4214- custom_assess_fields = (
4215- ("impact", 1),
4216- ("impact", 2),
4217- ("impact", 3),
4218- ("impact", 4),
4219- ("impact", 5),
4220- ("impact", 6),
4221- ("impact", 7),
4222- ("assess", "comments"),
4223- )
4224- form, form_accepted, assess_id = custom_assess(custom_assess_fields, location_id = irs_location_id)
4225- else:
4226- custom_assess_fields = (("assess", "location_id", "selector"),
4227- ("impact", 1),
4228- ("impact", 2),
4229- ("impact", 3),
4230- ("impact", 4),
4231- ("impact", 5),
4232- ("impact", 6),
4233- ("impact", 7),
4234- ("assess", "comments"),
4235- )
4236- form, form_accepted, assess_id = custom_assess(custom_assess_fields)
4237-
4238-
4239-
4240- if form_accepted:
4241- response.confirmation = T("Basic Assessment Reported")
4242- redirect(URL(r = request, f = "assess", args = [assess_id, "impact"]))
4243- return dict(title = T("Basic Assessment"),
4244- location = location,
4245- form = form)
4246-
4247-def mobile_basic_assess():
4248- custom_assess_fields = (("assess", "location_id", "auto"),
4249- ("impact", 1),
4250- ("impact", 2),
4251- ("impact", 3),
4252- ("impact", 4),
4253- ("impact", 5),
4254- ("impact", 6),
4255- ("impact", 7),
4256- ("assess", "comments"),
4257- )
4258-
4259- form, form_accepted, assess_id = custom_assess(custom_assess_fields)
4260-
4261- if form_accepted:
4262- form = FORM(H1("Sahana Eden"),
4263- H2(T("Short Assessment")),
4264- P(T("Assessment Reported")),
4265- A(T("Report Another Assessment..."),
4266- _href = URL(r=request)
4267- ),
4268- _class = "mobile",
4269- )
4270- return dict(form = form)
4271-
4272-def color_code_severity_widget(widget, name):
4273- for option, color in zip(widget, ["green", "yellow", "orange", "red"]):
4274- option[0].__setitem__("_style", "background-color:%s;" % color)
4275- option[0][0].__setitem__("_name", name)
4276- return widget
4277-
4278-def custom_assess(custom_assess_fields, location_id = None):
4279- """ Custom page to hide the complexity of the Assessments/Impacts/Summary model for a Mobile device """
4280- form_row = []
4281- comment = ""
4282- for field in custom_assess_fields:
4283- name = "custom_%s_%s" % (field[0], field[1])
4284- id = name
4285- if field[0] == "assess":
4286- if field[1] == "comments":
4287- label = "%s:" % db.assess_assess[ field[1] ].label
4288- #widget = db.assess_assess[ field[1] ].widget
4289- widget = TEXTAREA(_name = id,
4290- _class = "double",
4291- _type = "text")
4292-
4293- elif field[1] == "location_id":
4294- if field[2] == "auto":
4295- #HTML5 Geo-Locate
4296- label = "Location:"
4297- #widget = db.assess_assess[ field[1] ].widget
4298- widget = DIV(INPUT(_name = id,
4299- _type = "text"),
4300- INPUT(_name = "gis_location_lat",
4301- _id = "gis_location_lat",
4302- _type = "text"),
4303- INPUT(_name = "gis_location_lon",
4304- _id = "gis_location_lon",
4305- _type = "text"))
4306- else:
4307- #Locaton Selector
4308- label = "Location:"
4309- widget = SELECT(_id = id,
4310- _class = "reference gis_location",
4311- _name = "location_id")
4312- response.s3.gis.location_id = "custom_assess_location_id"
4313- elif field[0] == "baseline":
4314- label = shn_get_db_field_value(db = db,
4315- table = "assess_baseline_type",
4316- field = "name",
4317- look_up = field[1]
4318- )
4319- widget = INPUT(_name = id,
4320- _class = "double",
4321- _type = "text")
4322-
4323- elif field[0] == "impact":
4324- label = "%s:" % shn_get_db_field_value(db = db,
4325- table = "impact_type",
4326- field = "name",
4327- look_up = field[1]
4328- )
4329- value_widget = INPUT(_name = id,
4330- _class = "double",
4331- _type = "text")
4332- severity_widget = db.assess_summary.value.widget(db.impact_impact.severity,
4333- 0,
4334- _name = name + "_severity"
4335- )
4336- severity_widget = color_code_severity_widget(severity_widget, name + "_severity")
4337-
4338- widget = DIV(value_widget,
4339- DIV(T("Severity:")),
4340- severity_widget,
4341- XML("&nbsp"))
4342-
4343-
4344- elif field[0] == "summary":
4345- label = "%s:" % shn_org_cluster_subsector_represent( field[1] )
4346- widget = db.assess_summary.value.widget(db.assess_summary.value,
4347- 0,
4348- _name = name
4349- )
4350- widget = color_code_severity_widget(widget)
4351-
4352- #Add the field components to the form_rows
4353- if field[0] == "title":
4354- form_row.append(TR(H3( field[1] )))
4355- else:
4356- form_row = form_row + list( s3_formstyle(id + "__row", label, widget, comment) )
4357-
4358- form = FORM(TABLE(*form_row),
4359- INPUT(_value = T("Save"),
4360- _type = "submit"
4361- ),
4362- )
4363- assess_id = None
4364- if auth.is_logged_in():
4365- form_accepted = form.accepts(request.vars, session)
4366- if form_accepted:
4367- record_dict = {"organisation_id" : session.s3.organisation_id}
4368-
4369- #Add Assess (must happen first)
4370- for field in custom_assess_fields:
4371- if field[0] != "assess" or field[1] == "location":
4372- continue
4373- name = "custom__assess_%s" % field[1]
4374- if name in request.vars:
4375- record_dict[field[1]] = request.vars[name]
4376- if "custom_assess_location_id" in request.vars:
4377- #Auto
4378- if "gis_location_lat" in request.vars:
4379- location_dict = {}
4380- location_dict["lat"] = request.vars["gis_location_lat"]
4381- if "gis_location_lon" in request.vars:
4382- location_dict["lon"] = request.vars["gis_location_lon"]
4383- location_dict["name"] = request.vars["custom_assess_location_id"]
4384- record_dict["location_id"] = db.gis_location.insert(**location_dict)
4385- if "location_id" in request.vars:
4386- #Location Select
4387- record_dict["location_id"] = request.vars["location_id"]
4388-
4389- if location_id:
4390- #Location_id was passed to function
4391- record_dict["location_id"] =location_id
4392-
4393- assess_id = db.assess_assess.insert(**record_dict)
4394-
4395- fk_dict = dict(baseline = "baseline_type_id",
4396- impact = "impact_type_id",
4397- summary = "cluster_subsector_id"
4398- )
4399-
4400- component_dict = dict(baseline = "assess_baseline",
4401- impact = "impact_impact",
4402- summary = "assess_summary"
4403- )
4404-
4405- # Add Assess Components
4406- cluster_summary = {}
4407- for field in custom_assess_fields:
4408- if field[0] == "assess":
4409- continue
4410- record_dict = {}
4411- name = "custom_%s_%s" % (field[0], field[1])
4412- if name in request.vars:
4413- record_dict["assess_id"] = assess_id
4414- record_dict[fk_dict[ field[0] ] ] = field[1]
4415- record_dict["value"] = request.vars[name]
4416- if field[0] == "impact":
4417- severity = int(request.vars[name + "_severity"])
4418- record_dict["severity"] = severity
4419-
4420- if not record_dict["value"] and not record_dict["severity"]:
4421- #Do not record impact if there is no data for it.
4422- #Should we still average severity though? Now not doing this
4423- continue
4424-
4425- #record the Severity per cluster
4426- cluster_id = \
4427- shn_get_db_field_value(db = db,
4428- table = "impact_type",
4429- field = "cluster_id",
4430- look_up = field[1])
4431- if cluster_id in cluster_summary.keys():
4432- cluster_summary[cluster_id].append(severity)
4433- elif cluster_id:
4434- cluster_summary[cluster_id] = [severity]
4435-
4436- db[component_dict[ field[0] ] ].insert(**record_dict)
4437-
4438- #Add cluster summaries @TODO - make sure that this doesn't happen if there are clusters in the assess
4439- for cluster_id in cluster_summary.keys():
4440- severity_values = cluster_summary[cluster_id]
4441- db.assess_summary.insert(assess_id = assess_id,
4442- cluster_id = cluster_id,
4443- #Average severity
4444- value =sum(severity_values)/len(severity_values)
4445- )
4446-
4447- # Send Out Notification SMS
4448- #message = "Sahana: " + T("New Assessment reported from") + " %s by %s %s" % ( location_dict["name"],
4449- # session.auth.user.first_name,
4450- # session.auth.user.last_name
4451- # )
4452- # Hard coded notification message for Demo
4453- #msg.send_by_pe_id( 3,
4454- # subject="",
4455- # message=message,
4456- # sender_pe_id = None,
4457- # pr_message_method = 2,
4458- # sender="",
4459- # fromaddress="")
4460-
4461- else:
4462- redirect(URL(r=request, c = "default", f = "index"))
4463-
4464- return form, form_accepted, assess_id
4465-
4466-#==============================================================================
4467-def assess_short_mobile():
4468-
4469- """ Custom page to hide the complexity of the Assessments/Impacts/Summary model for a Mobile device """
4470-
4471- assess_short_fields = (("assess", "location"),
4472- ("baseline", 1),
4473- ("baseline", 2),
4474- ("baseline", 4),
4475- ("baseline", 3),
4476- ("impact", 3),
4477- ("impact", 4),
4478- ("title", "Cluster Indicators:"),
4479- ("summary", 4),
4480- ("summary", 3),
4481- ("summary", 10),
4482- ("summary", 11),
4483- ("summary", 9),
4484- ("assess", "comments"),
4485- )
4486- form_row = []
4487- comment = ""
4488- for field in assess_short_fields:
4489- name = "assess_short_%s_%s" % (field[0], field[1])
4490- id = name
4491- if field[0] == "assess":
4492- if field[1] == "comments":
4493- label = "%s:" % db.assess_assess[ field[1] ].label
4494- #widget = db.assess_assess[ field[1] ].widget
4495- widget = TEXTAREA(_name = id,
4496- _class = "double",
4497- _type = "text")
4498-
4499- elif field[1] == "location":
4500- label = "Location:"
4501- #widget = db.assess_assess[ field[1] ].widget
4502- widget = DIV(INPUT(_name = id,
4503- _type = "text"),
4504- INPUT(_name = "gis_location_lat",
4505- _id = "gis_location_lat",
4506- _type = "text"),
4507- INPUT(_name = "gis_location_lon",
4508- _id = "gis_location_lon",
4509- _type = "text"))
4510-
4511- elif field[0] == "baseline":
4512- label = shn_get_db_field_value(db = db,
4513- table = "assess_baseline_type",
4514- field = "name",
4515- look_up = field[1]
4516- )
4517- widget = INPUT(_name = id,
4518- _class = "double",
4519- _type = "text")
4520-
4521- elif field[0] == "impact":
4522- label = "%s:" % shn_get_db_field_value(db = db,
4523- table = "impact_type",
4524- field = "name",
4525- look_up = field[1]
4526- )
4527- widget = INPUT(_name = id,
4528- _class = "double",
4529- _type = "text")
4530-
4531- elif field[0] == "summary":
4532- label = "%s:" % shn_org_cluster_subsector_represent( field[1] )
4533- widget = db.assess_summary.value.widget(db.assess_summary.value,
4534- 0,
4535- _name = name
4536- )
4537- for option, color in zip(widget, ["green", "yellow", "orange", "red"]):
4538- option[0].__setitem__("_style", "background-color:%s;" % color)
4539- option[0][0].__setitem__("_name", name)
4540-
4541- #Add the field components to the form_rows
4542- if field[0] == "title":
4543- form_row.append(TR(H3( field[1] )))
4544- else:
4545- form_row = form_row + list( s3_formstyle(id, label, widget, comment) )
4546-
4547- form = FORM(H1("Sahana Eden"),
4548- H2(T("Short Assessment")),
4549- TABLE(*form_row),
4550- INPUT(_value = T("Save"),
4551- _type = "submit"
4552- ),
4553- _class = "mobile",
4554- )
4555-
4556- if auth.is_logged_in():
4557- if form.accepts(request.vars, session):
4558- record_dict = {}
4559-
4560- #Add Assess (must happen first)
4561- for field in assess_short_fields:
4562- if field[0] != "assess" or field[1] == "location":
4563- continue
4564- name = "assess_short_assess_%s" % field[1]
4565- if name in request.vars:
4566- record_dict[field[1]] = request.vars[name]
4567- if "assess_short_assess_location" in request.vars:
4568- location_dict = {}
4569- location_dict["name"] = request.vars["assess_short_assess_location"]
4570- if "gis_location_lat" in request.vars:
4571- location_dict["lat"] = request.vars["gis_location_lat"]
4572- if "gis_location_lon" in request.vars:
4573- location_dict["lon"] = request.vars["gis_location_lon"]
4574- location_id = db.gis_location.insert(**location_dict)
4575- record_dict["location_id"] = location_id
4576- assess_id = db.assess_assess.insert(**record_dict)
4577-
4578- fk_dict = dict(baseline = "baseline_type_id",
4579- impact = "impact_type_id",
4580- summary = "cluster_subsector_id"
4581- )
4582-
4583- component_dict = dict(baseline = "assess_baseline",
4584- impact = "impact_impact",
4585- summary = "assess_summary"
4586- )
4587-
4588- # Add Assess Components
4589- for field in assess_short_fields:
4590- if field[0] == "assess":
4591- continue
4592- record_dict = {}
4593- name = "assess_short_%s_%s" % (field[0], field[1])
4594- if name in request.vars:
4595- record_dict["assess_id"] = assess_id
4596- record_dict[fk_dict[ field[0] ] ] = field[1]
4597- record_dict["value"] = request.vars[name]
4598- db[component_dict[ field[0] ] ].insert(**record_dict)
4599-
4600- # Send Out Notification SMS
4601- message = "Sahana: " + T("New Assessment reported from") + " %s by %s %s" % ( location_dict["name"],
4602- session.auth.user.first_name,
4603- session.auth.user.last_name
4604- )
4605- # Hard coded notification message for Demo
4606- #msg.send_by_pe_id( 3,
4607- # subject="",
4608- # message=message,
4609- # sender_pe_id = None,
4610- # pr_message_method = 2,
4611- # sender="",
4612- # fromaddress="")
4613-
4614- form = FORM(H1("Sahana Eden"),
4615- H2(T("Short Assessment")),
4616- P(T("Assessment Reported")),
4617- A(T("Report Another Assessment..."),
4618- _href = URL(r=request)
4619- ),
4620- _class = "mobile",
4621- )
4622- else:
4623- redirect(URL(r=request, c = "default", f = "index"))
4624-
4625- return dict(form = form)
4626-
4627-#==============================================================================
4628
4629=== added file 'controllers/auth.py'
4630--- controllers/auth.py 1970-01-01 00:00:00 +0000
4631+++ controllers/auth.py 2011-01-24 22:41:50 +0000
4632@@ -0,0 +1,20 @@
4633+# -*- coding: utf-8 -*-
4634+
4635+"""
4636+ Auth Controllers
4637+"""
4638+
4639+def user():
4640+ "Defined in admin module, so redirect there"
4641+
4642+ redirect(URL(r=request, c="admin", args=request.args, vars=request.vars))
4643+
4644+def group():
4645+ "Defined in admin module, so redirect there"
4646+
4647+ redirect(URL(r=request, c="admin", args=request.args, vars=request.vars))
4648+
4649+def membership():
4650+ "Defined in admin module, so redirect there"
4651+
4652+ redirect(URL(r=request, c="admin", args=request.args, vars=request.vars))
4653
4654=== removed file 'controllers/auth.py'
4655--- controllers/auth.py 2010-06-24 22:07:18 +0000
4656+++ controllers/auth.py 1970-01-01 00:00:00 +0000
4657@@ -1,20 +0,0 @@
4658-# -*- coding: utf-8 -*-
4659-
4660-"""
4661- Auth Controllers
4662-"""
4663-
4664-def user():
4665- "Defined in admin module, so redirect there"
4666-
4667- redirect(URL(r=request, c="admin", args=request.args, vars=request.vars))
4668-
4669-def group():
4670- "Defined in admin module, so redirect there"
4671-
4672- redirect(URL(r=request, c="admin", args=request.args, vars=request.vars))
4673-
4674-def membership():
4675- "Defined in admin module, so redirect there"
4676-
4677- redirect(URL(r=request, c="admin", args=request.args, vars=request.vars))
4678
4679=== added file 'controllers/budget.py'
4680--- controllers/budget.py 1970-01-01 00:00:00 +0000
4681+++ controllers/budget.py 2011-01-24 22:41:50 +0000
4682@@ -0,0 +1,1468 @@
4683+# -*- coding: utf-8 -*-
4684+
4685+"""
4686+ Budgetting Module - Controllers
4687+"""
4688+
4689+module = request.controller
4690+resourcename = request.function
4691+
4692+# Requires 'project' module too
4693+if module not in deployment_settings.modules or not deployment_settings.has_module("project"):
4694+ session.error = T("Module disabled!")
4695+ redirect(URL(r=request, c="default", f="index"))
4696+
4697+# Options Menu (available in all Functions' Views)
4698+response.menu_options = [
4699+ [T("Parameters"), False, URL(r=request, f="parameters")],
4700+ [T("Items"), False, URL(r=request, f="item"), [
4701+ [T("List"), False, URL(r=request, f="item")],
4702+ [T("Add"), False, URL(r=request, f="item", args="create")],
4703+ ]],
4704+ [T("Kits"), False, URL(r=request, f="kit"), [
4705+ [T("List"), False, URL(r=request, f="kit")],
4706+ [T("Add"), False, URL(r=request, f="kit", args="create")],
4707+ ]],
4708+ [T("Bundles"), False, URL(r=request, f="bundle"), [
4709+ [T("List"), False, URL(r=request, f="bundle")],
4710+ [T("Add"), False, URL(r=request, f="bundle", args="create")],
4711+ ]],
4712+ [T("Staff"), False, URL(r=request, f="staff"), [
4713+ [T("List"), False, URL(r=request, f="staff")],
4714+ [T("Add"), False, URL(r=request, f="staff", args="create")],
4715+ ]],
4716+ [T("Locations"), False, URL(r=request, f="location"), [
4717+ [T("List"), False, URL(r=request, f="location")],
4718+ [T("Add"), False, URL(r=request, f="location", args="create")],
4719+ ]],
4720+ [T("Projects"), False, URL(r=request, f="project"), [
4721+ [T("List"), False, URL(r=request, f="project")],
4722+ [T("Add"), False, URL(r=request, f="project", args="create")],
4723+ ]],
4724+ [T("Budgets"), False, URL(r=request, f="budget"), [
4725+ [T("List"), False, URL(r=request, f="budget")],
4726+ [T("Add"), False, URL(r=request, f="budget", args="create")],
4727+ ]]
4728+]
4729+
4730+# Options used in multiple functions
4731+table = db.budget_item
4732+table.code.label = T("Code")
4733+table.description.label = T("Description")
4734+table.unit_cost.label = T("Unit Cost")
4735+table.monthly_cost.label = T("Monthly Cost")
4736+table.minute_cost.label = T("Cost per Minute")
4737+table.megabyte_cost.label = T("Cost per Megabyte")
4738+table.comments.label = T("Comments")
4739+
4740+table = db.budget_kit
4741+table.code.label = T("Code")
4742+table.description.label = T("Description")
4743+table.total_unit_cost.label = T("Total Unit Cost")
4744+table.total_monthly_cost.label = T("Total Monthly Cost")
4745+table.total_minute_cost.label = T("Total Cost per Minute")
4746+table.total_megabyte_cost.label = T("Total Cost per Megabyte")
4747+table.comments.label = T("Comments")
4748+
4749+table = db.budget_kit_item
4750+table.kit_id.label = T("Kit")
4751+table.kit_id.represent = lambda kit_id: db(db.budget_kit.id == kit_id).select(db.budget_kit.code, limitby=(0, 1)).first().code
4752+table.item_id.label = T("Item")
4753+table.item_id.represent = lambda item_id: db(db.budget_item.id == item_id).select(db.budget_item.description, limitby=(0, 1)).first().description
4754+table.quantity.label = T("Quantity")
4755+
4756+table = db.budget_bundle
4757+table.name.label = T("Name")
4758+table.description.label = T("Description")
4759+table.total_unit_cost.label = T("One time cost")
4760+table.total_monthly_cost.label = T("Recurring cost")
4761+table.comments.label = T("Comments")
4762+
4763+table = db.budget_bundle_kit
4764+table.bundle_id.label = T("Bundle")
4765+table.bundle_id.represent = lambda bundle_id: db(db.budget_bundle.id == bundle_id).select(db.budget_bundle.description, limitby=(0, 1)).first().description
4766+table.kit_id.label = T("Kit")
4767+table.kit_id.represent = lambda kit_id: db(db.budget_kit.id == kit_id).select(db.budget_kit.code, limitby=(0, 1)).first().code
4768+table.quantity.label = T("Quantity")
4769+table.minutes.label = T("Minutes per Month")
4770+table.megabytes.label = T("Megabytes per Month")
4771+
4772+table = db.budget_bundle_item
4773+table.bundle_id.label = T("Bundle")
4774+table.bundle_id.represent = lambda bundle_id: db(db.budget_bundle.id == bundle_id).select(db.budget_bundle.description, limitby=(0, 1)).first().description
4775+table.item_id.label = T("Item")
4776+table.item_id.represent = lambda item_id: db(db.budget_item.id == item_id).select(db.budget_item.description, limitby=(0, 1)).first().description
4777+table.quantity.label = T("Quantity")
4778+table.minutes.label = T("Minutes per Month")
4779+table.megabytes.label = T("Megabytes per Month")
4780+
4781+table = db.budget_staff
4782+table.name.label = T("Name")
4783+table.grade.label = T("Grade")
4784+table.salary.label = T("Monthly Salary")
4785+table.travel.label = T("Travel Cost")
4786+table.comments.label = T("Comments")
4787+
4788+table = db.budget_location
4789+table.code.label = T("Code")
4790+table.description.label = T("Description")
4791+table.subsistence.label = T("Subsistence Cost")
4792+# UN terminology
4793+#table.subsistence.label = "DSA"
4794+table.hazard_pay.label = T("Hazard Pay")
4795+table.comments.label = T("Comments")
4796+
4797+#table = db.budget_project
4798+#table.code.label = T("Code")
4799+#table.title.label = T("Title")
4800+#table.comments.label = T("Comments")
4801+
4802+table = db.budget_budget
4803+table.name.label = T("Name")
4804+table.description.label = T("Description")
4805+table.total_onetime_costs.label = T("Total One-time Costs")
4806+table.total_recurring_costs.label = T("Total Recurring Costs")
4807+table.comments.label = T("Comments")
4808+
4809+table = db.budget_budget_bundle
4810+table.budget_id.label = T("Budget")
4811+table.budget_id.represent = lambda budget_id: db(db.budget_budget.id == budget_id).select(db.budget_budget.name, limitby=(0, 1)).first().name
4812+#table.project_id.label = T("Project")
4813+#table.project_id.represent = lambda project_id: db(db.budget_project.id == project_id).select(db.budget_project.code, limitby=(0, 1)).first().code
4814+table.location_id.label = T("Location")
4815+table.location_id.represent = lambda location_id: db(db.budget_location.id == location_id).select(db.budget_location.code, limitby=(0, 1)).first().code
4816+table.bundle_id.label = T("Bundle")
4817+table.bundle_id.represent = lambda bundle_id: db(db.budget_bundle.id == bundle_id).select(db.budget_bundle.name, limitby=(0, 1)).first().name
4818+table.quantity.label = T("Quantity")
4819+table.months.label = T("Months")
4820+
4821+table = db.budget_budget_staff
4822+table.budget_id.label = T("Budget")
4823+table.budget_id.represent = lambda budget_id: db(db.budget_budget.id == budget_id).select(db.budget_budget.name, limitby=(0, 1)).first().name
4824+#table.project_id.label = T("Project")
4825+#table.project_id.represent = lambda project_id: db(db.budget_project.id == project_id).select(db.budget_project.code, limitby=(0, 1)).first().code
4826+table.location_id.label = T("Location")
4827+table.location_id.represent = lambda location_id: db(db.budget_location.id == location_id).select(db.budget_location.code, limitby=(0, 1)).first().code
4828+table.staff_id.label = T("Staff")
4829+table.staff_id.represent = lambda bundle_id: db(db.budget_staff.id == staff_id).select(db.budget_staff.description, limitby=(0, 1)).first().description
4830+table.quantity.label = T("Quantity")
4831+table.months.label = T("Months")
4832+
4833+# S3 framework functions
4834+def index():
4835+ "Module's Home Page"
4836+
4837+ module_name = deployment_settings.modules[module].name_nice
4838+ response.title = module_name
4839+ return dict(module_name=module_name)
4840+
4841+def parameters():
4842+ "Select which page to go to depending on login status"
4843+ table = db.budget_parameter
4844+ authorised = s3_has_permission("update", table)
4845+ if authorised:
4846+ redirect (URL(r=request, f="parameter", args=[1, "update"]))
4847+ else:
4848+ redirect (URL(r=request, f="parameter", args=[1, "read"]))
4849+
4850+def parameter():
4851+
4852+ """ RESTful CRUD controller """
4853+
4854+ tablename = module + "_" + resourcename
4855+ table = db[tablename]
4856+
4857+ # Model Options
4858+ table.shipping.label = "Shipping cost"
4859+ table.logistics.label = "Procurement & Logistics cost"
4860+ table.admin.label = "Administrative support cost"
4861+ table.indirect.label = "Indirect support cost HQ"
4862+
4863+ # CRUD Strings
4864+ s3.crud_strings[tablename] = Storage(
4865+ title_update = T("Edit Parameters"),
4866+ title_display = T("Parameters"))
4867+
4868+ s3xrc.model.configure(table, deletable=False)
4869+ return s3_rest_controller(module, resourcename)
4870+
4871+def item():
4872+ """ RESTful CRUD controller """
4873+ tablename = module + "_" + resourcename
4874+ table = db[tablename]
4875+
4876+ # Model options used in multiple controllers so defined at the top of the file
4877+
4878+ # CRUD Strings
4879+ ADD_ITEM = T("Add Item")
4880+ LIST_ITEMS = T("List Items")
4881+ s3.crud_strings[tablename] = Storage(
4882+ title_create = ADD_ITEM,
4883+ title_display = T("Item Details"),
4884+ title_list = LIST_ITEMS,
4885+ title_update = T("Edit Item"),
4886+ title_search = T("Search Items"),
4887+ subtitle_create = T("Add New Item"),
4888+ subtitle_list = T("Items"),
4889+ label_list_button = LIST_ITEMS,
4890+ label_create_button = ADD_ITEM,
4891+ label_delete_button = T("Delete Item"),
4892+ label_search_button = T("Search Items"),
4893+ msg_record_created = T("Item added"),
4894+ msg_record_modified = T("Item updated"),
4895+ msg_record_deleted = T("Item deleted"),
4896+ msg_list_empty = T("No Items currently registered"))
4897+
4898+ response.s3.formats.pdf = URL(r=request, f="item_export_pdf")
4899+
4900+ s3xrc.model.configure(table,
4901+ main="code",
4902+ extra="description",
4903+ orderby=db.budget_item.category_type)
4904+
4905+ return s3_rest_controller(module, resourcename)
4906+
4907+def item_export_pdf():
4908+ """
4909+ Export a list of Items in Adobe PDF format
4910+ Uses Geraldo Grouping Report
4911+ """
4912+ try:
4913+ from reportlab.lib.units import cm
4914+ from reportlab.lib.pagesizes import A4
4915+ from reportlab.lib.enums import TA_CENTER, TA_RIGHT
4916+ except ImportError:
4917+ session.error = REPORTLAB_ERROR
4918+ redirect(URL(r=request, c="item"))
4919+ try:
4920+ from geraldo import Report, ReportBand, ReportGroup, Label, ObjectValue, SystemField, landscape, BAND_WIDTH
4921+ from geraldo.generators import PDFGenerator
4922+ except ImportError:
4923+ session.error = GERALDO_ERROR
4924+ redirect(URL(r=request, c="item"))
4925+
4926+ table = db.budget_item
4927+ objects_list = db(table.id > 0).select(orderby=table.category_type)
4928+ if not objects_list:
4929+ session.warning = T("No data in this table - cannot create PDF!")
4930+ redirect(URL(r=request, f="item"))
4931+
4932+ import StringIO
4933+ output = StringIO.StringIO()
4934+
4935+ class MyReport(Report):
4936+ def __init__(self, queryset=None, T=None):
4937+ " Initialise parent class & make any necessary modifications "
4938+ Report.__init__(self, queryset)
4939+ self.T = T
4940+ def _T(self, rawstring):
4941+ return self.T(rawstring)
4942+ # can't use T() here!
4943+ #title = _T("Items")
4944+ title = "Items"
4945+ page_size = landscape(A4)
4946+ class band_page_header(ReportBand):
4947+ height = 1.3*cm
4948+ elements = [
4949+ SystemField(expression="%(report_title)s", top=0.1*cm,
4950+ left=0, width=BAND_WIDTH, style={"fontName": "Helvetica-Bold",
4951+ "fontSize": 14, "alignment": TA_CENTER}
4952+ ),
4953+ Label(text="Code", top=0.8*cm, left=0.2*cm),
4954+ Label(text="Description", top=0.8*cm, left=3*cm),
4955+ Label(text="Unit Cost", top=0.8*cm, left=13*cm),
4956+ Label(text="per Month", top=0.8*cm, left=15*cm),
4957+ Label(text="per Minute", top=0.8*cm, left=17*cm),
4958+ Label(text="per Megabyte", top=0.8*cm, left=19*cm),
4959+ Label(text="Comments", top=0.8*cm, left=21*cm),
4960+ ]
4961+ borders = {"bottom": True}
4962+ class band_page_footer(ReportBand):
4963+ height = 0.5*cm
4964+ elements = [
4965+ Label(text="%s" % request.utcnow.date(), top=0.1*cm, left=0),
4966+ SystemField(expression="Page # %(page_number)d of %(page_count)d", top=0.1*cm,
4967+ width=BAND_WIDTH, style={"alignment": TA_RIGHT}),
4968+ ]
4969+ borders = {"top": True}
4970+ class band_detail(ReportBand):
4971+ height = 0.5*cm
4972+ auto_expand_height = True
4973+ elements = (
4974+ ObjectValue(attribute_name="code", left=0.2*cm, width=2.8*cm),
4975+ ObjectValue(attribute_name="description", left=3*cm, width=10*cm),
4976+ ObjectValue(attribute_name="unit_cost", left=13*cm, width=2*cm),
4977+ ObjectValue(attribute_name="monthly_cost", left=15*cm, width=2*cm),
4978+ ObjectValue(attribute_name="minute_cost", left=17*cm, width=2*cm),
4979+ ObjectValue(attribute_name="megabyte_cost", left=19*cm, width=2*cm),
4980+ ObjectValue(attribute_name="comments", left=21*cm, width=6*cm),
4981+ )
4982+ groups = [
4983+ ReportGroup(attribute_name="category_type",
4984+ band_header=ReportBand(
4985+ height=0.7*cm,
4986+ elements=[
4987+ ObjectValue(attribute_name="category_type", left=0, top=0.1*cm,
4988+ get_value=lambda instance: instance.category_type and budget_category_type_opts[instance.category_type],
4989+ style={"fontName": "Helvetica-Bold", "fontSize": 12})
4990+ ],
4991+ borders={"bottom": True},
4992+ ),
4993+ ),
4994+ ]
4995+
4996+ #report = MyReport(queryset=objects_list)
4997+ report = MyReport(queryset=objects_list, T=T)
4998+ report.generate_by(PDFGenerator, filename=output)
4999+
5000+ output.seek(0)
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: