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

« back to all changes in this revision

Viewing changes to doc/dev/faq.rst

  • Committer: William Grant
  • Date: 2010-02-15 05:37:50 UTC
  • Revision ID: grantw@unimelb.edu.au-20100215053750-hihmegnp8e7dshc2
Ignore test coverage files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
.. IVLE - Informatics Virtual Learning Environment
 
2
   Copyright (C) 2007-2009 The University of Melbourne
 
3
 
 
4
.. This program is free software; you can redistribute it and/or modify
 
5
   it under the terms of the GNU General Public License as published by
 
6
   the Free Software Foundation; either version 2 of the License, or
 
7
   (at your option) any later version.
 
8
 
 
9
.. This program is distributed in the hope that it will be useful,
 
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
   GNU General Public License for more details.
 
13
 
 
14
.. You should have received a copy of the GNU General Public License
 
15
   along with this program; if not, write to the Free Software
 
16
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
17
 
 
18
.. _ref-dev-faq:
 
19
 
 
20
**************************
 
21
Frequently Asked Questions
 
22
**************************
 
23
 
 
24
This is a list of Frequently Asked Questions for IVLE developers. It answers
 
25
questions about common issues encountered when bludgeoning the system into
 
26
behaving.
 
27
 
 
28
.. _ref-dev-faq-how:
 
29
 
 
30
How can I...
 
31
============
 
32
 
 
33
.. _ref-dev-faq-config:
 
34
 
 
35
... get data out of the IVLE configuration?
 
36
-------------------------------------------
 
37
 
 
38
::
 
39
 
 
40
    from ivle.config import Config
 
41
    config = Config()
 
42
 
 
43
This makes `config`, a dictionary-tree containing the whole config hierarchy.
 
44
 
 
45
For example, to get the Subversion repository path, use
 
46
``config['paths']['svn']['repo_path']``.
 
47
 
 
48
.. note::
 
49
   For code running inside the jail, you will see different configuration
 
50
   variables than code running outside. It will be missing a lot of data, and
 
51
   will contain some user-specific data.
 
52
 
 
53
... restrict permission to different views?
 
54
-------------------------------------------
 
55
 
 
56
In all views derived from ``BaseView`` the ``authorize`` function is called to 
 
57
check if a user has access to a particular file. Often this is simply a check 
 
58
to ensure that the user is logged in (the value of 'user' is not None), but 
 
59
may be more complex such as checking if a user has a password hash set (to 
 
60
prevent clobbering of external auth) or checking if a user has permission to 
 
61
edit an ``Offering`` object.
 
62
 
 
63
Database
 
64
========
 
65
 
 
66
How can I...
 
67
------------
 
68
 
 
69
IVLE exclusively uses the `Storm`_ API for database access. Do not write any
 
70
SQL code yourself, or make use of low-level database libraries. The only
 
71
exception is in preparing the database schema, which is stored as an SQL file.
 
72
 
 
73
.. _Storm: https://storm.canonical.com/
 
74
 
 
75
... update the database schema?
 
76
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
77
 
 
78
Modify :file:`userdb/users.sql`. Any changes also need to be made in to a
 
79
migrations file, in :file:`userdb/migrations/`.
 
80
 
 
81
TODO: More detail on migrations.
 
82
 
 
83
.. _ref-dev-faq-read-data:
 
84
 
 
85
... read data from the database?
 
86
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
87
 
 
88
::
 
89
 
 
90
    import ivle.database
 
91
    # Typically, you import all database classes you want here
 
92
    from ivle.database import User
 
93
 
 
94
You need a `store` object to perform any interactions with the database. If
 
95
you are inside the web app, get a hold of the `req` (request) object, and use
 
96
``req.store``. In other code, create a new store as follows (where `config` is
 
97
a :ref:`config <ref-dev-faq-config>` object)::
 
98
 
 
99
    store = ivle.database.get_store(config)
 
100
 
 
101
You can read objects out of the database through the store. For example, to
 
102
get a User object::
 
103
 
 
104
    user = store.find(User, User.login==username).one()
 
105
 
 
106
(Note that ``store.find(User)`` just returns a sequence of all users.)
 
107
 
 
108
You can then treat `user` as a normal object, and read from its attributes.
 
109
All of the classes are defined in ``ivle/database.py``.
 
110
 
 
111
.. note::
 
112
   The code must be executed outside of the jail. Jail code runs under user
 
113
   privileges and cannot access the database.
 
114
 
 
115
.. note::
 
116
   For help with the database API, see the `Storm`_ documentation.
 
117
 
 
118
... write data to the database?
 
119
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
120
 
 
121
Get an object out of the database, as :ref:`above <ref-dev-faq-read-data>`,
 
122
and simply write to the object's attributes. This updates the *in-memory* copy
 
123
of the data only.
 
124
 
 
125
To write the changes back to the database, simply use::
 
126
 
 
127
    store.commit()
 
128
 
 
129
using the same store object as used to retrieve the object in the first place.
 
130
 
 
131
... insert a new object into the database?
 
132
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
133
 
 
134
Create the new object using its constructor, as with any Python object. e.g.::
 
135
 
 
136
    import ivle.database
 
137
    user = ivle.database.User()
 
138
 
 
139
You can then set the attributes of the object as desired. As with writing,
 
140
this only creates an *in-memory* object.
 
141
 
 
142
To add the object to the database, get a :ref:`store <ref-dev-faq-read-data>`,
 
143
and use::
 
144
 
 
145
    store.add(user)
 
146
    store.commit()
 
147
 
 
148
... modify user capabilities or privileges?
 
149
-------------------------------------------
 
150
 
 
151
User privileges are set by the ``get_permissions`` functions in 
 
152
``ivle/database.py``. Permissions are highly granular and can be set on almost 
 
153
every object in the database.
 
154
 
 
155
Most permissions are set on the ``Offering`` level with ``ProjectSet``, 
 
156
``Project`` and ``Worksheet`` simply delegating the check to ``Offering``.  
 
157
Since ``Exercise`` may be shared between multiple ``Offerings``, the 
 
158
permissions are calculated from the users active enrollments. Other objects 
 
159
such as ``User`` may only be modified by the user or an admin. If a user is 
 
160
not logged in (user is None) then they will typically receive no privileges at 
 
161
all.
 
162
 
 
163
Where do I find...
 
164
------------------
 
165
 
 
166
.. This is for finding obscure things in the code.
 
167
 
 
168
... the class definitions for database objects?
 
169
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
170
 
 
171
All of the classes are defined in ``ivle/database.py``.
 
172
 
 
173
What does "TypeError: Expected unicode, found <type 'str'>" mean?
 
174
-----------------------------------------------------------------
 
175
 
 
176
All string data going into and out of Storm (i.e., the IVLE database classes)
 
177
must be a Unicode string (type :class:`unicode`), not a regular byte string
 
178
(type :class:`str`). If you have a regular string, convert it to Unicode by
 
179
wrapping it in the :func:`unicode` function. For example::
 
180
 
 
181
    username = unicode(username)
 
182
 
 
183
Subversion
 
184
==========
 
185
 
 
186
How can I...
 
187
------------
 
188
 
 
189
... get the local file path to a user's Subversion repo?
 
190
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
191
 
 
192
Get a :ref:`config <ref-dev-faq-config>` object, and use ::
 
193
 
 
194
    repopath = os.path.join(config['paths']['svn']['repo_path'],
 
195
                            'users', username)
 
196
 
 
197
(This should probably be abstracted.)
 
198
 
 
199
... get the http:// URL for a user's Subversion repo?
 
200
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
201
 
 
202
Get a :ref:`config <ref-dev-faq-config>` object, and use ::
 
203
 
 
204
    repourl = config['urls']['svn_addr'] + '/users/' + username
 
205
 
 
206
(This should probably be abstracted.)
 
207
 
 
208
... get a Subversion client from Python?
 
209
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
210
 
 
211
::
 
212
 
 
213
    import ivle.svn
 
214
    svnclient = ivle.svn.create_auth_svn_client(username, password)
 
215
 
 
216
If you don't have any auth credentials and you just want to do SVN things
 
217
which don't require auth (though I don't see why this situation would arise),
 
218
you can get an auth-less SVN client, which will raise exceptions if you try to
 
219
do authy things (e.g., commit, update or checkout)::
 
220
 
 
221
    import pysvn
 
222
    svnclient = pysvn.Client()
 
223
 
 
224
In either case, the client object will raise `pysvn.ClientError` objects, so
 
225
you should be handling those.
 
226
 
 
227
You may wish to make error messages simpler using this line::
 
228
 
 
229
    svnclient.exception_style = 0
 
230
 
 
231
A good example of Subversion client code is in
 
232
``ivle/fileservice_lib/action.py``.
 
233
 
 
234
.. _ref-dev-faq-where: