✏️ 编辑:Welcome.orig.xml
路径:
/virtual/bigbrother/public_html/edream-c.com/cr/DOCUMENTATION/Welcome.orig.xml
大小:42.2 KB · 修改:2014-04-13 19:50:28 · 权限:0644 · 可写
← 返回目录
👁 查看
⬇ 下载
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>TOMUSS Technical Reference</title> </head> <style> object.svg { overflow: hidden ; background-color: #EEE; } pre { background-color: #EEE; border: 1px solid black; padding: 0.2em ; } table td { vertical-align: top ; } div.toc * { font-weight: normal ; margin: 0em;} div.toc h2 { font-size: 80% ; margin-left: 2em ; } div.toc h3 { font-size: 80% ; margin-left: 4em ; } table { border-spacing: 0px ; } table.plugin td { white-space: nowrap ; } table.plugin svg { width: 16px ; height: 110px} table.plugin svg text { font-size: 12px; font-family:sans ; font-weight: normal; text-anchor: start ; fill: black; } table.plugin svg:hover text { stroke-width: 3px; stroke: #0F0; stroke-opacity: 0.4; } @media print { body { margin-left: 5mm ; margin-right: 5mm ; } } </style> <body> <h1><a href="http://perso.univ-lyon1.fr/thierry.excoffier/TOMUSS/home.html">TOMUSS</a> Technical Reference</h1> <p> Table of content: </p> <div class="toc"> _INCLUDE_ xxx_toc.html </div> <object data="global.svg" class="svg"></object> <p> Some glossary : </p> <ul> <li> UE: a course (in french: <em>Unité d'Enseignement</em>)</li> <li> Year: the administrative year (the real year not the teaching start year)</li> <li> Semester: A span of time in the year. They do not overlap. Year+Semester+UE defines an instance of courses with its set of students. </li> <li> Etape: A code defining the registration of the student to a diploma (or a year in a diploma). </li> <li> Referent: A teacher that is linked to a student as a tutor. </li> <li> ABJ: it is a justification of a non attendance for a span of time given by a student to the administration.</li> <li> TT or 'Tiers Temps': it is a student with 'special examination condition'. For exemple for blind students or a student with a broken arm.</li> <li> DA or 'Dispense d'assiduité': If the student has one, the he is allowed to not attend the courses.</li> </ul> <h2><a name="organisation">TOMUSS file organisation</a></h2> <p>The first part describes the hierarchy created by the default installation script and the second part describes the hierarchy of the running servers.</p> <p>You may skip the first part is you only want to test TOMUSS</p> <h3><a name="organisation1">The over top file organisation</a></h3> <p> The hierarchy created by the installation tree insure that a running server can be stopped and an older version of the server can be quickly started without data loss. </p> <p> The installation script may use 2 directories, one for the server and one for the backup server. They store exactly the same things (except temporary and log files). The database stay synchronized in the two directories. </p> <ul> <li> <b>SERVEUR_NOTES</b> The last server version.</li> <li> <b>LOGS</b> The log files.</li> <li> <b>TMP</b> The temporary files.</li> <li> <b>Trash</b> The deleted tables.</li> <li> <b>TOMUSS_DB</b> The tables.</li> <li> <b>TOMUSS.YYYY-MM-DD_HH:MM:SS</b> Older versions of the server</li> </ul> <h3><a name="organisation2">Running server file organisation</a></h3> <p>If the installation script is used, the following directories are symbolic links to the version independant directories.</p> <ul> <li><b>DB</b>: Where the data are stored.</li> <li><b>LOGS</b>: The logs and statistics of the servers</li> <li><b>TMP</b>: Data files generated by program, but costly to create.</li> <li><b>Trash</b>: Where are moved the deleted tables</li> </ul> <p>The top level directories</p> <ul> <li><b>DB</b>: Where the data are stored.<br/> <b>BACKUP_DB</b>: Where the backup is stored. <ul> <li> One directory per year named <b>Y9999</b> </li> <li> One directory named <b>Y0</b> for year independent data.</li> <li> <b>CLOSED/???/---UE CODE---</b> stores the semester for which the UE seems to be close</li> <li> <b>RSSLOGINS/???/---RSS_KEY---</b> contains the login associated to the key.</li> <li><b>LOGINS/???/login</b>: Directory with user data. <ul> <li> <b>favstu</b> Favorite student list</li> <li> <b>master_of</b> The user is the master of theses UEs</li> <li> <b>pages</b> Favorites UE</li> <li> <b>signatures</b> list of questions/contract of the student</li> <li> <b>rsskey</b> Key used to read RSS stream without login</li> <li> <b>old_referent</b> The last referent of the student</li> <li> <b>resume</b> an abstract of all the student grades in TOMUSS</li> <li> <b>indexes</b> All the table in which the student appears</li> </ul> </li> </ul> </li> <li><b>FILES</b>: The static files sended by the server. They are automaticaly reloaded when they are modified.</li> <li><b>SCRIPTS</b>: Some scripts mostly local and obsolete except 'install' and 'crontab_run.py'</li> <li><b>TEMPLATES</b>: Defines classes of table.</li> <li><b>REGTEST_CLIENT</b>: An aborted experiment to do regressions tests on any web browser (the browsers do not react deterministicaly).</li> <li><b>REGTEST_SERVER</b>: A working set of regression tests on the server.</li> <li><b>DOCUMENTATION</b>: You are seeing it :-) <ul> <li><b>Makefile</b> The default goal create documentation.</li> <li><b><a href="ChangeLog">changelog</a></b> All the modifications done.</li> <li><b><a href="TODO">TODO</a></b> The things that need to be done</li> <li><b>Welcome.orig.xml</b> The documentation source.</li> </ul> </li> <li><b>PLUGINS</b>: They define how the servers react to an URL</li> <li><b>COLUMN_TYPES</b>: They define define the possible column types.</li> <li><b>ATTRIBUTES</b>: They define the possible column and table attributes.</li> <li><b>TRANSLATIONS</b>: The messages.</li> <li><b>LOCAL</b>: All the customization code and data must be inside. <ul> <li> <b>config.py</b>: Your real configuration</li> <li> <b>LOCAL_TEMPLATES</b>: Your local TEMPLATES directory</li> <li> <b>LOCAL_COLUMN_TYPES</b>: Your local COLUMN_TYPES directory</li> <li> <b>LOCAL_ATTRIBUTES</b>: Your local ATTRIBUTES directory</li> <li> <b>LOCAL_TRANSLATIONS</b>: Your local TRANSLATIONS directory (you can overide existing translations)</li> </ul> </li> </ul> <p>The core of the code</p> <ul> <li><b>Makefile</b>: The goals are <ul> <li><b>start</b>: Starts all the servers.</li> <li><b>stop</b>: Stops all the servers.</li> <li><b>stopsuivi</b>: Stops TOMUSS 'suivi' servers.</li> <li><b>stoptomuss</b>: Stops TOMUSS server.</li> <li><b>restartsuivi</b>: Restarts TOMUSS 'suivi' servers.</li> <li><b>recompute_the_ue_list</b>: Extract the UE list from database and store them in a Python module <tt>TMP/xxx_toute_les_ues.py</tt> and <tt>TMP/all_ues.js[.gz]</tt> This goal can be launched when TOMUSS is running, it will automaticaly reread the informations. </li> <li><b>stat</b>: Display some sources stats</li> <li><b>clean</b>: Delete garbages.</li> <li><b>regtest</b>: Run server regression tests.</li> <li><b>regtest1</b>: Run server regression tests only once</li> <li><b>release</b> : Package a release.</li> </ul> </li> <li><b>configuration.py</b>: configurations variables. <em>Read carefully, but do not modify this file.</em></li> <li><b>tomuss.py</b>: Server managing the tables. Possible parameters are: <ul> <li><b>regtest</b>: server in regtest mode, ticket are in the form '=invited.teacher' or '=super.user'</li> <li><b>profile</b>: compute the time and number of calls of functions.</li> </ul> </li> <li><b>suivi.py</b>: Server allowing the 'suivi'.</li> <li><b>abj.py</b>: All the code needed to manage ABJ, DA, TT.</li> <li><b>authentication.py</b>: The authentication core.</li> <li><b>cell.py</b>: The Cell object</li> <li><b>column.py</b>: The Column, Columns objects</li> <li><b>data.py</b>: Contains the functions used by data files</li> <li><b>document.py</b>: Define the Table and manages the tables.</li> <li><b>files.py</b>: Manage the static files. If a file is modified, it is automaticaly updated in the server (but they may stay in client cache one hour)</li> <li><b>inscrits.py</b>: LDAP connector to retrieve students lists</li> <li><b>plugin.py</b>: Plugin management and URL parsing.</li> <li><b>plugins.py</b>: Load plugins used by the servers.</li> <li><b>referent.py</b>: Manage the 'referent' table.</li> <li><b>tablestat.py</b>: Utility to compute statistics on tables. It manages the list of table used to do the 'suivi'</li> <li><b>teacher.py</b>: Interface to UE (courses) informations.</li> <li><b>ticket.py</b>: Ticket management.</li> <li><b>regtestpatch.py</b>: Loaded if TOMUSS is in regression test mode. It patches the module in order to have no random in server answer.</li> <li><b>objgraph.py</b>: GPL utility to navigate in object graph.</li> <li><b>servers.py</b>: Define the class describing a 'suivi' server.</li> <li><b>utilities.py</b>: Many utilities low level.</li> </ul> <h2><a name="plugins">TOMUSS plugins</a></h2> <p>When a TOMUSS process is started it loads its plugins. The received requests are dispatched to the fittest plugin. The most important attributes of a plugin are. </p> <p>Do not modify <tt>plugins.py</tt> source to add plugins, use a <a href="#local">redefine</a> to add plugins</p> <p> Do not modify global state with plugins because it may cause problems if the plugin is reloaded while the server is running.</p> <h3><a name="url_template">URL template</a></h3> <p> It defines the pattern of the request. For example: <tt>{Y}/{S}/{U}/resume</tt> </p> <p> Here are the components of the URLs and where they are stored in the request object in the server side. </p> <table border="1"> <tr><th>Component</th><th>Attribute name</th><th>Comment</th></tr> <tr><td>{Y}</td><td>the_year</td><td>The year of interest</td></tr> <tr><td>{S}</td><td>the_semester</td><td>The semester of interest</td></tr> <tr><td>{U}</td><td>the_ue</td><td>The course of interest</td></tr> <tr><td>{P}</td><td>the_page</td><td>The <em>page</em> of the table</td></tr> <tr><td>{?}</td><td>something</td><td>Not important</td></tr> <tr><td>{I}</td><td>the_student</td><td>A student identifier</td></tr> <tr><td>{_I}</td><td>the_student</td><td>A student identifier prefixed by _</td></tr> <tr><td>{*}</td><td>the_path</td><td>The remaining of the path</td></tr> <tr><td>{=}</td><td> </td><td>Remove any /=.... from the path</td></tr> <tr><td>{ }</td><td>the_time</td><td>The navigator request time (avoid caching)</td></tr> </table> <h3><a name="plugin_attributes">Plugin attributes</a></h3> <p> Plugin usage can be restricted to a list of user groups using <tt>config_plugins</tt> table, user groups are defined with the <tt>config_acls</tt> table. The <b>default</b> authorized group list contains the value of the <tt>group</tt> parameter. </p> <p> The possible values of the decision attributes are <tt>None</tt> to indicate that it is not important, <tt>True</tt> to indicate that session must match the attribute, <tt>False</tt> to indicate that session must <b>not</b> match the attribute. </p> <ul> <li> Authenticated: The client authenticated itself</li> <li> Password OK: The user has a not stupid password</li> </ul> <p> The action attributes are: </p> <ul> <li> Background: a subprocess must be launched.</li> <li> Keep Open: the client socket should not be closed.</li> <li> Cached: the answer must not be cached by client/proxies.</li> <li> Link: defines if and how the link to the plugin is diplayed on the home page. It is an object with many attributes : text, url, help text, safety, where it is display, authorization test...</li> <li> Mime type and Response: Defines the HTTP header answer.</li> </ul> <h3><a name="plugin_list">Plugin documentation</a></h3> <p> Some of the plugins are used both in TOMUSS and 'suivi' servers. </p> <p> The ``link and position´´ defines the function generating the <tt>HTML</tt> content to insert in an home page. The position specify the name of the box where to insert the code. </p> _INCLUDE_ xxx_doc_plugins.html <h3><a name="plugin_replacement">Plugin replacement</a></h3> <p> If you want to replace a builtin TOMUSS plugin by yours, you must remove the standard one before defining your replacement. To delete the 'picture' plugin: </p> <pre>plugin.plugins.remove(plugin.get("picture"))</pre> <h2><a name="protocols">TOMUSS protocols</a></h2> <p> The client perform action on the server by inserting image objects in the HTML code. The returned image give the user feedback (green: ok, orange: waiting server, red: unauthorized, violet: bug...) </p> <p> The client does not poll server to retrieve changes, but the server send javascript fragment when there is an update to send. </p> <h3><a name="protocol_tomuss">TOMUSS client/server protocol</a></h3> <p> The client load the documents as usual. But if the document is a table: </p> <ul> <li> The socket is not closed, so the client will receive live table update as javascript commands.</li> <li> an unique <em>page</em> identifier is created, all the modification and identifiers will be associated with this unique identifier so there is no possible naming conflict.</li> <li> a <em>request identifier</em> is initied. It will be used to sort the requests by time.</li> <li> Subsequent requests from the client to modifiy the table are images load, the image URL contains all the transaction information and the returned image itself is the feedback.</li> </ul> _INCLUDE_ xxx_tomuss_plugins.html <h3><a name="protocol_suivi">TOMUSS suivi client/server protocol</a></h3> _INCLUDE_ xxx_suivi_plugins.html <h2><a name="storage">TOMUSS storage</a></h2> <p> The table data is stored as a Python module, the module source is only modified by doing an append to prevent any data loss. File size is checked before and after append to insure that the data was really saved. </p> <p> All the TOMUSS data are stored in two files, so two identical hierarchies are managed. </p> <h3><a name="table_storage">Table storage</a></h3> <p> The columns and lines are identified by a key usualy created as: page_id + '_' + number. With this scheme, two identical keys are not possible. </p> <p> The functions to modify the table are: </p> _INCLUDE_ xxx_data.html <h3><a name="abj_storage">ABJ + DA storage</a></h3> <p>Informations about ABJ and DA are stored in one key file per student. The parameters are:</p> <ul> <li> '<b>login</b>' The student identifier</li> <li> '<b>from</b>', '<b>to</b>' Start and end date of the justification (DD/MM/YYYY[MA]) M=Morning A=Afternoon</li> <li> '<b>date</b>' (DD/MM/YYYY) Start of the dispense of assiduity.</li> <li> '<b>user_name</b>', '<b>action_date</b>' The user that modified the information and when.</li> </ul> <p> The functions to modify the data are: </p> <pre>add (login, from, to , user_name, action_date) rem (login, from, to , user_name, action_date) add_da(login, ue , date, user_name, action_date) rem_da(login, ue , user_name, action_date) </pre> <h3><a name="tt_storage">TT storage</a></h3> <p>The information about 'Tiers Temps' are stored in a normal table, the columns order must not be modified. There is a line per student.</p> <h3><a name="referent_storage">Referent storage</a></h3> <p>The information about referents teacher are stored in a normal table named 'orientation_rp'. Each line contains the teacher login, its portals. </p> <p>The list of students per referent is stored in 'referents_students' table </p> <h2><a name="objects">TOMUSS objects server side</a></h2> _INCLUDE_ xxx_objects.html <h3><a name="column_types">Types of columns</a></h3> <p> They are defined in <tt>COLUMN_TYPES</tt> directory. To add a new column type, the only thing to do is to add 2 new files in <tt>COLUMN_TYPES</tt>. There is a Python and a JavaScript file per type. Types are defined by a class tree. </p> <p><a href="xxx_type2.html">The table of types</a> display for each types how to manage the column and the cell. More explanations are in the <tt>text.py</tt> file. </p> <h2><a name="column_attributes">Attributes of table columns</a></h2> _INCLUDE_ xxx_column_attr.html <h2><a name="table_attributes">Attributes of tables</a></h2> _INCLUDE_ xxx_table_attr.html <h2><a name="serverthreads">TOMUSS server side threads</a></h2> <p> The server need informations from other servers, in order to be responsive, the requests must be performed in threads. To simplify the program, there is a single thread per data type to be updated. </p> <ul> <li> <b>authentication_thread</b>: It verifies the user identity and redirect the browser if it is not known.</li> <li> <b>check_send_queue</b>: In order to not block the server if a client is slow to receive the data, the send action is performed in a thread. The thread read a FIFO to get its job.</li> <li> <b>check_new_students</b>: The thread read a FIFO to get its job. It launches the 'check' function of the UE template in order to update the student list and informations.</li> <li> <b>check_students_in_tables</b>: periodicaly push job to the 'check_new_students' thread. The push interval is <tt>configuration.students_check_interval</tt> </li> <li> <b>check_requests</b>: The thread read a FIFO to get its job. It's this thread that perform all actions on a table. The requests stays in the FIFO if there is a missing request. It may happen because image loading in the browser is not sequential.</li> </ul> <p> Some external processes launched by <tt>crontab</tt> compute some files periodicaly. TOMUSS reread the file is they appear to be modified. </p> <h2><a name="client">TOMUSS client side</a></h2> <p> A maximum of work is done by the client, for exemple, average and other computation are not done by the server. </p> <h3><a name="clienthome">The home page</a></h3> <p> The page is generated by the 'home2' plugin. </p> <p> Most of the URL are computed with a small javascript function who take the current semester/year from the user selection and append the current ticket. </p> <p> The page template is stored in '<tt>top2.html</tt>' file.</p> <h3><a name="clienttable">The table editing page</a></h3> <p> The client load the page that stay open in order to receive updates as JavaScript codes. The client actions are done by inserting image, the image is inserted where the user interaction took place and at the right of the 'cell' tab. It is done so because, an image must stay visible when the user change of page or filter the table. The image is at the same time the server feedback indicating if the action performed well. </p> <p> The server, indicate that the action was performed with a javascript code. When the client receive this code, it removes the matching images at the right of the 'cell' tab. In the normal case, there is no image at this place. </p> <p> If an image is not loaded after some time, the image URL is modified in order to retry the aborted load because navigator do not retry failed loads. </p> <p> If image loads fails and the server is active, then we assume that communication fails because the ticket is no more valid (IP change for example). In this case, the user is asked to authenticate once more. </p> <h3><a name="clientobjects">Client side objects</a></h3> <p> As TOMUSS started as a trivial program, it was not developed with JavaScript objects. The only objects are:</p> <ul> <li> '<b>UE</b>': matches the informations from the Python UE object.</li> <li> '<b>Cell</b>': The table cell.</li> <li> '<b>Current</b>': The management of the current cell in the screen.</li> <li> '<b>Stats</b>': An object allowing to compute statistics.</li> <li> '<b>Request</b>': Allow fiable communication with the server.</li> <li> '<b>types[]</b>': Defines all the columns types.</li> <li> '<b>columns[]</b>': Defines the columns, needs methods to be really an object.</li> </ul> <p> A Table object should be added in order to clean the code. </p> <h3><a name="virtualtables">Virtual tables</a></h3> <p> These tables are not stored into files. They can be : </p> <ul> <li> Server side : See '<b>PLUGIN/resume.py</b>' as a template.</li> <li> Client side : See '<b>FILES/lib.js/statistics_per_group</b>' as a template.</li> </ul> <h3><a name="suivipage">'Suivi' page composition</a></h3> <p> The 'Display' framework is currently only used by the 'suivi' page. It allows to add new informations on the 'suivi' page without modifying code source code. Display trees are defined in <tt>PLUGINS/suivi_student.py</tt>, for example, the information about the 'more_on_suivi' plugin is defined as: </p> <pre>from .. import display # The display framework def display_more_on_suivi(server): return configuration.more_on_suivi(server.suivi_login, server) display.display('MoreOnSuivi', 'BodyRight', 9, data=display_more_on_suivi) </pre> <ul> <li> <tt>MoreOnSuivi</tt>: The box identifier.</li> <li> <tt>BodyRight</tt>: The container box identifier. It is possible to have multiple containers, eg. <tt>['Top','Private','Question']</tt> So the same display tree can be used in multiple places in the page or in different pages. </li> <li> <tt>9</tt>: The priority used to sort the item in the container. It can be a float number. </li> <li> <tt>data=display_more_on_suivi</tt>: the data returned by this function is sent to the browser. These functions are profiled in order to send fast-computed values first. <b>So the call order is random</b>. </li> <li> It is possible to add the parameter <tt>js='Vertical'</tt> to call 'DisplayVertical' javascript function to compute the HTML. Or horizontal by the way.</li> </ul> <p> On the javascript side <tt>PLUGINS/suivi_student.js</tt>: </p> <pre>function DisplayMoreOnSuivi(node) { // To use the data from Login display plugin : display_data['Login'] // If 'is_a_teacher' is true, it is the teacher view. // To hide the block from screen: return '' return node.data ; // Display the server computed content without change // It is possible to return values to insert in the container-DIV attributes // return ["HTML to display", [classes...], [styles...], "other attrs"] // see DisplayCellBox for an usage example } // Defines the data needed from other display plugin. // The plugin will be called once data is retrieved from server. // The default value for this function is itself: ['MoreOnSuivi'] // It is possible to wait data from multiple plugins: // <b>DisplayMoreOnSuivi.need_node = ['MoreOnSuivi', 'Login'] ;</b> // If no data is needed, use an empty required list: []</pre> <p> On the CSS side <tt>PLUGINS/suivi_student.css</tt>: </p> <pre>.MoreOnSuivi { background: white }</pre> <p> The <tt>node</tt> object has following attributes: name, children, containers, priority. </p> <p> On the javascript side, a display function can call other display function multiple times. For example <tt>DisplayUEGrades</tt> call <tt>CellBox</tt> to display each grade. </p> <h2><a name="translation">TOMUSS Translation</a></h2> <p> If the user has not defined its language in its preferences, it is the browser languages that is taken. The <b>server</b> default language is used to created table for column names, comments, value of literals as YES, NO... </p> <p> The translations are in TRANSLATIONS and LOCAL/LOCAL_TRANSLATIONS directories. The LOCAL translation override the default translation. </p> <p> some message ID are not in the source code because they are computed. for example for the column types and the attributes. </p> <p> Message ID format is usualy in this form: TYPE_PLUGIN_ID where TYPE is</p> <ul> <li> ALERT : displayed in an alert box in the browser (no HTML)</li> <li> ASK : displayed in a confirm box in the browser (no HTML)</li> <li> TIP : displayed in a tip message</li> <li> TH : an HTML TH header</li> <li> B : a button text in the interface</li> <li> BEFORE : a label before an input area</li> <li> COL_TITLE : a template column title</li> <li> COL_COMMENT : a template column comment</li> <li> TABLE_COMMENT : a template table comment</li> <li> ERROR : an error message</li> <li> LINK : the text in the home page link for the plugin</li> <li> HELP : the tip in the home page link for the plugin</li> <li> MESSAGE :</li> <li> TITLE : a page title (no HTML)</li> <li> MSG : a text</li> <li> SUIVI : a text on the 'suivi' page</li> <li> TAB : a tab title</li> </ul> <h2><a name="administration">TOMUSS Administration</a></h2> <h3><a name="semester">Semesters</a></h3> <p> TOMUSS retrieves the <b>current student list</b> without knowing to which semester it applies. </p> <p> The procedure to change of semester is the following: </p> <table border="1"> <tr><th>When</th><th>What</th></tr> <tr> <td> You want to use the next semester </td> <td> In your local configuration file, add the new semester with a new port number :<br/> <tt>suivi.add(2009, 'Automne' , socket.getfqdn() + ':%d', 8891)</tt> <br/> You can indicate the same port number for multiple semesters, in this case, only one process is launched for these semesters. <br/> Set the next semester name in '<tt>year_semester_next</tt>' in the TOMUSS configuration table. <p> The tables are editable in both semesters. But current student lists do not appear in the next semester. </p> <p> Il you want to update student lists for the next semester, add it to <tt>year_semester_update_student_list</tt> in the configuration table. </p> </td> </tr> <tr> <td> New lists of students are accessible. </td> <td> <p> Set '<tt>year_semester</tt>' to the same value than '<tt>year_semester_next</tt>'. </p> <p> Copy the 'referents_students' table in the new semester. </p> <p> Restart TOMUSS: <tt>make stop ; make</tt> </p> <p> Il you want to continue update student lists for in the old semester, add it to <tt>year_semester_update_student_list</tt> in the configuration table. </p> <p> Il you want to allow the previous semester tables to be editable, add it to <tt>year_semester_modifiable</tt> in the configuration table. </p> </td> </tr> </table> <p> If the table of the previous semester must be modifiable by default, you can indicate it in the configuration table in the modifiable semester list. The current and next semester are modifiable by default. </p> <h3><a name="templates">Table templates</a></h3> <p>Table templates are stored in 'TEMPLATES' directory. When loading a page, if the file match a template it is applied, if the semester match a template it is applied. Only one template can be applied. The templates may defines : </p> <ul> <li> '<b>create</b>': How the table is initialized on creation.</li> <li> '<b>init</b>': A hook called before table is loaded.</li> <li> '<b>onload</b>': A hook called after table is loaded.</li> <li> '<b>content</b>': A function returning the Javascript code to be appended to web page. </li> <li> '<b>check</b>': A function updating the student list in the table.</li> <li> '<b>cell_change</b>', <b>column_change</b>: A function called on cell content change or column_change. It must not use external services because it must return quickly. If this function raise an exception, the value will not be stored in the table. </li> <li> '<b>css</b>': A string containing CSS for the table</li> </ul> <p> Semester templates defined are: </p> <ul> <li> '<b>LOCAL/LOCAL_TEMPLATES/Example.py</b>' is a commented template. Create your own templates from this simple one. </li> <li> '<b>Printemps</b>', '<b>Automne</b>','<b>Test</b>' are standard table to enter data about students.</li> <li> '<b>Preferences</b>' is the standard table to enter user preferences.</li> <li> '<b>Referents</b>' is the definition of the referent teacher notepad.</li> <li> '<b>Favoris</b>' is the definition of the favoris notepad.</li> <li> '<b>Dossiers</b>' is the definition of an empty table modifiable only by the user that created it.</li> <li> '<b>Test</b>' this semester contains real students but it is a sandbox allowing to try anything.</li> <li> '<b>Variables</b>' this semester contains configuration variable table for Templates and Plugins.</li> </ul> <p> Table templates defined are: </p> <ul> <li> '<b>config_table</b>' the TOMUSS configuration.</li> <li> '<b>config_plugin</b>' the TOMUSS plugin access list.</li> <li> '<b>config_acls</b>' the TOMUSS user group tree.</li> <li> '<b>config_home</b>' defines the links on TOMUSS home page. that are not associated with Plugins</li> <li> '<b>ticket</b>' store the live tickets.</li> <li> '<b>tt</b>' create the table used to enter TT.</li> <li> '<b>average</b>' create a test table about averages.</li> <li> '<b>referents_students</b>' define the association between referent teachers and their students.</li> <li> '<b>test_type</b>' create a test table about column types.</li> </ul> <p> The table template must be created in order to match the teaching organisation. </p> <p> Do not store information in the module itself because it will be lost when the TEMPLATE is reloaded (it is triggered by a file change). </p> <p> The recommended way to define columns in a template is the table method <tt>update_columns</tt>. It will create and update columns definitions. </p> <p> If you have configuration parameters associated to your Plugin/Template it is a good idea to use 'utilities.Variables' in order to associate the values to the TOMUSS table '0/Variables/template_name' So the user can change the configuration at running time. You can give access rights to this table to non-root users. </p> <h3><a name="authentication">Authentication process</a></h3> <p> The URLs start by a ticket. If there is no ticket, the navigator is redirected to a service in order to get a ticket. <em>If CAS is not used, then a random ticket number is generated.</em> </p> <p> The tickets are ``exchanged´´ between the TOMUSS processes as a python module containing all the valid tickets. </p> <p> To be valid, a ticket must be used with the same navigator and the same IP than the first time. </p> <p> 'ticket.py' define the ticket object that store tickets and parse URLs. It is a generic and not configuration dependant. </p> <p> A new ticket can be used to revalidate an old ticket, it is useful if the client IP changed. </p> <p> 'authentication.py' can be redefined by a local plugin in order to have the good code for the functions 'ticket_login_name' and 'ticket_ask'. <em>If CAS is not used, then these functions assume that the authentication is done with Apache/.htaccess/.htpasswd with the <tt>Basic</tt> authentication method (the clear password is checked with <tt>su</tt>)</em> </p> <p> In <tt>regtest</tt> mode, the URLs accept <tt>=username</tt> as a valid ticket for the user. </p> <h3><a name="apache">Apache/NGINX configuration</a></h3> <p> If you have multiple suivi servers, then the configuration must be updated when there is a new suivi server. If you have only one suivi server for all the semesters, then no change is needed. </p> <p> TOMUSS urls are for example: </p> <ul> <li> <tt>http://tomuss1.fr:8888/</tt> The main process</li> <li> <tt>http://tomuss2.fr:8889/</tt> 'Suivi' for Automne 2008</li> <li> <tt>http://tomuss3.fr:8890/</tt> 'Suivi' for Printemps 2009</li> </ul> <p> To have TOMUSS working with nicer URLs we can configure Apache as: </p> <pre><VirtualHost tomuss.fr:80> ServerName tomuss.univ-lyon1.fr RewriteEngine On # It is the web server (not TOMUSS) that send the static files (UNTESTED) RewriteRule ^/files/([0-9.]+)/(.*) /home/tomuss/TMP/$1/$2 [L] RewriteRule ^(.*) http://tomuss1.fr:8888$1 [P] </VirtualHost> <VirtualHost tomusss.fr:80> ServerName tomusss.univ-lyon1.fr RewriteEngine On RewriteRule ^(.*/2009/Printemps/.*) http://tomuss3.fr:8890$1 [P] RewriteRule ^(.*/2008/Automne/.*) http://tomuss2.fr:8889$1 [P] # 'Suivi' on the current semester RewriteRule ^(.*) http://tomuss2.fr:8889$1 [P] </VirtualHost> </pre> <p> We can configure NGINX with:</p> <pre>proxy_buffering off; # To be really interactive proxy_read_timeout 1000000; # To keep connection open server { listen 80; server_name tomuss.fr; # It is the web server (not TOMUSS) that send the static files location ~ ^/files/ { root /home/tomuss/TMP ; # Must be readable by NGINX add_header Cache-Control "max-age=86400"; if ( $request_uri ~* "\.gz$" ) { add_header Content-Encoding gzip; add_header Cache-Control "max-age=86400"; } rewrite ^/files/([0-9.]+)/([^/]*) /$1/$2 break ; } location / { proxy_pass http://tomuss1.fr:8888; } } server { listen 80; server_name tomusss.fr; location / { proxy_pass http://tomuss3.fr:8890/2009/Printemps/; } location ~ ^/(=[^/]*/)?2009/Printemps { proxy_pass http://tomuss3.fr:8890; } location ~ ^/(=[^/]*/)?2008/Automne { proxy_pass http://tomuss2.fr:8889; } } </pre> <p> With this, the URLs become: </p> <ul> <li> <tt>http://tomuss.fr/</tt> The main process</li> <li> <tt>http://tomusss.fr/2008/Automne/</tt> 'Suivi' for Automne 2008</li> <li> <tt>http://tomusss.fr/2009/Printemps/</tt> 'Suivi' for Printemps 2009</li> </ul> <h3><a name="configuration">TOMUSS configuration</a></h3> <p> The initial TOMUSS configuration is stored in <tt>configuration.py</tt>. <tt>DB</tt> is the production database name. </p> <p> <b><tt>configuration.py</tt> must not be modified because it will be overwrited by each TOMUSS release.</b> The file <tt>LOCAL/config.py</tt> must be edited to customize and configure TOMUSS. </p> <p> This customization is done by replacing default functions by yours. For the UCBL university there is:</p> <pre># The login and the student ID are not the same at the UCBL # login_to_student_id, the_login, login_to_id (JavaScript) from . import student_id # get_ue_dict: Retrieve all the informations about all the UE from . import spiral if not regtest: # ticket_login_name: Get login name from ticket # ticket_ask: redirect the browser to ask a ticket from . import auth # stupid_password: Returns True if the password is stupid from . import checkpassword # students: Iterator on all the students of an UE, returns : # (student_id, firstname, surname, mail, group, sequence) from . import students_of_ue </pre> <p> Most of the configuration values are modifiable while TOMUSS is running by editing as 'root' the table named '<tt>http://......../0/Dossiers/config_table</tt>' The values in this table have precedence over values stored in the configuration source files. Nevertheless the first time, this table is created using the configuration source files </p> <h3><a name="authorization">TOMUSS authorizations</a></h3> <p> The home page of root user contains a link on the plugin configuration table. For each plugin, you can indicate a list of allowed <b>item</b> : </p> <ul> <li> An user: 'login'</li> <li> An user group: 'grp:group_name' (defined in the ACLS table)</li> <li> An LDAP group: 'ldap:OU=...DC=...'</li> <li> A Python expression: 'python: "teacher" in login'</li> </ul> <p> It is recommended to use group name because most of the time, a few plugins have the same users allowed. The user groups are defined in the config ACLS table. On the first column you enter an <b>item</b> as in the plugin table, on the second column, you indicate to which group you add the item. </p> <p> If a group contains items prefixed by '!', then they evaluated first, and if the user is contained in the group, it will be rejected. There is an exception: if the group or list contains only one '!' item, then it returns True if the user is not in the group. </p> <p> Example displayed as a tree:<pre> staff * ldap:GROUP_X # Evaluated after !, so some user may be rejected * !FORBIDEN # Define the list of forbidden users * ldap:GROUP_Y * !USER_A # It will not be in FORBIDEN * !grp:teachers # No teachers in FORBIDEN * teachers * ldap:GROUP_T * USER_B * administratives # FORBIDEN is tested before administrative * ldap:GROUP_A # If users are in GROUP_Y they will not * USER_C # be in 'administrative' group (even USER_C) </pre> </p> <h3><a name="regtests">TOMUSS Regressions Tests</a></h3> <p> The makefile goal <tt>regtest</tt> run an infinite loop on some server tests. The loop is broken if there is a problem. </p> <p> The <tt>URL http://SERVER/2009/Test/javascript_regtest_ue</tt> run some javascripts tests on the user interface. These tests works on FireFox and Opera but not on IE. </p> <h3><a name="startstop">TOMUSS starting and stopping</a></h3> <p>The makefile goals <tt>start</tt> and <tt>stop</tt> allow to manage the TOMUSS services. There is one database modification service and one 'suivi' service per semester in order to not have huge processes. The 'suivi' processes are huge because they load the full semester in memory.</p> <p> UPDATE SINCE Version 5.2.0: once students are indexed by <tt>SCRIPTS/bilan.py</tt> the 'suivi' process do not load complete semester but only needed tables. In this case only one 'suivi' process is needed. To use only one process, use the same <tt>port</tt> for all the semesters. </p> <h3><a name="install">TOMUSS install on production server</a></h3> <p> The goal <tt>install</tt> of the <tt>Makefile</tt> runs the script <tt>install</tt> that do all the work to replace a running TOMUSS by the new release. <b>IT IS A VERY BAD IDEA TO RUN THIS SCRIPT WITHOUT UNDERSTANDING IT</b>. </p> <ul> <li> The script contains the two directories where TOMUSS programs and databases must be copied.</li> <li> At any time, the current version can be stopped and an older restarted because all versions are kept.</li> <li> When running, the two databases are perfectly synchronized.</li> <li> When installing a new version, the synchronisation is verified.</li> <li> If the active directory is no more accessible, the backup directory is usable without modification.</li> <li> The installation process configure <tt>crontab</tt> in order to: <ul> <li> restart automaticaly stopped programs,</li> <li> make daily backup,</li> <li> create statistics charts,</li> <li> update 'xxx_toute_les_ues.py', 'all_ues.js'.</li> </ul> </li> </ul> <p> Two symbolic links (<tt>DB</tt> and <tt>BACKUP_DB</tt>) points on directory where the database is stored. </p> <p> Required packages : python-ldap, python-imaging, gzip, inkscape, gettext </p> <p> Recommended packages : gnuplot, graphviz, rsync (distant mirroring), catdoc (csv extract from xls) </p> <h3><a name="manage">TOMUSS managing</a></h3> <p> The TOMUSS <tt>root</tt> can use the following features: </p> <ul> <li> Interactively browse the python server object memory.</li> <li> Compute the favorite list for the semester once there is some data.</li> <li> Remove tables without any user generated content.</li> <li> See the live log of server actions.</li> <li> See the time statistics about the servers functions.</li> <li> See the tickets alive.</li> </ul> <p> Some non automatic work to do: see <tt>LOCAL/Makefile</tt> </p> <h2><a name="pitfall">TOMUSS Pitfall</a></h2> <p>When loading a Python module, never store the 'configuration' values in local variables because the configuration module may not be fully loaded.</p> <p>Use the function 'unload_module' to unload a Python module in order to not have a memory leak.</p> <p>Never modify the database files if the table is loaded in the TOMUSS server.</p> <h2><a name="local">Functions to redefine in order to customize TOMUSS</a></h2> <p> If you want your TOMUSS customization to not be destroyed by a version change you must follow the procedure. The functions listed are the ones that you need to modify, but you can modify any function you want. </p> <table><tr><td><p> In the following table the javascript functions must not be modified in the javascript source, they can be redefined by <tt>LOCAL/config.py</tt> script using this procedure: </p> <pre>import files files.files['lib.js'].append("a_key", """ function the_function_to_be_redefined() { } """</pre> </td><td><p> The Python function must not be modified in the Python sources, they must be redefined in <tt>LOCAL/config.py</tt> script using this procedure: </p> <pre>import a_module old_one = a_module.to_be_redefined def to_be_redefined(): old_one() a_module.to_be_redefined = to_be_redefined </pre></td></tr></table> _INCLUDE_ xxx_redefined.html </body> </html>
💾 保存
取消
保存为 UTF-8,换行统一为 LF