Version 15.38.1

This commit is contained in:
Antonio Cañas Vargas 2015-11-14 16:54:43 +01:00
parent 2bf5a0929c
commit 7758759ed9
8 changed files with 1581 additions and 242 deletions

View File

@ -32,7 +32,7 @@ body
margin:0;
background-color:white;
font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;
font-size:1.25em;
font-size:1em;
}
input {font-size:12pt; vertical-align:middle;}
select {font-size:12pt;}

File diff suppressed because it is too large Load Diff

View File

@ -422,11 +422,10 @@ mysql> DESCRIBE centres;
| RequesterUsrCod | int(11) | NO | | -1 | |
| ShortName | varchar(32) | NO | | NULL | |
| FullName | varchar(127) | NO | | NULL | |
| Logo | varchar(16) | NO | | NULL | |
| WWW | varchar(255) | NO | | NULL | |
| PhotoAttribution | text | NO | | NULL | |
+------------------+--------------+------+-----+---------+----------------+
10 rows in set (0.01 sec)
9 rows in set (0.00 sec)
</pre>
<h3>Table chat</h3>
@ -1923,42 +1922,43 @@ mysql> DESCRIBE usr_IDs;
</p>
<pre>
mysql> DESCRIBE usr_data;
+-----------------+---------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------------------------+------+-----+---------+----------------+
| UsrCod | int(11) | NO | PRI | NULL | auto_increment |
| EncryptedUsrCod | char(43) | NO | UNI | NULL | |
| Password | char(86) | NO | | NULL | |
| Surname1 | varchar(32) | NO | | NULL | |
| Surname2 | varchar(32) | NO | | NULL | |
| FirstName | varchar(32) | NO | | NULL | |
| Sex | enum('unknown','female','male') | NO | | unknown | |
| Layout | tinyint(4) | NO | MUL | 0 | |
| Theme | char(16) | NO | MUL | NULL | |
| IconSet | char(16) | NO | MUL | NULL | |
| Language | char(2) | NO | MUL | NULL | |
| Photo | char(43) | NO | | NULL | |
| PublicPhoto | enum('N','Y') | NO | | N | |
| CtyCod | int(11) | NO | MUL | -1 | |
| InsCtyCod | int(11) | NO | MUL | -1 | |
| InsCod | int(11) | NO | MUL | -1 | |
| DptCod | int(11) | NO | MUL | -1 | |
| CtrCod | int(11) | NO | MUL | -1 | |
| Office | varchar(127) | NO | | NULL | |
| OfficePhone | char(16) | NO | | NULL | |
| LocalAddress | varchar(127) | NO | | NULL | |
| LocalPhone | char(16) | NO | | NULL | |
| FamilyAddress | varchar(127) | NO | | NULL | |
| FamilyPhone | char(16) | NO | | NULL | |
| OriginPlace | varchar(127) | NO | | NULL | |
| Birthday | date | NO | | NULL | |
| Comments | text | NO | | NULL | |
| Menu | tinyint(4) | NO | MUL | 0 | |
| SideCols | tinyint(4) | NO | MUL | 3 | |
| NotifNtfEvents | int(11) | NO | | 0 | |
| EmailNtfEvents | int(11) | NO | | 0 | |
+-----------------+---------------------------------+------+-----+---------+----------------+
31 rows in set (0.00 sec)
+-------------------+----------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+----------------------------------------+------+-----+---------+----------------+
| UsrCod | int(11) | NO | PRI | NULL | auto_increment |
| EncryptedUsrCod | char(43) | NO | UNI | NULL | |
| Password | char(86) | NO | | NULL | |
| Surname1 | varchar(32) | NO | | NULL | |
| Surname2 | varchar(32) | NO | | NULL | |
| FirstName | varchar(32) | NO | | NULL | |
| Sex | enum('unknown','female','male') | NO | | unknown | |
| Layout | tinyint(4) | NO | MUL | 0 | |
| Theme | char(16) | NO | MUL | NULL | |
| IconSet | char(16) | NO | MUL | NULL | |
| Language | char(2) | NO | MUL | NULL | |
| Photo | char(43) | NO | | NULL | |
| PhotoVisibility | enum('user','course','system','world') | NO | | user | |
| ProfileVisibility | enum('user','course','system','world') | NO | | user | |
| CtyCod | int(11) | NO | MUL | -1 | |
| InsCtyCod | int(11) | NO | MUL | -1 | |
| InsCod | int(11) | NO | MUL | -1 | |
| DptCod | int(11) | NO | MUL | -1 | |
| CtrCod | int(11) | NO | MUL | -1 | |
| Office | varchar(127) | NO | | NULL | |
| OfficePhone | char(16) | NO | | NULL | |
| LocalAddress | varchar(127) | NO | | NULL | |
| LocalPhone | char(16) | NO | | NULL | |
| FamilyAddress | varchar(127) | NO | | NULL | |
| FamilyPhone | char(16) | NO | | NULL | |
| OriginPlace | varchar(127) | NO | | NULL | |
| Birthday | date | NO | | NULL | |
| Comments | text | NO | | NULL | |
| Menu | tinyint(4) | NO | MUL | 0 | |
| SideCols | tinyint(4) | NO | MUL | 3 | |
| NotifNtfEvents | int(11) | NO | | 0 | |
| EmailNtfEvents | int(11) | NO | | 0 | |
+-------------------+----------------------------------------+------+-----+---------+----------------+
32 rows in set (0.00 sec)
</pre>
<h3>Table usr_emails</h3>

View File

@ -56,6 +56,7 @@
<li><a href="#swad-database">Creating SWAD database</a></li>
<li><a href="#swad-files">Creating SWAD directories and files</a></li>
<li><a href="#swad-icons">Installing SWAD icons</a></li>
<li><a href="#jstz">Installing jstz and populating Time Zone Tables</a></li>
<li><a href="#dropzone">Installing DropzoneJS</a></li>
<li><a href="#mathjax">Installing MathJax</a></li>
<li><a href="#gsoap">Compiling and installing gSOAP, required to compile SWAD core</a></li>
@ -65,6 +66,7 @@
<li><a href="#chat-server">Installing chat server <code>swad-ircd</code></a></li>
<li><a href="#mail">Installing the script to send email <code>swad_smtp.py</code></a></li>
<li><a href="#services">Automating startup of services</a></li>
<li><a href="#mail-server">Installing mail server (optional)</a></li>
</ol>
</td>
</tr>
@ -650,6 +652,33 @@
<code>Options FollowSymLinks</code><br />
Remove <code>Indexes</code> to not list files in directories.
</li>
<li>
To cache contents, before the options for the root directory for web pages,
usually <code>/var/www/html</code>,
insert the lines:<br />
<code>
#<br />
# Cache<br />
#<br />
ExpiresActive On<br />
ExpiresDefault &quot;access plus 1 day&quot;<br />
</code>
Also, inside the root directory for web pages,
usually <code>/var/www/html</code>,
insert the lines:<br />
<code>
#<br />
# Cache<br />
#<br />
ExpiresByType text/html &quot;access plus 1 day&quot;<br />
ExpiresByType text/css &quot;access plus 1 day&quot;<br />
ExpiresByType text/javascript &quot;access plus 1 day&quot;<br />
ExpiresByType image/gif &quot;access plus 1 year&quot;<br />
ExpiresByType image/jpg &quot;access plus 1 year&quot;<br />
ExpiresByType image/png &quot;access plus 1 year&quot;
</code>
</li>
<li>
In the section <code>DirectoryIndex</code> search the line:<br />
@ -694,6 +723,33 @@
Remove <code>Indexes</code> to not list files in directories.
</li>
<li>
To cache contents, before the options for the root directory for web pages,
usually <code>/var/www/html</code>,
insert the lines:<br />
<code>
#<br />
# Cache<br />
#<br />
ExpiresActive On<br />
ExpiresDefault &quot;access plus 1 day&quot;<br />
</code>
Also, inside the root directory for web pages,
usually <code>/var/www/html</code>,
insert the lines:<br />
<code>
#<br />
# Cache<br />
#<br />
ExpiresByType text/html &quot;access plus 1 day&quot;<br />
ExpiresByType text/css &quot;access plus 1 day&quot;<br />
ExpiresByType text/javascript &quot;access plus 1 day&quot;<br />
ExpiresByType image/gif &quot;access plus 1 year&quot;<br />
ExpiresByType image/jpg &quot;access plus 1 year&quot;<br />
ExpiresByType image/png &quot;access plus 1 year&quot;
</code>
</li>
<li>
Optionally, if you want to rewrite some URIs,
inside the options for the directory <code>/var/www/</code>,
@ -1316,6 +1372,68 @@
<li>
<h2><a name="jstz">Installing jstz and populating Time Zone Tables</a></h2>
<p>
<strong>jstz</strong>,
available in <a href="https://bitbucket.org/pellepim/jstimezonedetect/">https://bitbucket.org/pellepim/jstimezonedetect/</a>
or <a href="http://pellepim.bitbucket.org/jstz/">http://pellepim.bitbucket.org/jstz/</a>,
is a Javascript script used by SWAD to get the user's time zone.
For example, if the user's operating system is configured with local time of Madrid (Spain),
the script <code>jstz.js</code> running in the user's browser
determines a user's time zone &quot;Europe/Berlin&quot;.
This user's time zone name is necessary to compute some stats of page hits
using user's local time instead of server time.
</p>
<p>
The script <code>jstz.js</code> is available in:<br />
<a href="https://bitbucket.org/pellepim/jstimezonedetect/">https://bitbucket.org/pellepim/jstimezonedetect/</a> &gt;
Downloads &gt;
Download repository &gt;
pellepim-jstimezonedetect-xxxxxxxxxxxx.zip &gt;
dist &gt;
jstz.js
</p>
<p>
To install it, you must copy the directory <code>jstz</code>,
located inside the directory <code>/home/&lt;user_directory&gt;/swad/swad-core</code>,
to the SWAD public directory:<br />
<table width="100%">
<tr>
<th>CentOS 6.5</th>
<th>Ubuntu 14.04</th>
</tr>
<tr>
<td width="50%" valign="top">
<code>cp -R /home/&lt;user_directory&gt;/swad/swad-core/jstz /var/www/html/swad/</code><br />
<code>chown -R apache:apache /var/www/html/swad/jstz</code><br />
If in CentOS <a href="http://en.wikipedia.org/wiki/Security-Enhanced_Linux">SELinux</a> is activated,
it should be necessary to change the permissions of the directory <code>jstz</code> and its contents:<br />
<code>ls -lZ /var/www/html/swad/</code><br />
<code>chcon -R -t httpd_sys_content_t /var/www/html/swad/jstz</code><br />
<code>ls -lZ /var/www/html/swad/</code>
</td>
<td width="50%" valign="top">
<code>sudo cp -R /home/&lt;user_directory&gt;/swad/swad-core/jstz /var/www/html/swad/</code><br />
<code>sudo chown -R www-data:www-data /var/www/html/swad/jstz</code>
</td>
</tr>
</table>
</p>
<p>
After installation, you must populate the Time Zone Tables
in your mysql database by following the instructions in
<a href="http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html">http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html</a>:<br />
<code>mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql</code>
</p>
</li>
<li>
<h2><a name="dropzone">Installing DropzoneJS</a></h2>
<p>
@ -2175,6 +2293,183 @@ chown $APACHE_USER:$APACHE_GROUP $PUBLIC_HTML/swad_mobile.css<br />
</table>
</p>
</li>
<li>
<h2><a name="mail-server">Installing mail server (optional)</a></h2>
<p>
If you have no external mail server,
you may need to install your own mail server
to send automatic emails.
In CentOS 6.5 you can install and configure it by following these instructions:
</p>
<h3>Installing and configuring Postfix and Dovecot</h3>
<p>
You can install and configure
<a href="http://www.postfix.org/">Postfix</a> and
<a href="http://www.dovecot.org/">Dovecot</a>
by following the instructions in
<a href="http://www.krizna.com/centos/setup-mail-server-in-centos-6/">http://www.krizna.com/centos/setup-mail-server-in-centos-6/</a>.
</p>
<h3>Settings to become a trusted mail server</h3>
<p>
If you want email providers, like GMail, to accept emails coming from your server
instead of rejecting them or labeling them as SPAM,
it is necessary to perform various settings detailed in this section.
</p>
<h4>Activating reverse DNS</h4>
<p>
We have activated Reverse DNS for our IPv4 address in our server by following the rules from
<a href="http://wiki.hetzner.de/index.php/DNS-Reverse-DNS/en">http://wiki.hetzner.de/index.php/DNS-Reverse-DNS/en</a>.
Instructions say that the address used for the mail command HELO should be used.
Our reverse DNS is <code>mail.openswad.org</code>.
</p>
<p>
Finally, we have also activated Reverse DNS from our IPv6 to <code>mail.openswad.org</code>.
If we write the command
<code>nslookup <em>our-server-IPV6-address</em></code>,
the result is <code>mail.openswad.org</code>.
</p>
<h4>Setting SPF</h4>
<p>
<a href="http://www.openspf.org/">SPF (Sender Policy Framework)</a>
is an open standard specifying a technical method to prevent sender address forgery.
By following instructions in:<br />
<a href="https://support.google.com/mail/answer/9008?hl=es">https://support.google.com/mail/answer/9008?hl=es</a><br />
<a href="https://support.google.com/a/answer/183895">https://support.google.com/a/answer/183895</a><br />
<a href="http://wiki.hetzner.de/index.php/DNS_SPF/en">http://wiki.hetzner.de/index.php/DNS_SPF/en</a><br />
we have added the next TXT record at the end of our DNS configuration page:<br />
<code>@ IN TXT &quot;v=spf1 a mx ip6:<em>our-server-ipv6-address</em> ~all&quot;</code>
</p>
<h4>Installing and setting DKIM</h4>
<p>
We need to install <a href="http://www.opendkim.org/">OpenDKIM</a> to sign emails.
Following the instructions in
<a href="https://www.rosehosting.com/blog/how-to-install-and-integrate-opendkim-with-postfix-on-a-centos-6-vps/">https://www.rosehosting.com/blog/how-to-install-and-integrate-opendkim-with-postfix-on-a-centos-6-vps/</a>:<br />
<code>yum install opendkim</code><br />
Make a copy of configuration file:<br />
<code>cd /etc</code><br />
<code>cp -a opendkim.conf opendkim.conf.original</code><br />
and edit file <code>opendkin.conf</code>:<br />
<code>vim /etc/opendkim.conf</code><br />
<ul>
<li>
Change option:<br />
<code>Mode v</code><br />
to:<br />
<code>Mode sv</code>
</li>
<li>
Comment the line:<br />
<code># KeyFile /etc/opendkim/keys/default.private</code><br />
and add this:<br />
<code>KeyFile /etc/opendkim/keys/openswad.org/default</code>
</li>
<li>
Uncomment the lines:<br />
<code>KeyTable /etc/opendkim/KeyTable</code><br />
<code>SigningTable refile:/etc/opendkim/SigningTable</code><br />
<code>ExternalIgnoreList refile:/etc/opendkim/TrustedHosts</code><br />
<code>InternalHosts refile:/etc/opendkim/TrustedHosts</code>
</li>
</ul>
</p>
<p>
Generate set of keys for your <em>mydomain.com</em> domain name:<br />
<code>mkdir /etc/opendkim/keys/openswad.org</code><br />
<code>opendkim-genkey -D /etc/opendkim/keys/openswad.org/ -d openswad.org -s default</code><br />
<code>chown -R opendkim: /etc/opendkim/keys/openswad.org</code><br />
<code>mv /etc/opendkim/keys/openswad.org/default.private /etc/opendkim/keys/openswad.org/default</code>
</p>
<p>
Edit <code>/etc/opendkim/KeyTable</code>:<br />
<code>cd /etc/opendkim</code><br />
<code>cp -a KeyTable KeyTable.original</code><br />
<code>vim /etc/opendkim/KeyTable</code><br />
and add the following record to OpenDKIM's key table <code>/etc/opendkim/KeyTable</code>:<br />
<code>default._domainkey.openswad.org openswad.org:default:/etc/opendkim/keys/openswad.org/default</code>
</p>
<p>
Edit <code>/etc/opendkim/SigningTable</code>:<br />
<code>cd /etc/opendkim</code><br />
<code>cp -a SigningTable SigningTable.original</code><br />
<code>vim /etc/opendkim/SigningTable</code><br />
and add the following record to OpenDKIM's signing table <code>/etc/opendkim/SigningTable</code>:<br />
<code>*@openswad.org default._domainkey.openswad.org</code>
</p>
<p>
Add your domain and your hostname as trusted hosts in <code>/etc/opendkim/TrustedHosts</code>:<br />
<code>cd /etc/opendkim</code><br />
<code>cp -a TrustedHosts TrustedHosts.original</code><br />
<code>vim /etc/opendkim/TrustedHosts</code><br />
We add the following lines:<br />
<code>openswad.org</code><br />
<code>mail.openswad.org</code>
</p>
<p>
Edit your DNS zone and add the TXT record from
<code>/etc/opendkim/keys/mydomain.com/default.txt</code>:<br />
<code>cat /etc/opendkim/keys/openswad.org/default.txt</code><br />
We add something like this:<br />
<code>default._domainkey IN TXT ( &quot;v=DKIM1; k=rsa; &quot;
&quot;p=<em>our-DKIM-key</em>&quot; ) ; ----- DKIM key default for openswad.org</code>
</p>
<p>
In order to integrate OpenDKIM with Postfix
we need to edit <code>/etc/postfix/main.cf</code>:<br />
<code>vim /etc/postfix/main.cf</code><br />
and add the following few lines:<br />
<code>smtpd_milters = inet:127.0.0.1:8891</code><br />
<code>non_smtpd_milters = $smtpd_milters</code><br />
<code>milter_default_action = accept</code><br />
<code>milter_protocol = 2</code>
</p>
<p>
Finally, add OpenDKIM to your system's start-up
and start opendkim and restart postfix using the following commands:<br />
<code>service opendkim start</code><br />
<code>chkconfig opendkim on</code><br />
<code>service postfix restart</code>
</p>
<h4>Setting DMARC</h4>
<p>
Finally, we add a <a href="https://dmarc.org/">DMARC</a> record to our DNS
by following the recommendations of
<a href="https://support.google.com/a/answer/2466563?hl=es">https://support.google.com/a/answer/2466563?hl=es</a>:<br />
<code>_dmarc IN TXT &quot;v=DMARC1; p=none; rua=mailto:postmaster@<em>our-domain</em>&quot;</code><br />
following the instructions from
<a href="https://support.google.com/a/answer/2466563?hl=es&ref_topic=2759254">https://support.google.com/a/answer/2466563?hl=es&ref_topic=2759254</a>
</p>
<h4>Final test</h4>
<p>
After the settings, we can check the health of our mail domain using web tests like this:<br />
<a href="http://mxtoolbox.com/domain/openswad.org/">http://mxtoolbox.com/domain/openswad.org/</a>
</p>
</li>
</ol>

View File

@ -170,7 +170,7 @@
The SWAD web service provides the following operations:
</p>
<ul>
<li><a href="#createAccount" class="not_implemented"><code>createAccount</code></a></li>
<li><a href="#createAccount"><code>createAccount</code></a></li>
<li><a href="#loginByUserPasswordKey"><code>loginByUserPasswordKey</code></a></li>
<li><a href="#loginBySessionKey"><code>loginBySessionKey</code></a></li>
<li style="margin-bottom:1em;"><a href="#getNewPassword"><code>getNewPassword</code></a></li>
@ -187,7 +187,8 @@
<li style="margin-bottom:1em;"><a href="#getMarks"><code>getMarks</code></a></li>
<li><a href="#getTestConfig"><code>getTestConfig</code></a></li>
<li style="margin-bottom:1em;"><a href="#getTests"><code>getTests</code></a></li>
<li><a href="#getTests"><code>getTests</code></a></li>
<li style="margin-bottom:1em;"><a href="#getTrivialQuestion"><code>getTrivialQuestion</code></a></li>
<li style="margin-bottom:1em;"><a href="#getUsers"><code>getUsers</code></a></li>
@ -205,17 +206,16 @@
<hr />
<a name="createAccount" class="not_implemented"><h3 class="WS_FUNCTION"><code>createAccount</code></h3></a>
<p align="justify" class="not_implemented">
<a name="createAccount"><h3 class="WS_FUNCTION"><code>createAccount</code></h3></a>
<p align="justify">
Create a new user account.
<strong>FUTURE, NOT YET IMPLEMENTED!</strong>
</p>
<ul class="not_implemented">
<ul>
<li>Call parameters:
<ul>
<li><strong>userNickname</strong>: string starting by @ (@nickname of the user).</li>
<li><strong>userEmail</strong>: string (email of the user).</li>
<li><strong>userID</strong>: string (DNI/passport of the user).</li>
<!-- <li><strong>userID</strong>: string (DNI/passport of the user).</li> -->
<li><strong>userPassword</strong>: string, plain password.</li>
<li><strong>appKey</strong>: string, key used by the application.</li>
</ul>
@ -224,7 +224,15 @@
<ul>
<li><strong>userCode</strong>: integer, unique identifier of the user.
<ul>
<li>If &lt;= 0, an error has happened, the account has not been created.</li>
<li>If &lt;= 0, an error has happened, the account has not been created.
<ul>
<li>-1 &rarr; nickname not valid</li>
<li>-2 &rarr; nickname registered by another user</li>
<li>-3 &rarr; e-mail not valid</li>
<li>-4 &rarr; e-mail registered by another user</li>
<li>-5 &rarr; password not valid (too short, too trivial...)</li>
</ul>
</li>
<li>If &gt; 0, the account has been successfully created
and this unique identifier has been assigned to the new user.</li>
</ul>
@ -840,6 +848,50 @@
</li>
</ul>
<a name="getTrivialQuestion"><h3 class="WS_FUNCTION"><code>getTrivialQuestion</code></h3></a>
<p align="justify">
Returns a random test question, selected from the "uniqueChoice" questions
in the courses of a given list of degrees,
and with a score in the interval [<code>lowerScore</code>, <code>upperScore</code>].
</p>
<ul>
<li>Call parameters:
<ul>
<li><strong>wsKey</strong>: string, identifier returned by loginByUserPasswordKey or loginBySessionKey.</li>
<li><strong>degrees</strong>: string. It can contain one or more degree codes, separated by commas.</li>
<li><strong>lowerScore</strong>: float. lower limit of the question score between -1.0 and 1.0</li>
<li><strong>upperScore</strong>: float. upper limit of the question score between -1.0 and 1.0</li>
</ul>
</li>
<li>Returns a data structure with the following fields:
<ul>
<li><strong>question</strong>: data structure with the following fields:
<ul>
<li><strong>questionCode</strong>: integer, unique identifier for the question, > 0.
If no question found &rArr; a questionCode value <= 0 will be returned.</li>
<li><strong>answerType</strong>: string,
currently only the following value is returned:
<ul>
<li>&quot;uniqueChoice&quot;: choice of a unique answer between several options.</li>
</ul>
<li><strong>shuffle</strong>: integer. If not 0 &rArr; the answers can be shuffled.</li>
<li><strong>stem</strong>: string with the stem of the question.</li>
<li><strong>feedback</strong>: string with the feedback of the question.</li>
</ul>
</li>
<li><strong>answers</strong>: list of answers of the returned question, where each answer is a data structure with the following fields:
<ul>
<li><strong>questionCode</strong>: integer.</li>
<li><strong>answerIndex</strong>: integer, index or position (0, 1, 2,...) of the answer inside the question.</li>
<li><strong>correct</strong>: integer. If not 0 &rArr; the answer is correct.</li>
<li><strong>answerText</strong>: string with the text of the answer.</li>
<li><strong>answerFeedback</strong>: string with the feedback for this answer.
</ul>
</li>
</ul>
</li>
</ul>
<hr />
<a name="getUsers" ><h3 class="WS_FUNCTION"><code>getUsers</code></h3></a>
@ -1099,14 +1151,15 @@
When a user opens this notification,
you should call <a href="#markNotificationsAsRead"><code>markNotificationsAsRead</code></a> with this value.</li>
<li><strong>eventType</strong>: string,
with one of the following 12 values:
with one of the following 13 values:
<ul>
<li>&quot;documentFile&quot;: document.</li>
<li>&quot;sharedFile&quot;: shared file.</li>
<li>&quot;assignment&quot;: assignment.</li>
<li>&quot;examAnnouncement&quot;: exam announcement.</li>
<li>&quot;marksFile&quot;: marks/grades file.</li>
<li>&quot;enrollment&quot;: enrollment in a course.</li>
<li>&quot;enrollmentStudent&quot;: enrollment in a course as a student.</li>
<li>&quot;enrollmentTeacher&quot;: enrollment in a course as a teacher.</li>
<li>&quot;enrollmentRequest&quot;: enrollment request.</li>
<li>&quot;notice&quot;: notice (yellow note).</li>
<li>&quot;forumPostCourse&quot;: new message in a forum of a course.</li>

View File

@ -226,7 +226,6 @@
<sequence>
<element name="userNickname" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/><!-- swad__createAccount::userNickname -->
<element name="userEmail" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/><!-- swad__createAccount::userEmail -->
<element name="userID" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/><!-- swad__createAccount::userID -->
<element name="userPassword" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/><!-- swad__createAccount::userPassword -->
<element name="appKey" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/><!-- swad__createAccount::appKey -->
</sequence>
@ -237,7 +236,7 @@
<complexType>
<sequence>
<element name="userCode" type="xsd:int" minOccurs="1" maxOccurs="1"/><!-- swad__createAccountOutput::userCode -->
<element name="string" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/><!-- swad__createAccountOutput::string -->
<element name="wsKey" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/><!-- swad__createAccountOutput::wsKey -->
</sequence>
</complexType>
</element>
@ -512,6 +511,26 @@
</complexType>
</element>
<!-- operation request element -->
<element name="getTrivialQuestion">
<complexType>
<sequence>
<element name="wsKey" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/><!-- swad__getTrivialQuestion::wsKey -->
<element name="degrees" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/><!-- swad__getTrivialQuestion::degrees -->
<element name="lowerScore" type="xsd:float" minOccurs="1" maxOccurs="1"/><!-- swad__getTrivialQuestion::lowerScore -->
<element name="upperScore" type="xsd:float" minOccurs="1" maxOccurs="1"/><!-- swad__getTrivialQuestion::upperScore -->
</sequence>
</complexType>
</element>
<!-- operation response element -->
<element name="getTrivialQuestionOutput">
<complexType>
<sequence>
<element name="question" type="swad:question" minOccurs="1" maxOccurs="1"/><!-- swad__getTrivialQuestionOutput::question -->
<element name="answersArray" type="swad:answersArray" minOccurs="1" maxOccurs="1" nillable="true"/><!-- swad__getTrivialQuestionOutput::answersArray -->
</sequence>
</complexType>
</element>
<!-- operation request element -->
<element name="getUsers">
<complexType>
<sequence>
@ -802,6 +821,14 @@
<part name="Body" element="swad:getTestsOutput"/><!-- swad__getTests::getTestsOut -->
</message>
<message name="getTrivialQuestion">
<part name="Body" element="swad:getTrivialQuestion"/><!-- swad__getTrivialQuestion::swad__getTrivialQuestion -->
</message>
<message name="getTrivialQuestionOutput">
<part name="Body" element="swad:getTrivialQuestionOutput"/><!-- swad__getTrivialQuestion::getTrivialQuestionOut -->
</message>
<message name="getUsers">
<part name="Body" element="swad:getUsers"/><!-- swad__getUsers::swad__getUsers -->
</message>
@ -945,6 +972,11 @@
<input message="tns:getTests"/>
<output message="tns:getTestsOutput"/>
</operation>
<operation name="getTrivialQuestion">
<documentation>Service definition of function swad__getTrivialQuestion</documentation>
<input message="tns:getTrivialQuestion"/>
<output message="tns:getTrivialQuestionOutput"/>
</operation>
<operation name="getUsers">
<documentation>Service definition of function swad__getUsers</documentation>
<input message="tns:getUsers"/>
@ -1120,6 +1152,15 @@
<SOAP:body parts="Body" use="literal"/>
</output>
</operation>
<operation name="getTrivialQuestion">
<SOAP:operation soapAction=""/>
<input>
<SOAP:body parts="Body" use="literal"/>
</input>
<output>
<SOAP:body parts="Body" use="literal"/>
</output>
</operation>
<operation name="getUsers">
<SOAP:operation soapAction=""/>
<input>
@ -1204,9 +1245,9 @@
</binding>
<service name="swad">
<documentation>gSOAP 2.8.18 generated service definition</documentation>
<documentation>gSOAP 2.8.17r generated service definition</documentation>
<port name="swad" binding="tns:swad">
<SOAP:address location="https://swad.ugr.es/"/>
<SOAP:address location="https://openswad.org/"/>
</port>
</service>

View File

@ -98,7 +98,6 @@
// TODO: Change link to Degree in Statistics > Visits > By degree to internal Degree
// TODO: Link to user's country in public profile
// TODO: Show guests in connected users.
// TODO: Hide global announcements without removing them
// TODO: A teacher should may confirm a student ID? In what conditions? (Necessary in order to a student can view his/her marks)
// TODO: Put headers Content-type and Content-disposition when redirecting with Location:
// TODO: System admin should be able to remove/edit user's mail (when he/she detects a recipient does not exists, for example)
@ -113,11 +112,12 @@
/****************************** Public constants *****************************/
/*****************************************************************************/
#define Log_PLATFORM_VERSION "SWAD 15.38 (2015/11/13)"
#define Log_PLATFORM_VERSION "SWAD 15.38.1 (2015/11/14)"
// Number of lines (includes comments but not blank lines) has been got with the following command:
// nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h sql/swad*.sql | tail -1
/*
Version 15.38.1: Nov 14, 2015 Changes in permission to query the whole range of dates in stats, suggested by Francisco Ocaña Lara. (187073 lines)
Version 15.38: Nov 13, 2015 New option for students: list of my attendance. (187063 lines)
2 changes necessary in database:
INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1473','es','N','Listar mi asistencia a varios eventos');

View File

@ -826,6 +826,7 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse)
char StrRole[256];
char StrQueryCountType[256];
unsigned NumDays;
bool ICanQueryWholeRange;
/***** Initialize data structure of the user *****/
Usr_UsrDataConstructor (&UsrDat);
@ -949,16 +950,25 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse)
/***** Check if range of dates is forbidden for me *****/
NumDays = Dat_GetNumDaysBetweenDates (&Gbl.DateRange.DateIni.Date,&Gbl.DateRange.DateEnd.Date);
if (!(Gbl.Usrs.Me.LoggedRole == Rol_SYS_ADM ||
(Gbl.Usrs.Me.LoggedRole == Rol_TEACHER && GlobalOrCourse == Sta_SHOW_COURSE_ACCESSES)))
// TODO: How long can query other admins?
if (NumDays > Cfg_DAYS_IN_RECENT_LOG)
{
sprintf (Gbl.Message,Txt_The_date_range_must_be_less_than_or_equal_to_X_days,
Cfg_DAYS_IN_RECENT_LOG);
Lay_ShowAlert (Lay_WARNING,Gbl.Message); // ...write warning message and show the form again
return;
}
ICanQueryWholeRange = (Gbl.Usrs.Me.LoggedRole >= Rol_TEACHER && GlobalOrCourse == Sta_SHOW_COURSE_ACCESSES) ||
(Gbl.Usrs.Me.LoggedRole == Rol_TEACHER && Gbl.Scope.Current == Sco_SCOPE_CRS) ||
(Gbl.Usrs.Me.LoggedRole == Rol_DEG_ADM && (Gbl.Scope.Current == Sco_SCOPE_DEG ||
Gbl.Scope.Current == Sco_SCOPE_CRS)) ||
(Gbl.Usrs.Me.LoggedRole == Rol_CTR_ADM && (Gbl.Scope.Current == Sco_SCOPE_CTR ||
Gbl.Scope.Current == Sco_SCOPE_DEG ||
Gbl.Scope.Current == Sco_SCOPE_CRS)) ||
(Gbl.Usrs.Me.LoggedRole == Rol_INS_ADM && (Gbl.Scope.Current == Sco_SCOPE_INS ||
Gbl.Scope.Current == Sco_SCOPE_CTR ||
Gbl.Scope.Current == Sco_SCOPE_DEG ||
Gbl.Scope.Current == Sco_SCOPE_CRS)) ||
Gbl.Usrs.Me.LoggedRole == Rol_SYS_ADM;
if (!ICanQueryWholeRange && NumDays > Cfg_DAYS_IN_RECENT_LOG)
{
sprintf (Gbl.Message,Txt_The_date_range_must_be_less_than_or_equal_to_X_days,
Cfg_DAYS_IN_RECENT_LOG);
Lay_ShowAlert (Lay_WARNING,Gbl.Message); // ...write warning message and show the form again
return;
}
/***** Query depending on the type of count *****/
switch (Gbl.Stat.CountType)