ghc

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

Upload: aidiq

Post on 21-Jun-2015

819 views

Category:

Documents


8 download

DESCRIPTION

Facilitator Training http://eden.sahanafoundation.org/wiki/GHC2010

TRANSCRIPT

Page 1: GHC

Sahana Eden:Emergency

Development Environment

15 September 2010, Grace Hopper Celebration

Fran Boon

[email protected]

Page 2: GHC

Agenda

• Stack Overview• Getting Set up• Model View Controller

– Filesystem Layout

• Web2Py execution model• S3 REST Controller• Sahana Modules

– Build a New Module

Page 3: GHC

Stack OverviewServer

Sahana Eden (S3)

Web2Py

Python

HTML

JavaScript

CSS

Client Browser

Eclipse Firebug

Page 4: GHC

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

Model-View-Controller

web2py/applications/eden/

•controllers

•models

•views

Page 6: GHC

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

Model-View-Controller

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

• Modules– Python libraries

Page 8: GHC

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

Sahana Modules• pr - Person Registry

• org - Organisation Registry

• gis - Mapping

• msg - Messaging

• cr - Shelter Registry

• hms - Hospital Management

• rms - Request Management

• vol – Volunteer Management

Page 10: GHC

Request processing

1. Web2Py environment setup

2. All Models executed

3. Controller executed

4. Controller Function executed

5. View parsed

6. HTML returned to browser

Page 11: GHC

eden module resource

Page 12: GHC

Emergency• We have to build a module before bed!

Page 13: GHC

Adding a new module

• Vehicle Tracking System

• Name: vts• Resources:

– vehicle– driver– location

Page 14: GHC

Model: Define Table

models/vts.py

# Vehicle resource

table = db.define_table("vts_vehicle",

Field("registration"),

Field("make"),

Field("model"),

Field("supplier"),

)

Page 15: GHC

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

Page 16: GHC

Controller: S3 REST

controllers/vts.py

def vehicle():

return shn_rest_controller("vts", "vehicle")

Page 17: GHC

View

None needed at 1st – can RAD without them

& then polish later

Try:

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

1.Create a vehicle.

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

http://127.0.0.1:8000/eden/vts/vehicle/1.json

Page 18: GHC

S3 REST Controller• GET args:

– /read, /create , /update, /delete

• HTTP verbs:– GET, PUT (POST), DELETE

• Representations:– .html, .json, .xml, .xls, .pdf

Page 19: GHC

Models

• All executed every request

• In alphabetical order

• Within web2py environment

Page 20: GHC

Models

• Define Tables in Database– Live Migrations:

Tables created/altered in database

• Utility functions & variables which are used by multiple controllers

Page 21: GHC

Core Models

• 000_config.py– deployment settings for easy customisation

• 00_db.py– connect to the database– instantiate classes

• 00_settings.py– read deployment settings & action them

Page 22: GHC

Core Models (continued)• 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

Page 23: GHC

Core Models (continued)

• 01_menu.py– build the Menus

• zzz_1st_run.py– Import default data on 1st run

(needs all tables defined 1st)

Page 24: GHC

Views: S3 REST

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

Page 25: GHC

Views: Web2Py• Python code inside {{ }} is parsed server-

side

• Views can extend & include other views

• Extend ‘layout’ for overall look/feel{{extend "layout.html"}}

• Defaults (non-REST) to views/controller/function.html

Page 26: GHC

Views: Custom

• REST views can be customised: views/vts/vehicle_list_create.html

{{extend "layout.html"}}

{{rheader="Register a new vehicle in the system:"}}

{{include "_list_create.html"}}

Page 27: GHC

ViewsVariables only visible to views if:

•explicitly passed in return dict()

•stored in global variables:•request, response, session

http://127.0.0.1:8000/eden/default/about

Page 28: GHC

SQL constraints / Validators

models/vts.py

table = db.define_table("vts_vehicle",

Field("registration", unique=True),

Field("make"),

Field("model"),

Field("supplier"),

)

Page 29: GHC

Field Types models/vts.py

table = db.define_table("vts_vehicle",

Field("registration", unique=True),

Field("make"),

Field("model"),

Field("purchase_date", "date"),

Field("supplier"),

)

Page 30: GHC

Default Values

models/vts.py

table = db.define_table("vts_vehicle",

Field("registration", unique=True),

Field("make"),

Field("model"),

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

Field("supplier"),

)

Page 31: GHC

Labels models/vts.py

table.registration.label = "License Plate"

Page 32: GHC

Internationalisation models/vts.py

table.registration.label = T("License Plate")

Page 33: GHC

Comments models/vts.py

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

Page 34: GHC

CRUD Strings controllers/vts.pydef vehicle():

s3.crud_strings["vts_vehicle"] = Storage(

title_list = T("List Vehicles"),

label_create_button = T("Add Vehicle"),

msg_record_created = T("Vehicle added"),

)

Page 35: GHC

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 36: GHC

Sahana Eden:Session 2

15 September 2010, Grace Hopper Celebration

Fran Boon

[email protected]

Page 37: GHC

LaunchPad

Merge proposal

Branches

Trunk

Local Branch

Your Branch

bzr merge

bzr push

Page 38: GHC

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

Page 39: GHC

Enable Module models/000_config.py

deployment_settings.modules = Storage(

vts = Storage(

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

module_type = 10

),

)

Page 40: GHC

Index page controllers/vts.py

module = request.controller

def index():

"Custom View"

module_name = \ deployment_settings.modules[module].name_nice

return dict(module_name=module_name)

Page 41: GHC

View

views/vts/index.html

{{extend "layout.html"}}

{{=H2(T(module_name))}}

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

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

Page 42: GHC

Controller: Menu controllers/vts.py

response.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")] ]]]

Page 43: GHC

DAL:Database Abstraction Layer• SQLite

• out of the box

• MySQL• well-tested with Eden

• PostgreSQL• what we want to use for Spatial support

• Oracle, DB2, MS SQL, Firebird, GAE

Page 44: GHC

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 45: GHC

DAL

• For shell scripts (e.g. Cron tasks):

db.commit()

• Beware locking with SQLite

Page 46: GHC

Joined Resources

• So far:– Resource = Single Table

• Reality:– Resource spread out over multiple Tables

Page 47: GHC

Joined Resources: Model

• Link Vehicle to Location– vts_presence

Page 48: GHC

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 49: GHC

Joined Resources: Model

models/vts.py

table = db.define_table(tablename,

Field("vehicle_id", db.vts_vehicle),

Field("location_id", db.gis_location),

)

Page 50: GHC

Joined Resources: Model

models/vts.py

table = db.define_table(tablename,

Field("vehicle_id", db.vts_vehicle),

location_id,

)

Page 51: GHC

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 52: GHC

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 53: GHC

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 54: GHC

Represent

table.vehicle_id.represent = lambda id: function

Page 55: GHC

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 56: GHC

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 57: GHC

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 58: GHC

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 59: GHC

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 60: GHC

RHeader Tabs

Page 61: GHC

End