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

1425 by Matt Giuca
doc: Added dev/faq, with some helpful tips on creating certain objects.
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
1496 by David Coles
Docs: Outline on permissions for views and database objects
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
1429 by Matt Giuca
dev/faq: Database access tips.
63
Database
1431 by Matt Giuca
doc/dev/faq: Slightly better hierarchy.
64
========
65
66
How can I...
67
------------
1429 by Matt Giuca
dev/faq: Database access tips.
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?
1431 by Matt Giuca
doc/dev/faq: Slightly better hierarchy.
76
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1429 by Matt Giuca
dev/faq: Database access tips.
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?
1431 by Matt Giuca
doc/dev/faq: Slightly better hierarchy.
86
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1429 by Matt Giuca
dev/faq: Database access tips.
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?
1431 by Matt Giuca
doc/dev/faq: Slightly better hierarchy.
119
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1429 by Matt Giuca
dev/faq: Database access tips.
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?
1431 by Matt Giuca
doc/dev/faq: Slightly better hierarchy.
132
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1429 by Matt Giuca
dev/faq: Database access tips.
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
1496 by David Coles
Docs: Outline on permissions for views and database objects
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
1431 by Matt Giuca
doc/dev/faq: Slightly better hierarchy.
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
1432 by Matt Giuca
doc/dev/faq: New Q&A.
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
1425 by Matt Giuca
doc: Added dev/faq, with some helpful tips on creating certain objects.
183
Subversion
1431 by Matt Giuca
doc/dev/faq: Slightly better hierarchy.
184
==========
185
186
How can I...
187
------------
1425 by Matt Giuca
doc: Added dev/faq, with some helpful tips on creating certain objects.
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: