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

« back to all changes in this revision

Viewing changes to doc/dev/faq.rst

Modified the database so that exercises are now stored in the database, rather
than in flat files.

This also necessitated adding new tables and storm classes for test suites
and test cases.

Note that this commit merely changes the database and adds a script to
upload exercises. The code for actually reading exercises has yet
to be changed.

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: