Wiki

Version 237 (Etienne Pallier, 03/22/2016 11:27 am)

1 1 Etienne Pallier
h1. Technical Documentation for the PYROS project (FGFT-CC)
2 1 Etienne Pallier
3 1 Etienne Pallier
4 1 Etienne Pallier
HOWTO Format Redmine Wiki : http://www.redmine.org/projects/redmine/wiki/FrRedmineWikiFormatting
5 1 Etienne Pallier
6 1 Etienne Pallier
{{>toc}}
7 1 Etienne Pallier
8 1 Etienne Pallier
9 121 Etienne Pallier
---
10 1 Etienne Pallier
11 121 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}I - TODO%
12 121 Etienne Pallier
13 126 Etienne Pallier
 * installation sur windows
14 125 Etienne Pallier
15 126 Etienne Pallier
 * gitlab
16 1 Etienne Pallier
17 126 Etienne Pallier
 * séparation des BD Django et Pyros
18 125 Etienne Pallier
19 126 Etienne Pallier
 * intégration dans Eclipse
20 126 Etienne Pallier
21 174 Etienne Pallier
 * Intégration des modules Django déjà développés
22 125 Etienne Pallier
23 121 Etienne Pallier
24 3 Etienne Pallier
---
25 1 Etienne Pallier
26 140 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}I - DATABASE SCHEMA (v0.2.1)%
27 116 Etienne Pallier
28 116 Etienne Pallier
29 117 Etienne Pallier
{{thumbnail(PYROS_PDM_v021.png, size=300, title=Pyros data model)}}
30 121 Etienne Pallier
31 121 Etienne Pallier
32 121 Etienne Pallier
---
33 116 Etienne Pallier
34 141 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}II - Get the project (from gitlab)%
35 141 Etienne Pallier
36 169 Etienne Pallier
h3. Get the project from the terminal
37 1 Etienne Pallier
38 1 Etienne Pallier
<pre>
39 1 Etienne Pallier
git clone https://gitlab.irap.omp.eu/epallier/pyros.git PYROS
40 169 Etienne Pallier
41 174 Etienne Pallier
(or also : git clone git@gitlab.irap.omp.eu:epallier/pyros.git)
42 1 Etienne Pallier
</pre>
43 1 Etienne Pallier
44 197 Etienne Pallier
This creates a PYROS/ folder containing the project (with a .git/ subfolder for synchronization with the git repository)
45 1 Etienne Pallier
46 225 Etienne Pallier
_If you just wanted a static copy of the project (without synchronization) just remove the .git/ folder:_
47 1 Etienne Pallier
<pre>
48 1 Etienne Pallier
$ rm -r .git/
49 1 Etienne Pallier
</pre>
50 226 Etienne Pallier
51 226 Etienne Pallier
You should obtain this structure:
52 226 Etienne Pallier
53 226 Etienne Pallier
<pre>
54 226 Etienne Pallier
55 226 Etienne Pallier
PYROS/
56 226 Etienne Pallier
├── REQUIREMENTS.txt
57 226 Etienne Pallier
├── private/
58 226 Etienne Pallier
│   └── venv_py35_pyros/
59 226 Etienne Pallier
├── public/
60 226 Etienne Pallier
│   └── static/
61 226 Etienne Pallier
├── src/
62 226 Etienne Pallier
│   ├── manage.py
63 226 Etienne Pallier
│   ├── pyros/
64 226 Etienne Pallier
│   │   ├── __init__.py
65 226 Etienne Pallier
│   │   ├── __pycache__
66 226 Etienne Pallier
│   │   ├── settings.py
67 226 Etienne Pallier
│   │   ├── urls.py
68 226 Etienne Pallier
│   │   └── wsgi.py
69 226 Etienne Pallier
│   └── pyrosapp/
70 226 Etienne Pallier
│       ├── __init__.py
71 226 Etienne Pallier
│       ├── admin.py
72 226 Etienne Pallier
│       ├── apps.py
73 226 Etienne Pallier
│       ├── migrations
74 226 Etienne Pallier
│       ├── models.py
75 226 Etienne Pallier
│       ├── tests.py
76 226 Etienne Pallier
│       └── views.py
77 226 Etienne Pallier
78 226 Etienne Pallier
79 226 Etienne Pallier
</pre>
80 226 Etienne Pallier
81 174 Etienne Pallier
82 174 Etienne Pallier
h3. Get the project from Eclipse
83 169 Etienne Pallier
84 197 Etienne Pallier
<pre>
85 169 Etienne Pallier
TODO:
86 197 Etienne Pallier
</pre>
87 169 Etienne Pallier
88 141 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}III - INSTALLATION%
89 2 Etienne Pallier
90 120 Etienne Pallier
91 120 Etienne Pallier
---
92 120 Etienne Pallier
93 184 Etienne Pallier
h3. Install MySql (only if necessary)
94 2 Etienne Pallier
95 49 Etienne Pallier
 * Linux Ubuntu
96 49 Etienne Pallier
<pre>
97 107 Paul Carensac
98 107 Paul Carensac
$ sudo apt-get install mysql-server
99 107 Paul Carensac
$ sudo apt-get install mysql-client
100 107 Paul Carensac
101 49 Etienne Pallier
</pre>
102 49 Etienne Pallier
103 49 Etienne Pallier
 * Linux CentOS
104 49 Etienne Pallier
<pre>
105 49 Etienne Pallier
TODO:
106 49 Etienne Pallier
$ sudo yum install mysql
107 49 Etienne Pallier
...
108 49 Etienne Pallier
</pre>
109 49 Etienne Pallier
110 49 Etienne Pallier
 * Mac OS X
111 1 Etienne Pallier
Install XAMPP
112 1 Etienne Pallier
(but you could also use the pre-installed Mac OS MySql)
113 177 Etienne Pallier
<pre>
114 177 Etienne Pallier
TODO:
115 49 Etienne Pallier
</pre>
116 1 Etienne Pallier
117 49 Etienne Pallier
 * Windows
118 177 Etienne Pallier
Install XAMPP
119 49 Etienne Pallier
<pre>
120 49 Etienne Pallier
TODO:
121 49 Etienne Pallier
</pre>
122 49 Etienne Pallier
123 49 Etienne Pallier
124 49 Etienne Pallier
---
125 1 Etienne Pallier
126 185 Etienne Pallier
h3. Install Python3.5 (only if necessary)
127 1 Etienne Pallier
128 11 Etienne Pallier
129 11 Etienne Pallier
 * Mac OS X :
130 1 Etienne Pallier
<pre>
131 183 Etienne Pallier
132 24 Etienne Pallier
1) Installer MacPort
133 24 Etienne Pallier
(TODO: doc)
134 24 Etienne Pallier
135 24 Etienne Pallier
2) Installer le "port" python35
136 1 Etienne Pallier
$ sudo port install python35
137 183 Etienne Pallier
138 1 Etienne Pallier
</pre>
139 1 Etienne Pallier
140 1 Etienne Pallier
 * Linux (Ubuntu) :
141 1 Etienne Pallier
<pre>
142 107 Paul Carensac
sudo add-apt-repository ppa:fkrull/deadsnakes
143 107 Paul Carensac
sudo apt-get update
144 107 Paul Carensac
sudo apt-get install python3.5
145 107 Paul Carensac
146 107 Paul Carensac
sudo pip install virtualenv
147 23 Etienne Pallier
</pre>
148 1 Etienne Pallier
149 1 Etienne Pallier
150 183 Etienne Pallier
 * Windows 10 :
151 183 Etienne Pallier
<pre>
152 187 Etienne Pallier
TODO:
153 183 Etienne Pallier
</pre>
154 3 Etienne Pallier
155 4 Etienne Pallier
---
156 5 Etienne Pallier
157 192 Etienne Pallier
h3. Create a Python3 virtual environment dedicated to the project (inside the project folder)
158 127 Etienne Pallier
159 131 Etienne Pallier
<pre>
160 1 Etienne Pallier
161 193 Etienne Pallier
$ mkdir private/
162 193 Etienne Pallier
163 133 Etienne Pallier
$ cd private/
164 3 Etienne Pallier
165 3 Etienne Pallier
$ which python3.5
166 3 Etienne Pallier
/opt/local/bin/python3.5
167 15 Etienne Pallier
168 127 Etienne Pallier
$ virtualenv-3.5 venv_py35_pyros -p /opt/local/bin/python3.5
169 3 Etienne Pallier
=> creates a venv_py35_pyros/ folder inside PYROS/private/
170 1 Etienne Pallier
171 131 Etienne Pallier
</pre>
172 1 Etienne Pallier
173 7 Etienne Pallier
---
174 3 Etienne Pallier
175 65 Etienne Pallier
h3. Activate the python virtual environment (from inside the project)
176 7 Etienne Pallier
177 55 Etienne Pallier
<pre>
178 1 Etienne Pallier
179 65 Etienne Pallier
$ pwd
180 134 Etienne Pallier
.../PYROS/private
181 1 Etienne Pallier
182 65 Etienne Pallier
$ source ./venv_py35_pyros/bin/activate
183 65 Etienne Pallier
184 3 Etienne Pallier
$ python -V
185 1 Etienne Pallier
Python 3.5.1
186 3 Etienne Pallier
187 3 Etienne Pallier
$ which pip
188 77 Etienne Pallier
.../PYROS/venv_py35_pyros/bin/pip
189 16 Etienne Pallier
190 194 Etienne Pallier
Upgrade pip to last version available:
191 3 Etienne Pallier
$ pip install --upgrade pip
192 3 Etienne Pallier
Collecting pip
193 3 Etienne Pallier
  Downloading pip-8.1.1-py2.py3-none-any.whl (1.2MB)
194 3 Etienne Pallier
Installing collected packages: pip
195 3 Etienne Pallier
  Found existing installation: pip 7.1.2
196 3 Etienne Pallier
    Uninstalling pip-7.1.2:
197 3 Etienne Pallier
      Successfully uninstalled pip-7.1.2
198 1 Etienne Pallier
Successfully installed pip-8.1.1
199 194 Etienne Pallier
200 194 Etienne Pallier
Upgrade wheel to last version available:
201 194 Etienne Pallier
$ pip install --upgrade wheel
202 194 Etienne Pallier
Collecting wheel
203 194 Etienne Pallier
  Downloading wheel-0.29.0-py2.py3-none-any.whl (66kB)
204 194 Etienne Pallier
Installing collected packages: wheel
205 194 Etienne Pallier
  Found existing installation: wheel 0.24.0
206 194 Etienne Pallier
    Uninstalling wheel-0.24.0:
207 194 Etienne Pallier
      Successfully uninstalled wheel-0.24.0
208 194 Etienne Pallier
Successfully installed wheel-0.29.0
209 194 Etienne Pallier
210 55 Etienne Pallier
211 55 Etienne Pallier
</pre>
212 18 Etienne Pallier
213 212 Etienne Pallier
h3. Install the needed Python packages (from within the virtual environment)
214 18 Etienne Pallier
215 66 Etienne Pallier
First, be sure that the virtual environment is activated:
216 66 Etienne Pallier
<pre>
217 66 Etienne Pallier
$ python -V
218 66 Etienne Pallier
Python 3.5.1
219 66 Etienne Pallier
</pre>
220 66 Etienne Pallier
221 62 Etienne Pallier
 * *Automatic Installation of all packages*
222 62 Etienne Pallier
<pre>
223 90 Etienne Pallier
$ pip install -r REQUIREMENTS.txt
224 62 Etienne Pallier
</pre>
225 62 Etienne Pallier
226 93 Etienne Pallier
 * *Or, manual installation of each package*
227 62 Etienne Pallier
228 62 Etienne Pallier
  * *Install Django* :
229 32 Etienne Pallier
<pre>
230 3 Etienne Pallier
$ pip install django
231 3 Etienne Pallier
Collecting django
232 3 Etienne Pallier
  Downloading Django-1.9.4-py2.py3-none-any.whl (6.6MB)
233 3 Etienne Pallier
Installing collected packages: django
234 3 Etienne Pallier
Successfully installed django-1.9.4
235 3 Etienne Pallier
236 3 Etienne Pallier
$ pip install django-admin-tools
237 3 Etienne Pallier
Collecting django-admin-tools
238 3 Etienne Pallier
  Downloading django_admin_tools-0.7.2-py2.py3-none-any.whl (289kB)
239 3 Etienne Pallier
Installing collected packages: django-admin-tools
240 3 Etienne Pallier
Successfully installed django-admin-tools-0.7.2
241 3 Etienne Pallier
242 21 Etienne Pallier
$ pip install django-debug-toolbar
243 21 Etienne Pallier
Collecting django-debug-toolbar
244 21 Etienne Pallier
  Downloading django_debug_toolbar-1.4-py2.py3-none-any.whl (212kB)
245 21 Etienne Pallier
Requirement already satisfied (use --upgrade to upgrade): Django>=1.7 in ./venv_py35_pyros/lib/python3.5/site-packages (from django-debug-toolbar)
246 21 Etienne Pallier
Collecting sqlparse (from django-debug-toolbar)
247 21 Etienne Pallier
  Downloading sqlparse-0.1.19.tar.gz (58kB)
248 21 Etienne Pallier
Building wheels for collected packages: sqlparse
249 21 Etienne Pallier
  Running setup.py bdist_wheel for sqlparse ... done
250 21 Etienne Pallier
  Stored in directory: /Users/epallier/Library/Caches/pip/wheels/7b/d4/72/6011bb100dd5fc213164e4bbee13d4e03261dd54ce6a5de6b8
251 21 Etienne Pallier
Successfully built sqlparse
252 21 Etienne Pallier
Installing collected packages: sqlparse, django-debug-toolbar
253 21 Etienne Pallier
Successfully installed django-debug-toolbar-1.4 sqlparse-0.1.19
254 21 Etienne Pallier
255 21 Etienne Pallier
$ pip install django-extensions
256 21 Etienne Pallier
Collecting django-extensions
257 21 Etienne Pallier
  Downloading django_extensions-1.6.1-py2.py3-none-any.whl (202kB)
258 21 Etienne Pallier
Collecting six>=1.2 (from django-extensions)
259 21 Etienne Pallier
  Downloading six-1.10.0-py2.py3-none-any.whl
260 21 Etienne Pallier
Installing collected packages: six, django-extensions
261 21 Etienne Pallier
Successfully installed django-extensions-1.6.1 six-1.10.0
262 21 Etienne Pallier
263 21 Etienne Pallier
$ pip install django-suit
264 21 Etienne Pallier
Collecting django-suit
265 21 Etienne Pallier
  Downloading django-suit-0.2.18.tar.gz (587kB)
266 21 Etienne Pallier
Building wheels for collected packages: django-suit
267 1 Etienne Pallier
  Running setup.py bdist_wheel for django-suit ... done
268 1 Etienne Pallier
  Stored in directory: /Users/epallier/Library/Caches/pip/wheels/12/8b/9a/e02ab0ad9229881638aa040d47d77c8f562999533811927d41
269 1 Etienne Pallier
Successfully built django-suit
270 1 Etienne Pallier
Installing collected packages: django-suit
271 1 Etienne Pallier
Successfully installed django-suit-0.2.18
272 21 Etienne Pallier
273 32 Etienne Pallier
</pre>
274 32 Etienne Pallier
275 63 Etienne Pallier
  * *Install the web application server gunicorn (will be used in production instead of the dev django web server)* :
276 32 Etienne Pallier
<pre>
277 25 Etienne Pallier
$ pip install gunicorn
278 25 Etienne Pallier
Collecting gunicorn
279 25 Etienne Pallier
  Downloading gunicorn-19.4.5-py2.py3-none-any.whl (112kB)
280 21 Etienne Pallier
Installing collected packages: gunicorn
281 26 Etienne Pallier
Successfully installed gunicorn-19.4.5
282 1 Etienne Pallier
</pre>
283 1 Etienne Pallier
284 63 Etienne Pallier
  * *Install the python mysql client*:
285 32 Etienne Pallier
<pre>
286 32 Etienne Pallier
$ pip install mysqlclient
287 72 Etienne Pallier
...
288 72 Etienne Pallier
</pre>
289 33 Etienne Pallier
290 73 Etienne Pallier
   * => Issue under Mac OS X:
291 72 Etienne Pallier
<pre>
292 3 Etienne Pallier
$ pip install mysqlclient
293 3 Etienne Pallier
Collecting mysqlclient
294 1 Etienne Pallier
  Downloading mysqlclient-1.3.7.tar.gz (79kB)
295 22 Etienne Pallier
Building wheels for collected packages: mysqlclient
296 3 Etienne Pallier
  Running setup.py bdist_wheel for mysqlclient ... error
297 3 Etienne Pallier
298 1 Etienne Pallier
  ----------------------------------------
299 1 Etienne Pallier
  Failed building wheel for mysqlclient
300 1 Etienne Pallier
  Running setup.py clean for mysqlclient
301 1 Etienne Pallier
Failed to build mysqlclient
302 1 Etienne Pallier
Installing collected packages: mysqlclient
303 1 Etienne Pallier
  Running setup.py install for mysqlclient ... done
304 1 Etienne Pallier
Successfully installed mysqlclient-1.3.7
305 1 Etienne Pallier
306 1 Etienne Pallier
BOUH !!!
307 1 Etienne Pallier
308 1 Etienne Pallier
$ pip install --upgrade wheel
309 1 Etienne Pallier
Collecting wheel
310 1 Etienne Pallier
  Downloading wheel-0.29.0-py2.py3-none-any.whl (66kB)
311 1 Etienne Pallier
Installing collected packages: wheel
312 1 Etienne Pallier
  Found existing installation: wheel 0.24.0
313 1 Etienne Pallier
    Uninstalling wheel-0.24.0:
314 1 Etienne Pallier
      Successfully uninstalled wheel-0.24.0
315 1 Etienne Pallier
Successfully installed wheel-0.29.0
316 1 Etienne Pallier
317 1 Etienne Pallier
$ pip uninstall mysqlclient
318 1 Etienne Pallier
319 1 Etienne Pallier
$ pip install mysqlclient
320 1 Etienne Pallier
Collecting mysqlclient
321 1 Etienne Pallier
  Using cached mysqlclient-1.3.7.tar.gz
322 1 Etienne Pallier
Building wheels for collected packages: mysqlclient
323 1 Etienne Pallier
  Running setup.py bdist_wheel for mysqlclient ... done
324 1 Etienne Pallier
  Stored in directory: /Users/epallier/Library/Caches/pip/wheels/9b/06/50/d11418c26cf8f2156b13d4363b5afde8e7e75ebb8540d0228d
325 1 Etienne Pallier
Successfully built mysqlclient
326 1 Etienne Pallier
Installing collected packages: mysqlclient
327 1 Etienne Pallier
Successfully installed mysqlclient-1.3.7
328 1 Etienne Pallier
329 1 Etienne Pallier
YES !!!
330 1 Etienne Pallier
331 1 Etienne Pallier
</pre>
332 1 Etienne Pallier
333 107 Paul Carensac
   * => Issues under Ubuntu:
334 107 Paul Carensac
<pre>
335 107 Paul Carensac
$ pip install mysqlclient
336 107 Paul Carensac
Collecting mysqlclient
337 107 Paul Carensac
  Downloading mysqlclient-1.3.7.tar.gz (79kB)
338 107 Paul Carensac
    100% |████████████████████████████████| 81kB 1.5MB/s
339 107 Paul Carensac
    Complete output from command python setup.py egg_info:
340 107 Paul Carensac
    /bin/sh: 1: mysql_config: not found
341 107 Paul Carensac
    Traceback (most recent call last):
342 107 Paul Carensac
      File "<string>", line 1, in <module>
343 107 Paul Carensac
    [...]
344 107 Paul Carensac
    ----------------------------------------
345 107 Paul Carensac
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-q6j4inuz/mysqlclient/
346 1 Etienne Pallier
347 108 Paul Carensac
BOUH !!!
348 108 Paul Carensac
349 107 Paul Carensac
$ sudo apt-get install libmysqlclient-dev
350 108 Paul Carensac
351 107 Paul Carensac
$ pip install mysqlclient
352 107 Paul Carensac
Collecting mysqlclient
353 107 Paul Carensac
  Using cached mysqlclient-1.3.7.tar.gz
354 107 Paul Carensac
Building wheels for collected packages: mysqlclient
355 107 Paul Carensac
  Running setup.py bdist_wheel for mysqlclient ... error
356 107 Paul Carensac
357 107 Paul Carensac
    _mysql.c:40:20: fatal error: Python.h: No such file or directory
358 107 Paul Carensac
     #include "Python.h"
359 107 Paul Carensac
                        ^
360 107 Paul Carensac
    compilation terminated.
361 107 Paul Carensac
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
362 107 Paul Carensac
    
363 107 Paul Carensac
    ----------------------------------------
364 107 Paul Carensac
Command "/home/carens_p/pyros/venv_py35_pyros/bin/python3.5 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-k3klv92j/mysqlclient/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-gz242xxs-record/install-record.txt --single-version-externally-managed --compile --install-headers /home/carens_p/pyros/venv_py35_pyros/include/site/python3.5/mysqlclient" failed with error code 1 in /tmp/pip-build-k3klv92j/mysqlclient/
365 107 Paul Carensac
366 108 Paul Carensac
BOUH !!!
367 108 Paul Carensac
368 107 Paul Carensac
$ sudo apt-get install python3.5-dev
369 108 Paul Carensac
370 107 Paul Carensac
$ pip install mysqlclient
371 107 Paul Carensac
372 107 Paul Carensac
YES !!!
373 107 Paul Carensac
374 107 Paul Carensac
</pre>
375 12 Etienne Pallier
376 12 Etienne Pallier
---
377 28 Etienne Pallier
378 142 Etienne Pallier
h3. Test the project
379 142 Etienne Pallier
380 142 Etienne Pallier
<pre>
381 142 Etienne Pallier
382 150 Etienne Pallier
$ cd src/
383 150 Etienne Pallier
384 1 Etienne Pallier
$ ./manage.py runserver
385 38 Etienne Pallier
(or gunicorn pyros.wsgi)
386 3 Etienne Pallier
==> http://localhost:8000
387 87 Etienne Pallier
...
388 87 Etienne Pallier
...
389 87 Etienne Pallier
Ctrl-c
390 87 Etienne Pallier
391 1 Etienne Pallier
</pre>
392 142 Etienne Pallier
393 142 Etienne Pallier
394 142 Etienne Pallier
395 142 Etienne Pallier
---
396 142 Etienne Pallier
397 156 Paul Carensac
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}IV - CONFIGURATION of the Django Back Office (administration interface)%
398 155 Paul Carensac
399 155 Paul Carensac
---
400 155 Paul Carensac
401 155 Paul Carensac
h3. Back Office setup
402 155 Paul Carensac
403 155 Paul Carensac
 * Prerequisites in src/pyros/settings.py :
404 155 Paul Carensac
405 155 Paul Carensac
    * INSTALLED_APPS must (at least) contain :
406 155 Paul Carensac
407 155 Paul Carensac
        * django.contrib.admin
408 155 Paul Carensac
        * django.contrib.auth
409 155 Paul Carensac
        * django.contrib.contenttypes
410 155 Paul Carensac
        * django.contrib.sessions
411 155 Paul Carensac
412 155 Paul Carensac
    * MIDDLEWARES must (at least) contain :
413 155 Paul Carensac
414 155 Paul Carensac
        * django.contrib.sessions.middleware.SessionMiddleware
415 155 Paul Carensac
        * django.middleware.common.CommonMiddleware
416 155 Paul Carensac
        * django.contrib.auth.middleware.AuthenticationMiddleware
417 155 Paul Carensac
418 155 Paul Carensac
 * At least one 'python manage.py migrate' must have been executed
419 155 Paul Carensac
420 155 Paul Carensac
 * Create a superuser for the administration :
421 155 Paul Carensac
422 155 Paul Carensac
<pre>
423 155 Paul Carensac
$ python manage.py createsuperuser
424 155 Paul Carensac
</pre>
425 155 Paul Carensac
426 156 Paul Carensac
* For each app of the project, fill the admin.py file :
427 155 Paul Carensac
428 155 Paul Carensac
<pre>
429 155 Paul Carensac
from django.contrib import admin
430 155 Paul Carensac
from app.models import Model1, Model2
431 155 Paul Carensac
432 155 Paul Carensac
admin.site.register(Model1)
433 155 Paul Carensac
admin.site.register(Model2)
434 155 Paul Carensac
</pre>
435 155 Paul Carensac
436 155 Paul Carensac
*Reminder* : each application must be registered in the settings.py INSTALLED_APPS variable.
437 157 Paul Carensac
438 168 Paul Carensac
* For each model in models.py, add a '__str__()' method in order to identify the object on the back office. Example :
439 157 Paul Carensac
440 157 Paul Carensac
<pre>
441 157 Paul Carensac
class UserLevel(models.Model):
442 157 Paul Carensac
    name = models.CharField(max_length=45, blank=True, null=True)
443 157 Paul Carensac
    desc = models.TextField(blank=True, null=True)
444 157 Paul Carensac
    priority = models.IntegerField(blank=True, null=True)
445 157 Paul Carensac
    quota = models.FloatField(blank=True, null=True)
446 157 Paul Carensac
447 157 Paul Carensac
    class Meta:
448 157 Paul Carensac
        managed = True
449 157 Paul Carensac
        db_table = 'userlevel'
450 157 Paul Carensac
451 157 Paul Carensac
    def __str__(self):
452 163 Paul Carensac
        return (str(self.name))
453 157 Paul Carensac
</pre>
454 157 Paul Carensac
455 159 Paul Carensac
*Naming convention* : Use self.name when possible, the creation time/date otherwise. Example :
456 159 Paul Carensac
457 159 Paul Carensac
<pre>
458 159 Paul Carensac
class SiteWatch(models.Model):
459 159 Paul Carensac
    updated = models.DateTimeField(blank=True, null=True)
460 159 Paul Carensac
    lights = models.CharField(max_length=45, blank=True, null=True)
461 159 Paul Carensac
    dome = models.CharField(max_length=45, blank=True, null=True)
462 159 Paul Carensac
    doors = models.CharField(max_length=45, blank=True, null=True)
463 159 Paul Carensac
    temperature = models.FloatField(blank=True, null=True)
464 159 Paul Carensac
465 159 Paul Carensac
    class Meta:
466 159 Paul Carensac
        managed = True
467 159 Paul Carensac
        db_table = 'sitewatch'
468 159 Paul Carensac
469 159 Paul Carensac
    def __str__(self):
470 160 Paul Carensac
        return (str(self.updated))
471 159 Paul Carensac
</pre>
472 173 Etienne Pallier
473 211 Paul Carensac
---
474 211 Paul Carensac
475 211 Paul Carensac
h3. Adaptation of the one-to-many and many-to-many display
476 211 Paul Carensac
477 211 Paul Carensac
* The one-to-many relationships are the following (One.many format) :
478 211 Paul Carensac
479 211 Paul Carensac
    * Schedule.sequences
480 211 Paul Carensac
    * Request.sequences
481 211 Paul Carensac
    * Sequence.albums
482 211 Paul Carensac
    * Album.plans
483 211 Paul Carensac
    * Plan.images
484 211 Paul Carensac
    * Telescope.detectors
485 211 Paul Carensac
    * Detector.filters
486 211 Paul Carensac
    * NrtAnalysis.images
487 211 Paul Carensac
    * Filter.plans
488 211 Paul Carensac
    * Detector.albums
489 211 Paul Carensac
    * UserLevel.users
490 211 Paul Carensac
    * Country.users
491 211 Paul Carensac
    * ScientificProgram.requests
492 211 Paul Carensac
    * User.requests
493 211 Paul Carensac
    * StrategyObs.alerts
494 211 Paul Carensac
    * SequenceType.sequences
495 211 Paul Carensac
496 211 Paul Carensac
* For each "many", create a new class in admin.py just after the imports, following these examples :
497 211 Paul Carensac
498 211 Paul Carensac
<pre>
499 211 Paul Carensac
500 211 Paul Carensac
For Schedule.sequences, Request.sequences and Sequentype.sequences, we will need :
501 211 Paul Carensac
502 211 Paul Carensac
class SequenceInline(admin.TabularInline):
503 211 Paul Carensac
    model = Sequence
504 211 Paul Carensac
    fields = ("name",)
505 211 Paul Carensac
    show_change_link = True
506 211 Paul Carensac
507 211 Paul Carensac
508 211 Paul Carensac
For Sequence.albums and Detector.albums, we will need :
509 211 Paul Carensac
510 211 Paul Carensac
class AlbumInline(admin.TabularInline):
511 211 Paul Carensac
    model = Album
512 211 Paul Carensac
    fields = ("name",)
513 211 Paul Carensac
    show_change_link = True
514 211 Paul Carensac
515 211 Paul Carensac
516 211 Paul Carensac
For StrategyObs.alerts, we will need :
517 211 Paul Carensac
518 211 Paul Carensac
class AlertInline(admin.TabularInline):
519 211 Paul Carensac
    model = Alert
520 211 Paul Carensac
    fields = ("request.name",) # there is no 'name' attribute in the Alert model
521 211 Paul Carensac
    show_change_link = True
522 211 Paul Carensac
523 211 Paul Carensac
</pre>
524 211 Paul Carensac
525 222 Paul Carensac
* For each "One", declare a new class in admin.py, just after the "Inlines" class declaration, as done in the following examples :
526 211 Paul Carensac
527 222 Paul Carensac
<pre>
528 222 Paul Carensac
For Request.sequences :
529 222 Paul Carensac
530 222 Paul Carensac
class RequestAdmin(admin.ModelAdmin):
531 222 Paul Carensac
    inlines = [
532 222 Paul Carensac
	SequenceInline,
533 222 Paul Carensac
    ]
534 222 Paul Carensac
535 222 Paul Carensac
For Detector.filters and Detector.albums :
536 222 Paul Carensac
537 222 Paul Carensac
class DetectorAdmin(admin.ModelAdmin):
538 222 Paul Carensac
    inlines = [
539 222 Paul Carensac
	FilterInline,
540 222 Paul Carensac
        AlbumInline,
541 222 Paul Carensac
    ]
542 222 Paul Carensac
543 222 Paul Carensac
</pre>
544 222 Paul Carensac
545 232 Paul Carensac
546 222 Paul Carensac
* The many-to-many relationships are the following :
547 232 Paul Carensac
548 222 Paul Carensac
    * ScientificProgram - User
549 222 Paul Carensac
    * ScheduleHistory - Sequence
550 222 Paul Carensac
551 222 Paul Carensac
* For each many-to-many relationship, declare a new "Inline" class in admin.py just after the imports, like this :
552 222 Paul Carensac
553 222 Paul Carensac
<pre>
554 222 Paul Carensac
For ScientificProgram - User :
555 222 Paul Carensac
556 222 Paul Carensac
class UserAndSPInline(admin.TabularInline):
557 222 Paul Carensac
    model = ScientificProgram.users.through
558 222 Paul Carensac
559 222 Paul Carensac
560 222 Paul Carensac
For ScheduleHistory - Sequence
561 222 Paul Carensac
562 222 Paul Carensac
class SequenceAndSHInline(admin.TabularInline):
563 222 Paul Carensac
    model = ScheduleHistory.sequences.through
564 222 Paul Carensac
565 222 Paul Carensac
</pre>
566 222 Paul Carensac
567 222 Paul Carensac
+Note :+ The order in the line "model = ScientificProgram.users.through" is very important : the first model (ScientificProgram) is the one in which is declared the ManyToManyField relationship.
568 232 Paul Carensac
569 232 Paul Carensac
* For each many-to-many relationship, declare two new classes in admin.py, just after the inlines, like in the following examples :
570 232 Paul Carensac
571 232 Paul Carensac
<pre>
572 232 Paul Carensac
For the ScheduleHistory - Sequence relationship :
573 232 Paul Carensac
574 232 Paul Carensac
class ScheduleHistoryAdmin(admin.ModelAdmin):
575 232 Paul Carensac
    inlines = [
576 232 Paul Carensac
        SequenceAndSHInline,
577 232 Paul Carensac
    ]
578 232 Paul Carensac
    exclude = ('sequences',) # ScheduleHistory declares the ManyToManyField, and we want to replace its display in the back office, so we won't display the default field
579 232 Paul Carensac
580 232 Paul Carensac
class SequenceAdmin(admin.ModelAdmin):
581 232 Paul Carensac
    inlines = [
582 232 Paul Carensac
        AlbumInline,        # This is the Inline for the one-to-many relationship Sequence.albums
583 232 Paul Carensac
        SequenceAndSHInline,                                                                
584 232 Paul Carensac
    ]
585 232 Paul Carensac
586 232 Paul Carensac
For the ScientificProgram - User relationship :
587 232 Paul Carensac
588 232 Paul Carensac
class ScientificProgramAdmin(admin.ModelAdmin):
589 232 Paul Carensac
    inlines = [
590 232 Paul Carensac
        RequestInline,
591 232 Paul Carensac
	UserAndSPInline,                                                                         
592 232 Paul Carensac
    ]
593 232 Paul Carensac
    exclude = ('users',) # Same as ScheduleHistory                                                                         
594 232 Paul Carensac
595 232 Paul Carensac
class UserAdmin(admin.ModelAdmin):
596 232 Paul Carensac
    inlines = [
597 232 Paul Carensac
	RequestInline,   # This is the Inline for the one-to-many relationship User.requests
598 232 Paul Carensac
        UserAndSPInline,                                                                    
599 232 Paul Carensac
    ]
600 232 Paul Carensac
601 232 Paul Carensac
</pre>
602 232 Paul Carensac
603 235 Paul Carensac
* For each ModelAdmin class in the admin.py, change the registering line
604 235 Paul Carensac
605 235 Paul Carensac
<pre>
606 235 Paul Carensac
admin.site.register(Album)
607 235 Paul Carensac
</pre>
608 235 Paul Carensac
609 235 Paul Carensac
to
610 235 Paul Carensac
611 235 Paul Carensac
<pre>
612 235 Paul Carensac
admin.site.register(Album, AlbumAdmin)
613 235 Paul Carensac
</pre>
614 211 Paul Carensac
615 229 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}V - INSTALLATION FROM THE BEGINNING (for dev only, history of the initial project creation)%
616 1 Etienne Pallier
617 236 Etienne Pallier
618 237 Etienne Pallier
[[pyros_install_from_start]]
619 204 Etienne Pallier
620 205 Etienne Pallier
h3. Install MySql (only if necessary)
621 205 Etienne Pallier
622 205 Etienne Pallier
See above in III-Installation
623 1 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#III-INSTALLATION
624 207 Etienne Pallier
625 207 Etienne Pallier
626 207 Etienne Pallier
---
627 207 Etienne Pallier
628 208 Etienne Pallier
h3. Create the database (from sql script generated with Mysql Workbench)
629 207 Etienne Pallier
630 207 Etienne Pallier
 * Linux and Mac OS X:
631 207 Etienne Pallier
<pre>
632 207 Etienne Pallier
One liner:
633 207 Etienne Pallier
$ mysql -u root < pyros_create.sql
634 207 Etienne Pallier
635 207 Etienne Pallier
Or :
636 207 Etienne Pallier
$ mysql -u root
637 207 Etienne Pallier
mysql> create database pyros;
638 207 Etienne Pallier
mysql> use pyros;
639 207 Etienne Pallier
mysql> source pyros_create.sql;
640 207 Etienne Pallier
641 207 Etienne Pallier
(
642 207 Etienne Pallier
TODO:
643 207 Etienne Pallier
mysql> grant all on pyros.* to pyros@localhost identified by ‘pyros’;)
644 207 Etienne Pallier
mysql> flush privileges;
645 207 Etienne Pallier
)
646 207 Etienne Pallier
</pre>
647 207 Etienne Pallier
648 207 Etienne Pallier
649 207 Etienne Pallier
 * Windows:
650 207 Etienne Pallier
<pre>
651 207 Etienne Pallier
TODO: Use phpmyadmin ?
652 207 Etienne Pallier
</pre>
653 205 Etienne Pallier
654 205 Etienne Pallier
h3. Install Python3.5 (only if necessary)
655 205 Etienne Pallier
656 205 Etienne Pallier
See above in III-Installation
657 205 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#III-INSTALLATION
658 205 Etienne Pallier
659 210 Etienne Pallier
660 210 Etienne Pallier
h3. Create the project structure
661 210 Etienne Pallier
662 210 Etienne Pallier
<pre>
663 210 Etienne Pallier
$ mkdir PYROS
664 210 Etienne Pallier
</pre>
665 210 Etienne Pallier
666 210 Etienne Pallier
Example of a good organization :
667 210 Etienne Pallier
668 210 Etienne Pallier
1 project = N applis
669 210 Etienne Pallier
1 appli = N models
670 210 Etienne Pallier
A! L’appli est à côté du projet, PAS DEDANS,
671 210 Etienne Pallier
cela facilite la REUTILISATION
672 210 Etienne Pallier
(an appli can be part of many projects => reuse)
673 210 Etienne Pallier
1 appli = 1 Python module, organized for Django, by default = appli web (but not mandatory)
674 210 Etienne Pallier
675 210 Etienne Pallier
<pre>
676 210 Etienne Pallier
677 210 Etienne Pallier
MYPROJECT/
678 210 Etienne Pallier
	REQUIREMENTS.txt
679 210 Etienne Pallier
	src/
680 210 Etienne Pallier
		myproject/
681 210 Etienne Pallier
		appli1/
682 210 Etienne Pallier
		appli2/
683 210 Etienne Pallier
684 210 Etienne Pallier
		appliN/
685 210 Etienne Pallier
686 210 Etienne Pallier
	public/
687 210 Etienne Pallier
		static/
688 210 Etienne Pallier
689 210 Etienne Pallier
	private/
690 210 Etienne Pallier
		venv_py35_pyros/
691 210 Etienne Pallier
692 210 Etienne Pallier
</pre>
693 210 Etienne Pallier
694 210 Etienne Pallier
695 210 Etienne Pallier
Set needed folders:
696 210 Etienne Pallier
<pre>
697 210 Etienne Pallier
$ cd PYROS/
698 210 Etienne Pallier
$ mkdir private public
699 210 Etienne Pallier
$ mkdir public/static
700 210 Etienne Pallier
</pre>
701 210 Etienne Pallier
702 210 Etienne Pallier
703 210 Etienne Pallier
704 210 Etienne Pallier
---
705 210 Etienne Pallier
706 205 Etienne Pallier
h3. Create a Python3 virtual environment dedicated to the project (inside the project folder)
707 205 Etienne Pallier
708 205 Etienne Pallier
See above in III-Installation
709 205 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#III-INSTALLATION
710 205 Etienne Pallier
711 205 Etienne Pallier
h3. Activate the Python virtual environment (from inside the project)
712 205 Etienne Pallier
713 205 Etienne Pallier
See above in III-Installation
714 205 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#III-INSTALLATION
715 205 Etienne Pallier
716 213 Etienne Pallier
h3. Install the needed Python packages (from within the virtual environment)
717 205 Etienne Pallier
718 1 Etienne Pallier
See above in III-Installation
719 213 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#Install-the-needed-Python-packages-from-within-the-virtual-environment
720 213 Etienne Pallier
(cf manual installation)
721 213 Etienne Pallier
722 215 Etienne Pallier
h3. Create a Django project named PYROS
723 1 Etienne Pallier
724 215 Etienne Pallier
<pre>
725 215 Etienne Pallier
726 215 Etienne Pallier
From inside the project:
727 215 Etienne Pallier
$ pwd
728 215 Etienne Pallier
.../PYROS/
729 215 Etienne Pallier
730 215 Etienne Pallier
$ django-admin startproject pyros
731 215 Etienne Pallier
732 215 Etienne Pallier
Rename the project folder "pyros/" as "src/"
733 215 Etienne Pallier
734 215 Etienne Pallier
$ mv pyros src
735 215 Etienne Pallier
736 215 Etienne Pallier
We have then this architecture:
737 215 Etienne Pallier
738 215 Etienne Pallier
PYROS
739 215 Etienne Pallier
├── REQUIREMENTS.txt
740 215 Etienne Pallier
├── private
741 215 Etienne Pallier
│   └── venv_py35_pyros
742 215 Etienne Pallier
├── public
743 215 Etienne Pallier
│   └── static
744 215 Etienne Pallier
├── src
745 215 Etienne Pallier
│   ├── manage.py
746 215 Etienne Pallier
│   ├── pyros
747 215 Etienne Pallier
│   │   ├── __init__.py
748 215 Etienne Pallier
│   │   ├── settings.py
749 215 Etienne Pallier
│   │   ├── urls.py
750 215 Etienne Pallier
│   │   └── wsgi.py
751 215 Etienne Pallier
752 215 Etienne Pallier
</pre>
753 215 Etienne Pallier
754 215 Etienne Pallier
755 215 Etienne Pallier
756 215 Etienne Pallier
757 215 Etienne Pallier
---
758 205 Etienne Pallier
759 205 Etienne Pallier
h3. Test the project
760 205 Etienne Pallier
761 205 Etienne Pallier
See above in III-Installation
762 205 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#III-INSTALLATION
763 205 Etienne Pallier
764 205 Etienne Pallier
h3. The Web server
765 205 Etienne Pallier
766 217 Etienne Pallier
767 217 Etienne Pallier
Apache : gère tous les fichiers statiques (images, html…), et délègue les fichiers python au serveur django (par défaut)
768 217 Etienne Pallier
769 217 Etienne Pallier
Le fichier pyros/urls.py prend le relai pour tout ce qui est django
770 217 Etienne Pallier
771 217 Etienne Pallier
Le moteur web django sera soit du wsgi soit du unicorn
772 217 Etienne Pallier
773 217 Etienne Pallier
Par défaut, 1 seul worker, mais on peut en configurer plusieurs, l’idéal étant de faire "nb coeurs + 1" 
774 217 Etienne Pallier
(le worker maître qui fait le dispatching aux autres)
775 217 Etienne Pallier
776 217 Etienne Pallier
Frontend : Apache ou Ngininx
777 217 Etienne Pallier
778 217 Etienne Pallier
Backend : gunicorn (gère facilement des workers) ou uwsgi
779 217 Etienne Pallier
780 217 Etienne Pallier
<pre>
781 217 Etienne Pallier
$ gunicorn pyros.wsgi
782 217 Etienne Pallier
(à la place de manage runserver => A EVITER EN PROD)
783 217 Etienne Pallier
784 217 Etienne Pallier
Ou encore:
785 217 Etienne Pallier
786 217 Etienne Pallier
$ gunicorn --workers 5 library.wsgi
787 217 Etienne Pallier
</pre>
788 217 Etienne Pallier
789 217 Etienne Pallier
---
790 217 Etienne Pallier
791 219 Etienne Pallier
h3. Set the database engine as MySql
792 219 Etienne Pallier
793 219 Etienne Pallier
Edit src/pyros/settings.py
794 219 Etienne Pallier
795 219 Etienne Pallier
<pre>
796 219 Etienne Pallier
DATABASES = {
797 219 Etienne Pallier
    'default': {
798 219 Etienne Pallier
        'ENGINE': 'django.db.backends.mysql',
799 219 Etienne Pallier
        'NAME': 'pyros',
800 219 Etienne Pallier
        'USER': 'root',
801 219 Etienne Pallier
        'PASSWORD': ''
802 219 Etienne Pallier
    }
803 219 Etienne Pallier
}
804 219 Etienne Pallier
</pre>
805 219 Etienne Pallier
806 219 Etienne Pallier
---
807 205 Etienne Pallier
808 221 Etienne Pallier
h3. Import the database into Django (with inspectdb)
809 221 Etienne Pallier
810 221 Etienne Pallier
From src/ :
811 221 Etienne Pallier
812 221 Etienne Pallier
<pre>
813 221 Etienne Pallier
$ ./manage.py inspectdb > models.py
814 221 Etienne Pallier
</pre>
815 221 Etienne Pallier
816 221 Etienne Pallier
Issue on Mac OS X:
817 221 Etienne Pallier
<pre>
818 221 Etienne Pallier
Traceback (most recent call last):
819 221 Etienne Pallier
  File "/Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/django/db/backends/mysql/base.py", line 25, in <module>
820 221 Etienne Pallier
    import MySQLdb as Database
821 221 Etienne Pallier
  File "/Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/MySQLdb/__init__.py", line 19, in <module>
822 221 Etienne Pallier
    import _mysql
823 221 Etienne Pallier
ImportError: dlopen(/Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so, 2): Library not loaded: libmysqlclient.18.dylib
824 221 Etienne Pallier
  Referenced from: /Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so
825 221 Etienne Pallier
  Reason: image not found
826 221 Etienne Pallier
827 221 Etienne Pallier
=> BOUH !!!
828 221 Etienne Pallier
829 221 Etienne Pallier
LA SOLUTION EST ICI : http://stackoverflow.com/questions/6383310/python-mysqldb-library-not-loaded-libmysqlclient-18-dylib
830 221 Etienne Pallier
831 221 Etienne Pallier
Il suffit de faire ceci:
832 221 Etienne Pallier
833 221 Etienne Pallier
$ sudo mkdir -p /usr/local/lib   
834 221 Etienne Pallier
$ sudo ln -s /Applications/XAMPP/xamppfiles/lib/libmysql* /usr/local/lib/
835 221 Etienne Pallier
836 221 Etienne Pallier
Mais on peut aussi faire ceci:
837 221 Etienne Pallier
838 221 Etienne Pallier
Okay, so the offending file is /Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so
839 221 Etienne Pallier
840 221 Etienne Pallier
Next, figure out where _mysql.so thinks it should find libmysqlclient.18.dylib:
841 221 Etienne Pallier
842 221 Etienne Pallier
$ otool -L /Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so
843 221 Etienne Pallier
/Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so:
844 221 Etienne Pallier
	libmysqlclient.18.dylib (compatibility version 18.0.0, current version 18.0.0)
845 221 Etienne Pallier
...
846 221 Etienne Pallier
847 221 Etienne Pallier
So, it's looking for libmysqlclient.18.dylib with no path information, let's fix that:
848 221 Etienne Pallier
849 221 Etienne Pallier
$ locate libmysqlclient.18.dylib
850 221 Etienne Pallier
/Applications/XAMPP/xamppfiles/lib/libmysqlclient.18.dylib
851 221 Etienne Pallier
/Library/SystemMigration/History/Migration-68137DFB-CB6A-4FBB-81E2-11BDB5D01E48/QuarantineRoot/usr/lib/libmysqlclient.18.dylib
852 221 Etienne Pallier
853 221 Etienne Pallier
$ sudo install_name_tool -change libmysqlclient.18.dylib /Applications/XAMPP/xamppfiles/lib/libmysqlclient.18.dylib /Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so
854 221 Etienne Pallier
855 221 Etienne Pallier
Now _mysql.so knows the full path to the library and everything works, regardless of environment variables.
856 221 Etienne Pallier
857 221 Etienne Pallier
$ otool -L /Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so
858 221 Etienne Pallier
/Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so:
859 221 Etienne Pallier
	/Applications/XAMPP/xamppfiles/lib/libmysqlclient.18.dylib (compatibility version 18.0.0, current version 18.0.0)
860 221 Etienne Pallier
...
861 221 Etienne Pallier
862 221 Etienne Pallier
$ ./manage.py inspectdb > models.py
863 221 Etienne Pallier
864 221 Etienne Pallier
=> YES !!!
865 221 Etienne Pallier
</pre>
866 221 Etienne Pallier
867 221 Etienne Pallier
868 221 Etienne Pallier
---
869 205 Etienne Pallier
870 224 Etienne Pallier
h3. Create a Django application named "pyrosapp"
871 224 Etienne Pallier
872 224 Etienne Pallier
From src/ :
873 224 Etienne Pallier
874 224 Etienne Pallier
<pre>
875 224 Etienne Pallier
$ ./manage.py startapp pyrosapp
876 224 Etienne Pallier
</pre>
877 224 Etienne Pallier
878 224 Etienne Pallier
We obtain this structure:
879 224 Etienne Pallier
880 224 Etienne Pallier
<pre>
881 224 Etienne Pallier
882 224 Etienne Pallier
PYROS/
883 224 Etienne Pallier
├── REQUIREMENTS.txt
884 224 Etienne Pallier
├── private/
885 224 Etienne Pallier
│   └── venv_py35_pyros/
886 224 Etienne Pallier
├── public/
887 224 Etienne Pallier
│   └── static/
888 224 Etienne Pallier
├── src/
889 224 Etienne Pallier
│   ├── manage.py
890 224 Etienne Pallier
│   ├── pyros/
891 224 Etienne Pallier
│   │   ├── __init__.py
892 224 Etienne Pallier
│   │   ├── __pycache__
893 224 Etienne Pallier
│   │   ├── settings.py
894 224 Etienne Pallier
│   │   ├── urls.py
895 224 Etienne Pallier
│   │   └── wsgi.py
896 224 Etienne Pallier
│   └── pyrosapp/
897 224 Etienne Pallier
│       ├── __init__.py
898 224 Etienne Pallier
│       ├── admin.py
899 224 Etienne Pallier
│       ├── apps.py
900 224 Etienne Pallier
│       ├── migrations
901 224 Etienne Pallier
│       ├── models.py
902 224 Etienne Pallier
│       ├── tests.py
903 224 Etienne Pallier
│       └── views.py
904 224 Etienne Pallier
905 224 Etienne Pallier
906 224 Etienne Pallier
</pre>
907 224 Etienne Pallier
908 224 Etienne Pallier
---
909 205 Etienne Pallier
910 205 Etienne Pallier
h3. Replace the default pyrosapp models.py with the inspectdb generated one
911 205 Etienne Pallier
912 228 Etienne Pallier
From src/ :
913 228 Etienne Pallier
914 228 Etienne Pallier
<pre>
915 228 Etienne Pallier
$ mv models.py pyrosapp/
916 228 Etienne Pallier
</pre>
917 228 Etienne Pallier
918 228 Etienne Pallier
Add pyrosapp to the project's applications :
919 228 Etienne Pallier
920 228 Etienne Pallier
Edit src/pyros/settings.py
921 228 Etienne Pallier
922 228 Etienne Pallier
<pre>
923 228 Etienne Pallier
INSTALLED_APPS = [
924 228 Etienne Pallier
    'django.contrib.admin',
925 228 Etienne Pallier
    'django.contrib.auth',
926 228 Etienne Pallier
    'django.contrib.contenttypes',
927 228 Etienne Pallier
    'django.contrib.sessions',
928 228 Etienne Pallier
    'django.contrib.messages',
929 228 Etienne Pallier
    'django.contrib.staticfiles',
930 228 Etienne Pallier
    'pyrosapp',
931 228 Etienne Pallier
]
932 228 Etienne Pallier
</pre>
933 228 Etienne Pallier
934 228 Etienne Pallier
---
935 228 Etienne Pallier
936 205 Etienne Pallier
h3. Fix and improve the pyrosapp models.py file (generated by inspectdb)
937 205 Etienne Pallier
938 201 Etienne Pallier
h3. Set Requirements
939 201 Etienne Pallier
940 201 Etienne Pallier
<pre>
941 201 Etienne Pallier
$ pip freeze > REQUIREMENTS.txt
942 201 Etienne Pallier
</pre>
943 182 Etienne Pallier
944 182 Etienne Pallier
945 1 Etienne Pallier
---
946 203 Etienne Pallier
947 203 Etienne Pallier
h3. Initialize the git repository
948 203 Etienne Pallier
949 203 Etienne Pallier
*Git global setup:*
950 203 Etienne Pallier
951 203 Etienne Pallier
<pre>
952 203 Etienne Pallier
$ git config --global user.name "Etienne Pallier"
953 203 Etienne Pallier
$ git config --global user.email "etienne.pallier@irap.omp.eu"
954 203 Etienne Pallier
955 203 Etienne Pallier
$ cat ~/.gitconfig 
956 203 Etienne Pallier
[user]
957 203 Etienne Pallier
	name = Etienne Pallier
958 203 Etienne Pallier
	email = epallier@irap.omp.eu
959 203 Etienne Pallier
[http]
960 203 Etienne Pallier
	sslVerify = false
961 203 Etienne Pallier
</pre>
962 203 Etienne Pallier
963 203 Etienne Pallier
964 203 Etienne Pallier
*Create a new repository:*
965 203 Etienne Pallier
966 203 Etienne Pallier
<pre>
967 203 Etienne Pallier
$ cd PYROS/
968 203 Etienne Pallier
969 203 Etienne Pallier
Define files and folders to be ignored:
970 203 Etienne Pallier
$ vi .gitignore
971 203 Etienne Pallier
.DS_Store
972 203 Etienne Pallier
private
973 203 Etienne Pallier
__pycache__
974 203 Etienne Pallier
975 203 Etienne Pallier
$ touch README.md
976 203 Etienne Pallier
977 203 Etienne Pallier
$ git add README.md
978 203 Etienne Pallier
979 203 Etienne Pallier
$ git commit -m "first commit"
980 203 Etienne Pallier
981 203 Etienne Pallier
$ git remote add origin https://gitlab.irap.omp.eu/epallier/pyros.git
982 203 Etienne Pallier
983 203 Etienne Pallier
$ git push -u origin master
984 203 Etienne Pallier
985 203 Etienne Pallier
$ git add .
986 203 Etienne Pallier
987 203 Etienne Pallier
( if you want to be sure to add ALL files: 
988 203 Etienne Pallier
$ git add -A
989 203 Etienne Pallier
)
990 203 Etienne Pallier
991 203 Etienne Pallier
( if you wanted to remove added files, just type:
992 203 Etienne Pallier
$ git reset HEAD
993 203 Etienne Pallier
)
994 203 Etienne Pallier
995 203 Etienne Pallier
$ git commit -m "first full project commit"
996 203 Etienne Pallier
997 203 Etienne Pallier
$ git push -u origin master
998 203 Etienne Pallier
Counting objects: 43, done.
999 203 Etienne Pallier
Delta compression using up to 4 threads.
1000 203 Etienne Pallier
Compressing objects: 100% (41/41), done.
1001 203 Etienne Pallier
Writing objects: 100% (43/43), 575.13 KiB ö 0 bytes/s, done.
1002 203 Etienne Pallier
Total 43 (delta 2), reused 0 (delta 0)
1003 203 Etienne Pallier
To https://gitlab.irap.omp.eu/epallier/pyros.git
1004 203 Etienne Pallier
   9c7128c..64501c9  master -> master
1005 203 Etienne Pallier
Branch master set up to track remote branch master from origin.
1006 203 Etienne Pallier
1007 203 Etienne Pallier
$ git status
1008 203 Etienne Pallier
On branch master
1009 203 Etienne Pallier
Your branch is up-to-date with 'origin/master'.
1010 203 Etienne Pallier
nothing to commit, working directory clean
1011 203 Etienne Pallier
1012 203 Etienne Pallier
</pre>
1013 231 Etienne Pallier
1014 231 Etienne Pallier
1015 231 Etienne Pallier
---
1016 231 Etienne Pallier
1017 231 Etienne Pallier
h3. Fix and improve the pyrosapp models.py file (generated by inspectdb)
1018 231 Etienne Pallier
1019 231 Etienne Pallier
Once models.py file generated, we need to delete the database and create an empty one :
1020 231 Etienne Pallier
 
1021 231 Etienne Pallier
<pre>
1022 231 Etienne Pallier
$ mysql -u root [-p (if password needed)]
1023 231 Etienne Pallier
1024 231 Etienne Pallier
mysql> DROP DATABSE pyros
1025 231 Etienne Pallier
mysql> CREATE SCHEMA IF NOT EXISTS 'pyros' DEFAULT CHARACTER SET utf8;
1026 231 Etienne Pallier
1027 231 Etienne Pallier
</pre>
1028 231 Etienne Pallier
1029 231 Etienne Pallier
Then edit pyrosapp/models.py :
1030 231 Etienne Pallier
1031 231 Etienne Pallier
 * Change 'managed = False' to 'managed = True' for every model
1032 231 Etienne Pallier
1033 231 Etienne Pallier
 * Change classes names to CamelCase (do not change the 'db_table = ...' lines). *Be careful* : it is needed to change all occurences :
1034 231 Etienne Pallier
1035 231 Etienne Pallier
    * NrtAlanysis
1036 231 Etienne Pallier
    * ScheduleHistory
1037 231 Etienne Pallier
    * ScientificProgram
1038 231 Etienne Pallier
    * SequenceType
1039 231 Etienne Pallier
    * SiteWatch
1040 231 Etienne Pallier
    * SiteWatchHistory
1041 231 Etienne Pallier
    * StrategyObs
1042 231 Etienne Pallier
    * UserLevel
1043 231 Etienne Pallier
    * WeatherWatch
1044 231 Etienne Pallier
    * WeatherWatchHistory
1045 231 Etienne Pallier
1046 231 Etienne Pallier
 * Change the deleting mode from 'models.DO_NOTHING' to 'models.CASCADE' for the following foreign keys :
1047 231 Etienne Pallier
1048 231 Etienne Pallier
    * Image.plan
1049 231 Etienne Pallier
    * Plan.album
1050 231 Etienne Pallier
    * Album.sequence
1051 231 Etienne Pallier
    * Sequence.request
1052 231 Etienne Pallier
1053 231 Etienne Pallier
 * Change the 'ForeignKey' liaisons to 'OneToOneField' liaisons (just replace ForeignKey by OneToOneField), and change deleting mode to 'models.CASCADE' for the following foreign keys :
1054 231 Etienne Pallier
1055 231 Etienne Pallier
    * Alert.request
1056 231 Etienne Pallier
    * Detector.device
1057 231 Etienne Pallier
    * Filter.device
1058 231 Etienne Pallier
    * Telescope.device
1059 231 Etienne Pallier
1060 231 Etienne Pallier
 * We need to redefine many to many relationships for the following classes :
1061 231 Etienne Pallier
1062 231 Etienne Pallier
    * User - ScientificProgram :
1063 231 Etienne Pallier
1064 231 Etienne Pallier
        * add 'users = models.ManyToManyField('User')' in ScientificProgram class
1065 231 Etienne Pallier
        * delete UserHasScientificProgram class
1066 231 Etienne Pallier
1067 231 Etienne Pallier
    * Sequence - ScheduleHistory
1068 231 Etienne Pallier
1069 231 Etienne Pallier
        * add 'sequences = models.ManyToManyField('Sequence')' in ScheduleHistory class
1070 231 Etienne Pallier
        * delete ScheduleHasSequences class
1071 231 Etienne Pallier
1072 231 Etienne Pallier
1073 231 Etienne Pallier
 * For each ForeignKey and ManyToManyField creation in models.py, add the 'related_name=[...]' named parameter, as in the following examples :
1074 231 Etienne Pallier
1075 231 Etienne Pallier
<pre>
1076 231 Etienne Pallier
class Sequence(models.Model):
1077 231 Etienne Pallier
    request = models.ForeignKey(Request, models.CASCADE, related_name="sequences")
1078 231 Etienne Pallier
    sequencetype = models.ForeignKey('SequenceType', models.DO_NOTHING, related_name="sequences")
1079 231 Etienne Pallier
    schedule = models.ForeignKey(Schedule, models.DO_NOTHING, related_name="sequences")
1080 231 Etienne Pallier
    name = models.CharField(max_length=45, blank=True, null=True)
1081 231 Etienne Pallier
    desc = models.TextField(blank=True, null=True)
1082 231 Etienne Pallier
    ...
1083 231 Etienne Pallier
1084 231 Etienne Pallier
class ScheduleHistory(models.Model):
1085 231 Etienne Pallier
    sequences = models.ManyToManyField('Sequence', related_name='schedulehistorys')
1086 231 Etienne Pallier
    created = models.DateTimeField(blank=True, null=True)
1087 231 Etienne Pallier
    ...
1088 231 Etienne Pallier
1089 231 Etienne Pallier
</pre>
1090 231 Etienne Pallier
1091 231 Etienne Pallier
 * Finally apply modifications to the database :
1092 231 Etienne Pallier
1093 231 Etienne Pallier
<pre>
1094 231 Etienne Pallier
$ pwd
1095 231 Etienne Pallier
.../PYROS/src
1096 231 Etienne Pallier
$ python manage.py makemigrations pyrosapp
1097 231 Etienne Pallier
$ python manage.py migrate
1098 231 Etienne Pallier
</pre>
1099 231 Etienne Pallier
1100 231 Etienne Pallier
---
1101 233 Etienne Pallier
1102 234 Etienne Pallier
h3. CONFIGURATION of the Django Back Office (administration interface)
1103 234 Etienne Pallier
1104 234 Etienne Pallier
cf https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#IV-CONFIGURATION-of-the-Django-Back-Office-administration-interface