Sahana Eden - Introduction to the Code

Post on 06-Jul-2015

1.345 views 13 download

description

A 1/2 day tutorial on how to code in the Sahana Eden framework.(This course is still under development)

Transcript of Sahana Eden - Introduction to the Code

:Sahana Eden Emergency DevelopmentEnvironment

2 July 2010, Sahana CampFran Boon

fran@ sahanafoundation.org

: -Technology Stack Back end•Python• 2Web Py

–MVC framework–cron scheduler

•Libraries–lxml–Shapely–PyGSM–xlwt–s3*** (custom Eden modules)

: -Technology Stack Front end

•JavaScript–jQuery

•dataTables•colorbox

–ExtJS

–OpenLayers•GeoExt

Set yours e lf up

:// . . / /http eden s ahanafoundation org wiki Ins tallationGuide lines Deve loper•Install Python:

– inc lxml & Shapely

•Install Bzr•Install web2py

bzr export web2py lp:~mdipierro/web2py/devel•Download Eden

cd applicationsbzr branch lp:~sahana-eden edencd ..python web2py.py

: 2 Exploring Web Py s hell•Python is great for interactive exploring!•Web2Py allows this too •Install iPython to make it better!

–pyreadline needed on Windows–explore objects with tab

python web2py.py –S eden –M

- -Model View Controller•Models

–Database Table definitions

•Contro llers–Workflow, Logic

•Views–HTML / JS Templates parsed server-side–JS functions then run client-side in browser

•Static–no server-side processing–Images, CSS, JavaScript

Modules

•org - Organisation Registry•mpr - Missing Person Registry•cr - Shelter Registry•hms - Hospital Management•rms - Request Management•vol – Volunteer Management•msg - Messaging•gis - Mapping

Res ources• person (pr)• location (gis)• organisation (org)• hospital (hms)• shelter (cr)

•REST Controller–HTTP verbs: GET, PUT (POST), DELETE–Args: /update, /create–Representations: .html, .json, .xml, .xls, .pdf

eden module resource

JavaScript

URL(r=request, a=application, c=controller, f=function, args=[], vars={})

Models

•All executed every request–in alphabetical order–within web2py environment

•Define Tables in Database–Live Migrations

•Provide utility functions & variables which are used by multiple controllers

Core Models

•000_ .config py–deployment settings for easy customisation

•00_ .db py–connect to the database–instantiate classes

•00_ .s e ttings py–read deployment settings & action them

( )Core Models cont•00_ .tables py

–define some re-usable fields for tables–define admin tables

•00_ .utils py–patch session–utility functions

•01_ .crud py–REST Controller front-end

( )Core Models cont

•01_ .menu py–build the Menus

• _ 1 _ .zzz s t run py–Import default data on 1st run

(needs all tables defined 1st)

Controllers

•Entire Controller is executed–Manipulation done outside of functions is

visible to all functions

•Function which has been called is executed

•Functions with no arguments are automatically visible via URLs

Views

•Defaults to views/controller/function.html

•Views can extend & include other views– views/layout.html

•Variables only visible to views if explicitly passed in dict() or else data stored in global variables:

•request, response, sessionhttp://127.0.0.1:8000/eden/default/about

Coffee

Adding a new module

•Vehicle Tracking System•Name: vts•Resources:

–vehicle–driver–location

Model

models/vts.py

# Vehicle resourcetable = db.define_table( “vts_vehicle”,

Field("registration"),Field("make"),Field("model"),Field("supplier"),)

Controller

controllers/vts.py

def vehicle():return shn_rest_controller("vts", "vehicle")

View

None needed at 1st – can RAD without them•then polish later

Try:http://127.0.0.1:8000/eden/vts/vehicle

( )Model revis ited

models/vts.pytable = db.define_table("vts_vehicle",

Field("registration", unique=True),Field("make"),Field("model"),Field("purchase_date", "date",

default=request.utcnow),Field("supplier"),)

table.registration.requires = IS_NOT_IN_DB(db, table.registration)table.purchase_date.requires = IS_DATE()

( )Controller revis itedcontrollers/vts.pymodule = request.controllerdef vehicle():

"REST Controller for the Vehicle Resource"resource = request.functiontablename = "%s_%s" % (module, resource)table = db[tablename]

table.license.label = T("License Plate") table.license.comment = SPAN("*", _class="req")

return shn_rest_controller(module, resource)

: Controller CRUD Stringscontrollers/vts.pydef vehicle():

…s3.crud_strings[tablename] = Storage(

title_create = T("Add Vehicle"), title_display = T("Vehicle Details"), title_list = T("List Vehicles"), title_update = T("Edit Vehicle"), label_create_button = T("Add Vehicle"), msg_record_created = T("Vehicle added"),

…)…

: Controller Action buttonscontrollers/vts.pydef vehicle():

…def veh_postp(jr, output):

shn_action_buttons(jr)return output

response.s3.postp = veh_postp

output = shn_rest_controller(module, resource)return output

: Controller prepcontrollers/org.pydef organisation():

…def org_prep(jr):

if jr.representation == "html":crud.settings.create_next =

URL(r=request, f="dashboard") crud.settings.update_next =

URL(r=request, f="dashboard") return True

response.s3.prep = org_prep

output = shn_rest_controller(module, resource)return output

Documentation

•Examples from other modules•Developer Guidelines on Wiki•But the best… ?

, !Us e the Source LukeMany resources and tricks on the Internet find you will, but solutions to all technical issues only in the source lie

3 2S is built on Web Py

FORM -> SQLFORM -> CRUD -> RESTweb2py/gluon/tools.pyself.settings.create_onvalidation = None self.settings.update_onvalidation = None self.settings.delete_onvalidation = None self.settings.create_onaccept = None self.settings.update_onaccept = None self.settings.update_ondelete = None self.settings.delete_onaccept = None

•onvalidation: before DB I/O•onaccept: after DB I/O

Menus

•Modules menu–Enable Module in 000_config–Create an ‘index’ function & view–01_menu.py will add it to default menu–default/index.html will add it to front page

: Controller Menucontrollers/vts.pydef index():

"Custom View"module_name =

deployment_settings.modules[module].name_nicereturn dict(module_name=module_name)

Enable Modulemodels/000_config.pydeployment_settings.modules = Storage(

…vts = Storage(

name_nice = "Vehicle Tracking System", description = "Track vehicles",

module_type = 4),…

)

: Controller Menucontrollers/vts.pyresponse.menu_options = [ [T("Vehicles"), False, URL(r=request, f="vehicle"),[

[T("List"), False, URL(r=request, f="vehicle")],[T("Add"), False, URL(r=request, f="vehicle", args="create")] ] ]]

: Controller Menucontrollers/vts.pyresponse.menu_options = [ [T("Vehicles"), False, URL(r=request, f="vehicle"),[

[T("List"), False, URL(r=request, f="vehicle")],[T("Add"), False, URL(r=request, f="vehicle", args="create")] ]]

View

views/vts/index.html

{{extend "layout.html"}}{{=H2(T(module_name))}}<p>This module allows users to track their vehicles</p>{{=A("List Vehicles", URL(r=request, f="vehicle"))}}

( )View REST

•REST has defaults– create.html, display.html, list.html, update.html

•They can also be customised:views/vts/vehicle_create.html

{{extend "layout.html"}}{{rheader="Some extra text in my REST view"}}{{include "_create.html"}}

Lunch

: Joined Res ources Model

•Link to Location

models/vts.pytable = db.define_table("vts_presence",

Field("vehicle_id", db.vts_vehicle),location_id,Field("time", "datetime"),Field("comments"),)

table.time.requires = IS_DATETIME()table.vehicle_id.requires = \IS_ONE_OF(db, "vts_vehicle.id", "%(registration)s")

: Joined Res ources Controller

controllers/vts.pydef presence():

return shn_rest_controller("vts", "presence")

:DAL Databas e Abs traction Layer

http://web2py.com/examples/default/dal

db.define_table("person", Field("name"))id = db.person.insert(name="max")query = (db.person.id == id)db(query).count()db(query).delete()db(query).update(name="Max")rows = db(query).select(orderby=db.person.name)for row in rows: print row.namedb.commit()

( )JR Model cont

table.vehicle_id.represent = lambda id: db(db.vts_vehicle.id == id).select() \ .first().registration

table.vehicle_id.represent = lambda id: db(db.vts_vehicle.id == id) \.select(limitby=(0, 1)).first().registration

table.vehicle_id.represent = lambda id: db(db.vts_vehicle.id == id).select(db.vts_vehicle. registration, limitby=(0, 1)).first().registration

: JR Model Components

# Component of vehicle entity s3xrc.model.add_component(module, resource,

multiple=True,joinby=dict(vts_vehicle="vehicle_id"),deletable=True,editable=True,main="time",extra="location_details")

http://127.0.0.1:8000/eden/vts/vehicle/presence

rheader allows main resource details to be visible in component views

!Dis play on Map

•Map displays Feature Groups•Feature Groups contain Feature Classes•Locations have Feature Classes•“Vehicles” are set up ready to go

: Joined Res ources View

views/gis/location_popup.html

{{if "vts_vehicle" in request.vars.caller:}}{{fc = db(db.gis_feature_class.name == "Vehicle").select(db.gis_feature_class.id, limitby=(0, 1)).first().id}}// Hide unnecessary fields…// Pre-populate the FeatureClass & Name…// HTML5 GeoLocation support…{{pass}}

3S XRC

•Export–1st build native XML tree–Then transform to output format using XSLT

•Import–1st transform the input format using XSLT –Then import native XML tree

:Sahana Eden Community Deve lopment

Proces s2 July 2010, Sahana Camp

Fran Boonfran@ sahanafoundation.org

Blue Prints

•Drafted on Wiki•Discussed on IRC & Mailing List•Functional Specs

–User Requirements–User Stories–Wireframes

•Technical Specs

Mes s aging

Open Data Kit

JavaRosa

Development Proces s

•Branches on LaunchPad–Distributed Version Control (bzr)–Merge Early, Merge Often

•Demo sites

•Developer Guidelines•User Guidelines

Sahana Community Tools

Email List sahana-eden@ googlegroups.com

IRC Chat #sahana-edenWiki /BugTracker

eden.sahanafoundation.org

LaunchPad launchpad.net/sahana-edenDimDimTwitter @ SahanaFOSS