ghc participant training

52
Sahana Eden: Emergency Development Environment 30 September 2010, Grace Hopper Celebration Fran Boon [email protected]

Upload: aidiq

Post on 20-Jan-2015

686 views

Category:

Documents


3 download

DESCRIPTION

 

TRANSCRIPT

Page 1: GHC Participant Training

Sahana Eden:Emergency

Development Environment

30 September 2010, Grace Hopper Celebration

Fran Boon

[email protected]

Page 2: GHC Participant Training

Agenda

• Stack Overview

• Getting Set up

• Model View Controller– Filesystem Layout

• Build a New Module– S3 REST Controller

Page 3: GHC Participant Training

Stack OverviewServer

Sahana Eden (S3)

Web2Py

Python

HTML

JavaScript

CSS

Client Browser

Eclipse Firebug

Page 4: GHC Participant Training

Installation: Virtual Machine

Simplest way to start:http://eden.sahanafoundation.org/wiki/InstallationGuidelinesVirtualMachine

Full Developer Environment:•Eclipse•Codebase (Web2Py/Sahana Eden)

Launch Eclipse to get started…

Page 5: GHC Participant Training

Model-View-Controller

web2py/applications/eden/

•controllers

•models

•views

Page 6: GHC Participant Training

Model-View-Controller• Models

– Define Tables in the Database

• Controllers– Workflow, Logic

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

Page 7: GHC Participant Training

Model-View-Controller

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

• Modules– Python libraries

Page 8: GHC Participant Training

Modules• Sahana concept

– Logical grouping of user-facing functionality– Not to be confused with Python modules

• i.e. not web2py/applications/eden/modules

• Consist of:– Model(s)– Controller– Views

Page 9: GHC Participant Training

Sahana Modules

• Organisation Registry: org

• Person Finder: pr, mpr, dvi

• Request Management: rms

• Inventory: inv

• Shelter Registry: cr

• Mapping: gis

• Messaging: msg

Page 10: GHC Participant Training

LaunchPad

Merge proposal

Branches

Trunk

Local Branch

Your Branch

bzr merge

bzr push

Page 11: GHC Participant Training

Request processing

1. Web2Py environment setup

2. All Models executed (alphabetical order)

3. Controller executed

4. Controller Function executed

5. View parsed (explicit variable passing)

6. HTML/JS returned to browser

Page 12: GHC Participant Training

Emergency• We have to build a module before bed!

Page 13: GHC Participant Training

Software Development Cycle

Page 14: GHC Participant Training

Incident Reporting SystemData:• Location• Date• Reporter• Details

Screens:• Report Incident• View Incidents• Update Incident

Page 15: GHC Participant Training

Define Data

models/inc.py

table = db.define_table("inc_incident",

location_id(),

Field("date", "date"),

person_id(),

comments()

)

Page 16: GHC Participant Training

Forms for CRUD

controllers/inc.py

def incident():

return shn_rest_controller("inc",

"incident")

Page 17: GHC Participant Training

We’re done!

http://127.0.0.1:8000/eden/inc/incident

1.Create an incident.

2.View in different formats:– .json, .xml, .xls, .pdf

http://127.0.0.1:8000/eden/inc/incident/1.json

Page 18: GHC Participant Training

Views: Custom REST

views/inc/incident_list_create.html

{{extend "layout.html"}}

<p>A Normal HTML Paragraph</p>

{{rheader="A Paragraph inserted inside the page"}}

{{include "_list_create.html"}}

{{include "gis/location_autocomplete.js"}}

•Python code inside {{ }} is parsed server-side•Views can extend (one) & include (many) other views•Extend ‘layout’ for overall look/feel•Variables only visible to views if:

– explicitly passed in return dict()– stored in global variables: request, response, session

Page 19: GHC Participant Training

SQL constraints / Validators

models/inc.py

table = db.define_table("inc_incident",

Field("code", unique=True),

)

DAL supports Live Migrations

Page 20: GHC Participant Training

Field Types models/inc.py

table = db.define_table ("inc_incident",

Field("date", "date"),

)

Page 21: GHC Participant Training

Default Values

models/inc.py

table = db.define_table("inc_incident",

Field("date_date", "date", default=request.utcnow),

)

Page 22: GHC Participant Training

Labels models/inc.py

table.person_id.label = "Reporter"

Page 23: GHC Participant Training

Internationalisation models/inc.py

table.person_id.label = T("Reporter“)

Page 24: GHC Participant Training

Comments models/inc.py

table.code.comment = SPAN("*", _class="req")

Page 25: GHC Participant Training

Requires

models/03_gis.py

db.gis_location.comment = …

db.gis_location.requires = IS_ONE_OF(…)

Page 26: GHC Participant Training

Represent

models/03_gis.py

db.gis_location.represent = shn_location_represent

Page 27: GHC Participant Training

Exploring: Web2Py shell• Python is great for interactive exploring!

– Web2Py allows this too

w2p

python web2py.py –S eden –M

• Explore objects with tabdb.

gis.

Page 28: GHC Participant Training

DALTry these in the shell: w2p

db.define_table("person", Field("name"))

id = db.person.insert(name="max")query = (db.person.id == id)

db(query).count()

db(query).update(name="Max")

rows = db(query).select(orderby=db.person.name)for row in rows:

print row.name

db(query).delete()

Page 29: GHC Participant Training

End

Page 30: GHC Participant Training

Enable Module models/000_config.py

deployment_settings.modules = Storage(

#irs = Storage(

inc = Storage(

name_nice = "Incident Reporting System", description = "Report Incidents",

module_type = 3

),

)

Page 31: GHC Participant Training

Index page controllers/inc.py

module = request.controller

def index():

"Custom View"

module_name = \ deployment_settings.modules[module].name_nice

return dict(module_name=module_name)

Page 32: GHC Participant Training

View

views/inc/index.html

{{extend "layout.html"}}

{{=H2(module_name)}}

<p>This module allows users to track their vehicles</p>

{{=LI(A("List Vehicles", _href=URL(r=request, f="vehicle")))}}

Page 33: GHC Participant Training

Controller: Menu controllers/inc.py

response.menu_options = [

[T("Incidents"), False, URL(r=request, f="incident"),[[T("List"), False, URL(r=request, f="incident")],[T("Add"), False, URL(r=request, f="incident",

args="create")] ]]]

Page 34: GHC Participant Training

Joined Resources

• So far:– Resource = Single Table

• Reality:– Resource spread out over multiple Tables

Page 35: GHC Participant Training

Joined Resources: Model

• Link Vehicle to Location– vts_presence

Page 36: GHC Participant Training

Joined Resources: Model

models/vts.pymodule = "vts"

resource = "presence"

tablename = "%s_%s" % (module, resource)

table = db.define_table(tablename,

Field("vehicle_id"),

Field("location_id"),

)

Page 37: GHC Participant Training

Joined Resources: Model

models/vts.py

table = db.define_table(tablename,

Field("vehicle_id", db.vts_vehicle),

Field("location_id", db.gis_location),

)

Page 38: GHC Participant Training

Joined Resources: Model

models/vts.py

table = db.define_table(tablename,

Field("vehicle_id", db.vts_vehicle),

location_id(),

)

Page 39: GHC Participant Training

Joined Resources: Controller controllers/vts.py

def presence():

resource = request.function

return shn_rest_controller(module, resource)

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

Page 40: GHC Participant Training

Joined Resources: Model

models/vts.py

table = db.define_table(tablename,

Field("vehicle_id", db.vts_vehicle),

location_id(),

)

table.vehicle_id.requires = IS_ONE_OF(db,

"vts_vehicle.id",

"vts_vehicle.registration")

Page 41: GHC Participant Training

Joined Resources: Model

models/vts.py

table = db.define_table(tablename,

Field("vehicle_id", db.vts_vehicle),

location_id(),

Field("timestmp", "datetime"),

)

table.vehicle_id.requires = IS_ONE_OF(db, "vts_vehicle.id", "vts_vehicle.registration")

table.timestmp.requires = IS_DATETIME()

Page 42: GHC Participant Training

Represent

table.vehicle_id.represent = lambda id: function

Page 43: GHC Participant Training

DAL: Optimised SQL queries

“Find the vehicle with this ID”:

db(db.vts_vehicle.id == id).select()

db(db.vts_vehicle.id == id).select().first()

“Return the Registration”:

db(db.vts_vehicle.id == id).select().first().registration

db(db.vts_vehicle.id == id).\

select(limitby=(0,1)).first().registration

db(db.vts_vehicle.id == id).\

select(db.vts_vehicle.registration,

limitby=(0,1)).first().registration

Page 44: GHC Participant Training

JR: Represent models/vts.py

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

Page 45: GHC Participant Training

Components models/vts.py

# Presence as component of vehicle

s3xrc.model.add_component(module,

resource,

multiple=True,

joinby=dict(vts_vehicle="vehicle_id"),

deletable=True,

editable=True)

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

Page 46: GHC Participant Training

RHeader controllers/vts.pydef shn_vts_rheader(r, tabs=[]):

if r.representation == "html":

rheader_tabs = shn_rheader_tabs(r, tabs)

vehicle = r.record

rheader = DIV(TABLE(

TR(TH(T("Vehicle: ")), vehicle.registration)

),

rheader_tabs

)

return rheader

return None

Page 47: GHC Participant Training

RHeader Tabs controllers/vts.pydef vehicle():

output = shn_rest_controller(module, "vehicle",

rheader=lambda r: shn_vts_rheader(r,

tabs = [(T("Basic Details"), None),

(T("Presence"), "presence")

]))

return output

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

Page 48: GHC Participant Training

RHeader Tabs

Page 49: GHC Participant Training

S3 is built on Web2Py

REST

CRUD

SQLFORM

FORM

Page 50: GHC Participant Training

Form submission

• Use Firebug’s Net Panel to look at a form submission.

• Each field has an entry in form.vars

• Can add additional vars to the form in a custom View

• Can process these within our Controller– onvalidation: Before DB I/O– onaccept: After DB I/O

Page 51: GHC Participant Training

Documentation

• Examples from other modules

• Developer Guidelines on Wiki:http://eden.sahanafoundation.org/wiki/DeveloperGuidelines

• But the best…?

Page 52: GHC Participant Training

Use the Source, Luke!Many resources and tricks on the Internet find you will, but the ultimate answers only in the source lie