ghc

Post on 21-Jun-2015

820 Views

Category:

Documents

8 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

Sahana Eden:Emergency

Development Environment

15 September 2010, Grace Hopper Celebration

Fran Boon

fran@sahanafoundation.org

Agenda

• Stack Overview• Getting Set up• Model View Controller

– Filesystem Layout

• Web2Py execution model• S3 REST Controller• Sahana Modules

– Build a New Module

Stack OverviewServer

Sahana Eden (S3)

Web2Py

Python

HTML

JavaScript

CSS

Client Browser

Eclipse Firebug

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…

Model-View-Controller

web2py/applications/eden/

•controllers

•models

•views

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

Model-View-Controller

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

• Modules– Python libraries

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

Sahana Modules• pr - Person Registry

• org - Organisation Registry

• gis - Mapping

• msg - Messaging

• cr - Shelter Registry

• hms - Hospital Management

• rms - Request Management

• vol – Volunteer Management

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

eden module resource

Emergency• We have to build a module before bed!

Adding a new module

• Vehicle Tracking System

• Name: vts• Resources:

– vehicle– driver– location

Model: Define Table

models/vts.py

# Vehicle resource

table = db.define_table("vts_vehicle",

Field("registration"),

Field("make"),

Field("model"),

Field("supplier"),

)

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

Controller: S3 REST

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

1.Create a vehicle.

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

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

S3 REST Controller• GET args:

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

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

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

Models

• All executed every request

• In alphabetical order

• Within web2py environment

Models

• Define Tables in Database– Live Migrations:

Tables created/altered in database

• 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_settings.py– read deployment settings & action them

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

Core Models (continued)

• 01_menu.py– build the Menus

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

(needs all tables defined 1st)

Views: S3 REST

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

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

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"}}

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

SQL constraints / Validators

models/vts.py

table = db.define_table("vts_vehicle",

Field("registration", unique=True),

Field("make"),

Field("model"),

Field("supplier"),

)

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"),

)

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"),

)

Labels models/vts.py

table.registration.label = "License Plate"

Internationalisation models/vts.py

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

Comments models/vts.py

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

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"),

)

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.

Sahana Eden:Session 2

15 September 2010, Grace Hopper Celebration

Fran Boon

fran@sahanafoundation.org

LaunchPad

Merge proposal

Branches

Trunk

Local Branch

Your Branch

bzr merge

bzr push

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

Enable Module models/000_config.py

deployment_settings.modules = Storage(

vts = Storage(

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

module_type = 10

),

)

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)

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")))}}

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

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

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()

DAL

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

db.commit()

• Beware locking with SQLite

Joined Resources

• So far:– Resource = Single Table

• Reality:– Resource spread out over multiple Tables

Joined Resources: Model

• Link Vehicle to Location– vts_presence

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"),

)

Joined Resources: Model

models/vts.py

table = db.define_table(tablename,

Field("vehicle_id", db.vts_vehicle),

Field("location_id", db.gis_location),

)

Joined Resources: Model

models/vts.py

table = db.define_table(tablename,

Field("vehicle_id", db.vts_vehicle),

location_id,

)

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

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")

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()

Represent

table.vehicle_id.represent = lambda id: function

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

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

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

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

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

RHeader Tabs

End

top related