~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to doc/app_howto.txt

  • Committer: William Grant
  • Date: 2010-02-23 07:49:55 UTC
  • Revision ID: grantw@unimelb.edu.au-20100223074955-0wd5dmpjkn2hq0qe
Display '+++' when input is requested by the console, as the docs suggest.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
IVLE - App Authoring Guide
2
 
==========================
3
 
 
4
 
    Author: Matt Giuca
5
 
    Date: 17/12/2007
6
 
 
7
 
Intended audience: IVLE developers who wish to write a new application for
8
 
IVLE's plugin interface.
9
 
 
10
 
IVLE's modular architecture allows new applications ("apps") to be easily
11
 
written and added to the site. An app is just a Python program which conforms
12
 
to a small API, plus a few additional configurations.
13
 
 
14
 
Application Specification
15
 
-------------------------
16
 
 
17
 
An application consists of two parts:
18
 
 
19
 
* A Python package in the `apps` directory of IVLE. (That is, a directory with
20
 
  the name of the application containing a file `__init__.py`).
21
 
* An entry in the applications database, stored in the file `conf/apps.py`.
22
 
 
23
 
The entry in the apps database allows IVLE to locate and run the application.
24
 
The package contains the application's code.
25
 
 
26
 
### App name ###
27
 
 
28
 
Applications may be known by three distinct names:
29
 
 
30
 
* The "directory name" ("`dir`") is the most common identifier used for an
31
 
  app. This is the name of the app's package directory.
32
 
* The "URL name" is the URL path segment used to publically identify the
33
 
  application. Is is usually the same as the dir name but may be distinct.
34
 
* The "friendly name" ("`name`") is the name shown to users, eg, in the title
35
 
  bar and in the tabs.
36
 
 
37
 
Applications Database Entry
38
 
---------------------------
39
 
 
40
 
The file `conf/apps.py` is the applications database. (No, it isn't a real
41
 
database, just a Python file with a dictionary in it). Each application is
42
 
defined in a variable. This is merely a convenience so they don't all have
43
 
to be defined inside the dictionary.
44
 
 
45
 
Each application should be created by calling the App constructor, with the
46
 
following fields:
47
 
 
48
 
* `dir` : string - The "directory name" of the app.
49
 
* `name` : string - The "friendly name" of the app.
50
 
* `requireauth` : bool - If True, will automatically require authentication
51
 
      (but not authorization).
52
 
* `hashelp` : bool - If True, this app will be given a help entry.
53
 
 
54
 
Each application should be given an entry in the `app_url` dict, mapping its
55
 
"url name" to the App variable.
56
 
 
57
 
Applications which require a tab in the IVLE interface should have their "url
58
 
names" added to the `apps_in_tabs` list as well.
59
 
 
60
 
Application Interface
61
 
---------------------
62
 
 
63
 
The application directory must have two special files:
64
 
 
65
 
* `__init__.py` is the application entrypoint, discussed below.
66
 
* `help.html` is the application's help file. Only required if `hashelp` is
67
 
    set to True in the application database.
68
 
 
69
 
The directory may contain any other files you wish, including other Python
70
 
modules to import. Note that no files places in the application directory or
71
 
its subdirectories will be directly visible from the web.
72
 
 
73
 
If you wish to make static files such as images, JavaScript and CSS content
74
 
available, they must be placed in `media/apps/yourapp`. Import common.util and
75
 
use `util.make_path` to generate URLs which point to the media directory.
76
 
 
77
 
`__init__.py` must contain a function `handle(req)` which takes 1 argument.
78
 
The argument, "req", will be passed an IVLE Request object. This is very
79
 
similar to the mod_python/Apache Request object but has an
80
 
independently-defined interface. The Request object provides input data in its
81
 
fields. It also provides a `write` method through which the application sends
82
 
its output.
83
 
 
84
 
The `handle` function has no return value.
85
 
 
86
 
The application should operate by reading input from req, setting its fields
87
 
accordingly, then writing the output data. The HTTP response status is set by
88
 
one of the fields of the Request. It also provides error and redirection
89
 
functions which halt execution by throwing an exception.
90
 
 
91
 
See the documentation on `dispatch.request` for the details of this object.
92
 
 
93
 
### Help file ###
94
 
 
95
 
Applications with `hashelp` set to True in the database are required to have
96
 
an additional file, "help.html". This file's contents are displayed by the
97
 
Help app.
98
 
 
99
 
This is not an ordinary HTML file. It should be a valid XHTML file except
100
 
should not contain html or body tags (its contents should just be the inside
101
 
of a body tag). This is equivalent to the output of an app which has
102
 
`write_html_head_foot` set to True. Note that this means it is not a valid XML
103
 
file, but it will be valid once rendered by the Help app.
104
 
 
105
 
The help file will be styled by IVLE's default style sheet. Please use h2 for
106
 
headings (h1 will be used for the main page heading). Use other HTML elements
107
 
in a natural way and they will be styled accordingly.
108
 
 
109
 
Important notes
110
 
---------------
111
 
 
112
 
* The settings of the Request object can only be set before any writing takes
113
 
  place. This is necessary to ensure the correct HTTP and HTML headers can be
114
 
  written before the first actual piece of data is written. Any settings which
115
 
  are set after the first write will be ignored.
116
 
* Similarly, throwing errors or redirects after the first write will not have
117
 
  the intended effects, as the HTTP headers will not be written.
118
 
* Never generate absolute URLs directly (either site-absolute or
119
 
  world-absolute). Applications should not guess where IVLE is located in the
120
 
  site's URL hierarchy. Instead use `common.util.make_path`, and supply it
121
 
  with a path relative to the IVLE site root.
122
 
* All HTML pages generated by the app should set `req.write_html_head_foot` to
123
 
  True (which will decorate the page in the IVLE theme and interface). All
124
 
  non-HTML pages should set it to False or the output will be corrupted by
125
 
  HTML headers. An exception to this rule is an app such as "serve" which
126
 
  serves user applications which should not be decorated by the IVLE
127
 
  interface.
128
 
* Applications which wish to access the student's file system or subversion
129
 
  dynamically (using Ajax) can do so through the `fileservice` app. This will
130
 
  be described in detail in another document. See the `files` app for an
131
 
  example.
132
 
 
133
 
Example Application
134
 
-------------------
135
 
 
136
 
This section shows the creation of a "Hello World" application which simply
137
 
prints some text, inside the IVLE interface. The app's name will be "hello",
138
 
"hello" and "Hello World" respectively.
139
 
 
140
 
Firstly, create a directory, `apps/hello`. Create a file
141
 
`apps/hello/__init__.py` with the following contents:
142
 
 
143
 
    def handle(req):
144
 
        req.content_type = "text/html"
145
 
        req.write_html_head_foot = True
146
 
        req.write("<p>Hello, IVLE!</p>\n")
147
 
 
148
 
Now, edit the file `conf/apps.py`, and add the following lines:
149
 
 
150
 
    app_hello = App()
151
 
    app_hello.dir = "hello"
152
 
    app_hello.name = "Hello World"
153
 
    app_hello.requireauth = False
154
 
    app_hello.hashelp = False
155
 
 
156
 
Add `"hello" : app\_hello,` to the app\_url dictionary. Add `"hello"` to the
157
 
apps\_in\_tabs list.
158
 
 
159
 
Now restart the web server, and the "Hello World" tab should appear. Click
160
 
the tab to call your new app.
161
 
 
162
 
Note that the page output includes the standard IVLE interface and style
163
 
theme (by virtue of setting `req.write_html_head_foot` to True). The data that
164
 
the Hello World app itself outputs should be written assuming it is inside an
165
 
XHTML body element. The final output will be valid XHTML 1.0 Strict if the
166
 
application's output is.
167
 
 
168
 
### Making a file dump ###
169
 
 
170
 
You can modify the application to dump files from the students directories
171
 
easily. You may wish to set `requireauth` to True, which will require that a
172
 
user is logged in. (Note that it doesn't say anything about which user must be
173
 
logged in - any student will still be able to read any other student's files).
174
 
 
175
 
You will need to import the `studpath` module from `common` - this provides
176
 
utilities for accessing student files.
177
 
 
178
 
    from common import studpath
179
 
 
180
 
    def handle(req):
181
 
        req.content_type = "text/html"
182
 
        req.write_html_head_foot = True
183
 
 
184
 
        (user, path) = studpath.url_to_local(req.path)
185
 
        req.write("<p>")
186
 
        try:
187
 
            req.sendfile(path)
188
 
        except IOError, msg:
189
 
            req.write("Error: %s" % msg)
190
 
        req.write("</p>")
191
 
 
192
 
`studpath.url_to_local` gives you a path on the local file system which the
193
 
file corresponds to. (It also gives you the name of the user or group who owns
194
 
the file, though we don't use that here).
195
 
 
196
 
 **Important**: This simple example does not escape characters for HTML, so it
197
 
will not display some files correctly, and could be vulnerable to JavaScript
198
 
injections. In a real app, characters (at the very least, '<', '>' and '&')
199
 
should be escaped correctly.