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 |
||
1429
by Matt Giuca
dev/faq: Database access tips. |
53 |
Database
|
1431
by Matt Giuca
doc/dev/faq: Slightly better hierarchy. |
54 |
========
|
55 |
||
56 |
How can I...
|
|
57 |
------------
|
|
1429
by Matt Giuca
dev/faq: Database access tips. |
58 |
|
59 |
IVLE exclusively uses the `Storm`_ API for database access. Do not write any
|
|
60 |
SQL code yourself, or make use of low-level database libraries. The only |
|
61 |
exception is in preparing the database schema, which is stored as an SQL file. |
|
62 |
||
63 |
.. _Storm: https://storm.canonical.com/ |
|
64 |
||
65 |
... update the database schema?
|
|
1431
by Matt Giuca
doc/dev/faq: Slightly better hierarchy. |
66 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1429
by Matt Giuca
dev/faq: Database access tips. |
67 |
|
68 |
Modify :file:`userdb/users.sql`. Any changes also need to be made in to a |
|
69 |
migrations file, in :file:`userdb/migrations/`. |
|
70 |
||
71 |
TODO: More detail on migrations. |
|
72 |
||
73 |
.. _ref-dev-faq-read-data: |
|
74 |
||
75 |
... read data from the database?
|
|
1431
by Matt Giuca
doc/dev/faq: Slightly better hierarchy. |
76 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1429
by Matt Giuca
dev/faq: Database access tips. |
77 |
|
78 |
::
|
|
79 |
||
80 |
import ivle.database
|
|
81 |
# Typically, you import all database classes you want here
|
|
82 |
from ivle.database import User
|
|
83 |
||
84 |
You need a `store` object to perform any interactions with the database. If
|
|
85 |
you are inside the web app, get a hold of the `req` (request) object, and use
|
|
86 |
``req.store``. In other code, create a new store as follows (where `config` is |
|
87 |
a :ref:`config <ref-dev-faq-config>` object):: |
|
88 |
||
89 |
store = ivle.database.get_store(config)
|
|
90 |
||
91 |
You can read objects out of the database through the store. For example, to |
|
92 |
get a User object::
|
|
93 |
||
94 |
user = store.find(User, User.login==username).one()
|
|
95 |
||
96 |
(Note that ``store.find(User)`` just returns a sequence of all users.)
|
|
97 |
||
98 |
You can then treat `user` as a normal object, and read from its attributes.
|
|
99 |
All of the classes are defined in ``ivle/database.py``.
|
|
100 |
||
101 |
.. note:: |
|
102 |
The code must be executed outside of the jail. Jail code runs under user |
|
103 |
privileges and cannot access the database. |
|
104 |
||
105 |
.. note:: |
|
106 |
For help with the database API, see the `Storm`_ documentation.
|
|
107 |
||
108 |
... write data to the database?
|
|
1431
by Matt Giuca
doc/dev/faq: Slightly better hierarchy. |
109 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1429
by Matt Giuca
dev/faq: Database access tips. |
110 |
|
111 |
Get an object out of the database, as :ref:`above <ref-dev-faq-read-data>`, |
|
112 |
and simply write to the object's attributes. This updates the *in-memory* copy
|
|
113 |
of the data only. |
|
114 |
||
115 |
To write the changes back to the database, simply use::
|
|
116 |
||
117 |
store.commit()
|
|
118 |
||
119 |
using the same store object as used to retrieve the object in the first place. |
|
120 |
||
121 |
... insert a new object into the database?
|
|
1431
by Matt Giuca
doc/dev/faq: Slightly better hierarchy. |
122 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1429
by Matt Giuca
dev/faq: Database access tips. |
123 |
|
124 |
Create the new object using its constructor, as with any Python object. e.g.::
|
|
125 |
||
126 |
import ivle.database
|
|
127 |
user = ivle.database.User()
|
|
128 |
||
129 |
You can then set the attributes of the object as desired. As with writing, |
|
130 |
this only creates an *in-memory* object.
|
|
131 |
||
132 |
To add the object to the database, get a :ref:`store <ref-dev-faq-read-data>`, |
|
133 |
and use::
|
|
134 |
||
135 |
store.add(user)
|
|
136 |
store.commit()
|
|
137 |
||
1431
by Matt Giuca
doc/dev/faq: Slightly better hierarchy. |
138 |
Where do I find...
|
139 |
------------------
|
|
140 |
||
141 |
.. This is for finding obscure things in the code.
|
|
142 |
||
143 |
... the class definitions for database objects?
|
|
144 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
145 |
||
146 |
All of the classes are defined in ``ivle/database.py``.
|
|
147 |
||
1432
by Matt Giuca
doc/dev/faq: New Q&A. |
148 |
What does "TypeError: Expected unicode, found <type 'str'>" mean?
|
149 |
-----------------------------------------------------------------
|
|
150 |
||
151 |
All string data going into and out of Storm (i.e., the IVLE database classes) |
|
152 |
must be a Unicode string (type :class:`unicode`), not a regular byte string |
|
153 |
(type :class:`str`). If you have a regular string, convert it to Unicode by |
|
154 |
wrapping it in the :func:`unicode` function. For example:: |
|
155 |
||
156 |
username = unicode(username)
|
|
157 |
||
1425
by Matt Giuca
doc: Added dev/faq, with some helpful tips on creating certain objects. |
158 |
Subversion
|
1431
by Matt Giuca
doc/dev/faq: Slightly better hierarchy. |
159 |
==========
|
160 |
||
161 |
How can I...
|
|
162 |
------------
|
|
1425
by Matt Giuca
doc: Added dev/faq, with some helpful tips on creating certain objects. |
163 |
|
164 |
... get the local file path to a user's Subversion repo?
|
|
165 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
166 |
||
167 |
Get a :ref:`config <ref-dev-faq-config>` object, and use :: |
|
168 |
||
169 |
repopath = os.path.join(config['paths']['svn']['repo_path'],
|
|
170 |
'users', username)
|
|
171 |
||
172 |
(This should probably be abstracted.) |
|
173 |
||
174 |
... get the http:// URL for a user's Subversion repo?
|
|
175 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
176 |
||
177 |
Get a :ref:`config <ref-dev-faq-config>` object, and use :: |
|
178 |
||
179 |
repourl = config['urls']['svn_addr'] + '/users/' + username
|
|
180 |
||
181 |
(This should probably be abstracted.) |
|
182 |
||
183 |
... get a Subversion client from Python?
|
|
184 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
185 |
||
186 |
::
|
|
187 |
||
188 |
import ivle.svn
|
|
189 |
svnclient = ivle.svn.create_auth_svn_client(username, password)
|
|
190 |
||
191 |
If you don't have any auth credentials and you just want to do SVN things |
|
192 |
which don't require auth (though I don't see why this situation would arise), |
|
193 |
you can get an auth-less SVN client, which will raise exceptions if you try to |
|
194 |
do authy things (e.g., commit, update or checkout)::
|
|
195 |
||
196 |
import pysvn
|
|
197 |
svnclient = pysvn.Client()
|
|
198 |
||
199 |
In either case, the client object will raise `pysvn.ClientError` objects, so
|
|
200 |
you should be handling those. |
|
201 |
||
202 |
You may wish to make error messages simpler using this line::
|
|
203 |
||
204 |
svnclient.exception_style = 0
|
|
205 |
||
206 |
A good example of Subversion client code is in |
|
207 |
``ivle/fileservice_lib/action.py``.
|
|
208 |
||
209 |
.. _ref-dev-faq-where: |