Rev 15847 | Rev 16130 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
10 | reyssat | 1 | /* Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis |
2 | * |
||
3 | * This program is free software; you can redistribute it and/or modify |
||
4 | * it under the terms of the GNU General Public License as published by |
||
5 | * the Free Software Foundation; either version 2 of the License, or |
||
6 | * (at your option) any later version. |
||
7 | * |
||
8 | * This program is distributed in the hope that it will be useful, |
||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
11 | * GNU General Public License for more details. |
||
12 | * |
||
13 | * You should have received a copy of the GNU General Public License |
||
14 | * along with this program; if not, write to the Free Software |
||
15 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
||
16 | */ |
||
17 | |||
8155 | bpr | 18 | /* Routines treating user scores. */ |
8185 | bpr | 19 | #include "wims.h" |
10 | reyssat | 20 | |
7149 | bpr | 21 | double oldfactor=0.85; /* quality factor, should remain stable. */ |
10 | reyssat | 22 | |
12222 | bpr | 23 | enum {sr_require, sr_weight, sr_score, sr_mean, sr_remain, |
12273 | bpr | 24 | sr_last, sr_try, sr_best, sr_level, sr_new, sr_seedlast, sr_seedscorelast, |
12295 | bpr | 25 | sr_seedscores, sr_seedlastcnt}; |
10 | reyssat | 26 | char scorebuf[MAX_CLASSEXOS*sizeof(scoreresult)+32]; |
27 | struct scoreresult *rscore; |
||
28 | int scorecnt; |
||
29 | double scoresum[MAX_SHEETS]; |
||
30 | int sheetstart[MAX_SHEETS], shexocnt[MAX_SHEETS]; |
||
31 | int examstart, examcnt; |
||
32 | char rscore_class[MAX_CLASSLEN+1]; |
||
33 | char rscore_user[MAX_NAMELEN+1]; |
||
34 | |||
35 | int totsheets=0; |
||
36 | int score_ispublic=0; |
||
7149 | bpr | 37 | int score_status=-1; /* save of score status */ |
10 | reyssat | 38 | int score_statussheet=-1; |
39 | int score_statusisexam=-1; |
||
40 | double scorerecfactor=0.9; |
||
41 | |||
12197 | bpr | 42 | /* gather user score, core routine. |
43 | rscore data is created (table of structures). |
||
44 | according to the value of wims_sheet or wims_exo |
||
45 | */ |
||
10 | reyssat | 46 | int getscoreuser(char *classe, char *user) |
47 | { |
||
15847 | bpr | 48 | int i, osh, sh; |
7407 | bpr | 49 | char *nowuser, *nowsheet, *nowexo, *nowscore; |
50 | char *pp; |
||
12196 | bpr | 51 | if(user==NULL || *user==0) { |
7407 | bpr | 52 | user=getvar("wims_user"); |
53 | if(user==NULL || *user==0) return -1; |
||
54 | } |
||
55 | if(strcmp(classe,rscore_class)==0 && strcmp(user,rscore_user)==0) return 0; |
||
56 | nowsheet=nowexo=nowscore=""; |
||
12495 | bpr | 57 | nowuser=getvar("wims_user"); |
58 | if(nowuser!=NULL && strcmp(user,nowuser)==0) { |
||
12196 | bpr | 59 | nowscore=getvar("module_score"); |
60 | if(nowscore!=NULL && *nowscore!=0) { |
||
61 | nowsheet=getvar("wims_sheet"); |
||
62 | if(nowsheet==NULL) nowsheet=""; |
||
63 | nowexo=getvar("wims_exo"); |
||
64 | if(nowexo==NULL) nowexo=""; |
||
10 | reyssat | 65 | } |
7407 | bpr | 66 | else nowscore=""; |
67 | } |
||
68 | snprintf(scorebuf+sizeof(int),sizeof(scorebuf)-sizeof(int), |
||
7646 | bpr | 69 | "-c%s -u%s getscore %s %s %s", |
70 | classe,user,nowsheet,nowexo,nowscore); |
||
71 | i=kerneld(scorebuf,sizeof(scorebuf)); |
||
72 | if(i<0) internal_error("getscoreuser(): daemon failure."); |
||
7407 | bpr | 73 | if(memcmp(scorebuf+sizeof(int),"OK",2)!=0) { |
74 | if(memcmp(scorebuf+sizeof(int),"ERROR",5)==0) { |
||
75 | module_error(find_word_start(scorebuf+sizeof(int)+8)); |
||
10 | reyssat | 76 | } |
7407 | bpr | 77 | else internal_error("getscoreuser(): communication error with wimslogd."); |
78 | } |
||
8340 | bpr | 79 | /* 3 is here the length of "OK " */ |
7407 | bpr | 80 | pp=scorebuf+sizeof(int)+3; rscore=(struct scoreresult *) pp; |
81 | scorecnt=(i-sizeof(int)-3)/sizeof(scoreresult); |
||
82 | if(scorecnt>MAX_CLASSEXOS) module_error("too_many_exercises"); |
||
15847 | bpr | 83 | osh=-1; |
84 | for(i=totsheets=0;i<scorecnt;i++) { |
||
85 | sh=rscore[i].sh; |
||
86 | /* MAX_SHEETS doit être inférieur à 255 donc on n'atteint pas l'examen */ |
||
87 | if (sh >= MAX_SHEETS) break; |
||
88 | while(osh<sh) |
||
89 | {++osh; scoresum[osh]=shexocnt[osh]=0; sheetstart[osh]=i;} |
||
90 | scoresum[sh]+=rscore[i].require*rscore[i].weight*rscore[i].active; |
||
91 | shexocnt[sh]++; |
||
7407 | bpr | 92 | } |
15847 | bpr | 93 | totsheets=osh+1; |
94 | |||
95 | examstart=i; examcnt=scorecnt-examstart; |
||
7407 | bpr | 96 | mystrncpy(rscore_class,classe,sizeof(rscore_class)); |
97 | mystrncpy(rscore_user,user,sizeof(rscore_user)); |
||
98 | return 0; |
||
10 | reyssat | 99 | } |
7602 | bpr | 100 | /* work : exo */ |
10 | reyssat | 101 | char *scorepname[]={ |
12222 | bpr | 102 | "class","user","sheet","work","exam" |
10 | reyssat | 103 | }; |
104 | #define scorepname_no (sizeof(scorepname)/sizeof(scorepname[0])) |
||
105 | char score_class[MAX_CLASSLEN+1]; |
||
106 | int score_sheet,score_exo,score_isexam; |
||
107 | char score_user[256]; |
||
108 | |||
7407 | bpr | 109 | /* Uniformed treatment of score command parameters |
110 | * format: class=? user=? sheet=? work=? |
||
8155 | bpr | 111 | * all are optional. |
112 | */ |
||
10 | reyssat | 113 | void _scoreparm(char *p) |
114 | { |
||
115 | int i; |
||
116 | char *pn, *pe, *pd, *pf; |
||
117 | char sav; |
||
7407 | bpr | 118 | |
10 | reyssat | 119 | score_sheet=score_exo=score_isexam=score_ispublic=0; *score_class=0; |
120 | score_user[0]=0; |
||
121 | for(i=0;i<scorepname_no;i++) { |
||
7149 | bpr | 122 | pf=p; |
123 | ahead: |
||
124 | pn=strstr(pf,scorepname[i]); pf=pn+1; |
||
125 | if(pn==NULL) continue; |
||
126 | if(pn>p && !isspace(*(pn-1))) goto ahead; |
||
127 | pe=find_word_start(pn+strlen(scorepname[i])); |
||
128 | if(*pe!='=') goto ahead; |
||
129 | pd=find_word_start(pe+1); |
||
130 | pf=find_word_end(pd); |
||
131 | if(pf<=pd) continue; |
||
132 | sav=*pf; *pf=0; |
||
133 | switch(i) { |
||
134 | case 0: /* class */ |
||
135 | mystrncpy(score_class,pd,sizeof(score_class)); break; |
||
136 | case 1: /* user */ |
||
137 | mystrncpy(score_user,pd,sizeof(score_user)); break; |
||
138 | case 2: { /* sheet */ |
||
139 | if(*pd=='P') {pd++; score_ispublic=1;} |
||
140 | score_sheet=atoi(pd); |
||
141 | break; |
||
142 | } |
||
7363 | bpr | 143 | case 3: /* work=exo */ |
7149 | bpr | 144 | score_exo=atoi(pd); break; |
145 | case 4: /* exam */ |
||
146 | score_isexam=1; break; |
||
147 | } |
||
148 | *pf=sav; ovlstrcpy(pn, pf); |
||
10 | reyssat | 149 | } |
150 | *p=0; |
||
12381 | bpr | 151 | /* the commands are OK from a non trusted module if the user and the |
12369 | bpr | 152 | class are not precised, so it can be only the user in his class */ |
10 | reyssat | 153 | if((*score_class!=0 || score_user[0]!=0) && !trusted_module()) { |
7149 | bpr | 154 | module_error("not_trusted"); return; |
10 | reyssat | 155 | } |
156 | if(*score_class==0) { |
||
7149 | bpr | 157 | char *classe; |
158 | classe=getvar("wims_class"); |
||
159 | if(classe==NULL || *classe==0) return; |
||
160 | else mystrncpy(score_class,classe,sizeof(score_class)); |
||
10 | reyssat | 161 | } |
162 | if(score_user[0]==0) { |
||
7149 | bpr | 163 | char *user; |
164 | user=getvar("wims_user"); |
||
165 | if(user!=NULL) mystrncpy(score_user,user,sizeof(score_user)); |
||
10 | reyssat | 166 | } |
167 | } |
||
168 | |||
7407 | bpr | 169 | /* gather score: relatif to some of the |
170 | * user class work sheet exam |
||
8155 | bpr | 171 | * dtype can be require weight score mean remain best last level try |
7407 | bpr | 172 | */ |
173 | |||
10 | reyssat | 174 | void _getscore(char *p,int dtype) |
175 | { |
||
12222 | bpr | 176 | int i,sh,ex,osh; |
177 | float d; |
||
12273 | bpr | 178 | char dc[SEEDSIZE]; |
179 | char ds[SEEDSCORES]; |
||
12222 | bpr | 180 | char *p1; |
10 | reyssat | 181 | |
12222 | bpr | 182 | _scoreparm(p); |
183 | if(*score_class==0 || *score_user==0) return; |
||
184 | if(getscoreuser(score_class,score_user)<0) return; |
||
185 | for(i=osh=0,p1=p;i<scorecnt && p1-p<MAX_LINELEN-32;i++) { |
||
15847 | bpr | 186 | sh=rscore[i].sh+1; if(sh<1 || sh>MAX_SHEETS) break; |
12222 | bpr | 187 | if(score_sheet!=0) { |
188 | if(sh<score_sheet) continue; |
||
189 | if(sh>score_sheet || sh>MAX_SHEETS) break; |
||
190 | } |
||
15847 | bpr | 191 | ex=rscore[i].exo+1; |
12222 | bpr | 192 | if(score_exo!=0 && ex!=score_exo) continue; |
193 | if(osh!=0 && sh!=osh) *p1++='\n'; |
||
194 | switch(dtype) { |
||
195 | case sr_require: {d=rscore[i].require; break;} |
||
196 | case sr_weight: {d=rscore[i].weight; break;} |
||
197 | case sr_score: {d=rscore[i].score; break;} |
||
198 | case sr_mean: {d=rscore[i].mean; break;} |
||
199 | case sr_remain: {d=rscore[i].require-rscore[i].score; break;} |
||
200 | case sr_last: {d=rscore[i].last; break;} |
||
201 | case sr_try: {d=rscore[i].try; break;} |
||
12230 | bpr | 202 | case sr_new: {d=rscore[i].new; break;} |
12222 | bpr | 203 | case sr_best: {d=rscore[i].best; break;} |
12273 | bpr | 204 | case sr_level: {d=rscore[i].level; break;} |
205 | case sr_seedscorelast: {d=rscore[i].seedscorelast; break;} |
||
12295 | bpr | 206 | case sr_seedlastcnt: {d=rscore[i].seedlastcnt; break;} |
12273 | bpr | 207 | case sr_seedlast: { mystrncpy(dc,rscore[i].seedlast,SEEDSIZE); |
208 | break; |
||
209 | } |
||
210 | case sr_seedscores: { |
||
211 | mystrncpy(ds,rscore[i].seedscores,SEEDSCORES); break; |
||
212 | } |
||
12222 | bpr | 213 | default: {d=0; break;} |
214 | } |
||
12273 | bpr | 215 | switch(dtype) { |
216 | case sr_seedlast: |
||
217 | { snprintf(p1,SEEDSIZE, "%s", dc); p1+=strlen(p1); break; } |
||
218 | case sr_seedscores: |
||
219 | { snprintf(p1,SEEDSCORES, "%s", ds); p1+=strlen(p1); break; } |
||
220 | default: |
||
221 | { p1=moneyprint(p1,d); } |
||
222 | } |
||
223 | *p1++=' '; |
||
12222 | bpr | 224 | osh=sh; |
225 | } |
||
226 | *p1++='\n'; *p1=0; |
||
10 | reyssat | 227 | } |
228 | |||
7407 | bpr | 229 | /* gather user score. */ |
10 | reyssat | 230 | void calc_getscore(char *p) |
231 | { |
||
7407 | bpr | 232 | _getscore(p,sr_score); |
10 | reyssat | 233 | } |
234 | |||
7407 | bpr | 235 | /* gather user score average. */ |
10 | reyssat | 236 | void calc_getscoremean(char *p) |
237 | { |
||
7407 | bpr | 238 | _getscore(p,sr_mean); |
10 | reyssat | 239 | } |
240 | |||
7407 | bpr | 241 | /* gather remaining of score to get for user. */ |
10 | reyssat | 242 | void calc_getscoreremain(char *p) |
243 | { |
||
7407 | bpr | 244 | _getscore(p,sr_remain); |
10 | reyssat | 245 | } |
246 | |||
7407 | bpr | 247 | /* Require score table. */ |
10 | reyssat | 248 | void calc_getscorerequire(char *p) |
249 | { |
||
7407 | bpr | 250 | _getscore(p,sr_require); |
10 | reyssat | 251 | } |
252 | |||
7407 | bpr | 253 | /* Score weight table. */ |
10 | reyssat | 254 | void calc_getscoreweight(char *p) |
255 | { |
||
7407 | bpr | 256 | _getscore(p,sr_weight); |
10 | reyssat | 257 | } |
14126 | obado | 258 | /* user last score */ |
7602 | bpr | 259 | void calc_getscorelast(char *p) |
260 | { |
||
261 | _getscore(p,sr_last); |
||
262 | } |
||
12196 | bpr | 263 | /* gather user score try numbers with score activated. */ |
7602 | bpr | 264 | void calc_getscoretry(char *p) |
265 | { |
||
266 | _getscore(p,sr_try); |
||
267 | } |
||
12220 | bpr | 268 | /* gather all user try numbers (terminated or not, but with notation activated)*/ |
12197 | bpr | 269 | void calc_getscorealltries(char *p) |
12196 | bpr | 270 | { |
12230 | bpr | 271 | _getscore(p,sr_new); |
12196 | bpr | 272 | } |
7602 | bpr | 273 | |
7657 | bpr | 274 | /* if the required points are 10* N, gather N user best scores */ |
7638 | bpr | 275 | void calc_getscorebest(char *p) |
276 | { |
||
277 | _getscore(p,sr_best); |
||
278 | } |
||
279 | |||
7657 | bpr | 280 | /* gather user score average. */ |
281 | void calc_getscorelevel(char *p) |
||
282 | { |
||
283 | _getscore(p,sr_level); |
||
284 | } |
||
285 | |||
7638 | bpr | 286 | /* percentage of work done for each sheet: |
7657 | bpr | 287 | * score mean best level |
288 | * as follows |
||
14126 | obado | 289 | * score=100*cumulative_points/required_points (< 100) |
7665 | bpr | 290 | * mean=quality (<10) |
291 | * best=10*(required/10 best_scores)/required_points (< 100) |
||
14134 | obado | 292 | * level=minimum of the required/10 best_scores (< 100) |
7638 | bpr | 293 | */ |
7657 | bpr | 294 | |
295 | void calc_getscorepercent(char *p) |
||
10 | reyssat | 296 | { |
7407 | bpr | 297 | int i,j,jend; |
7657 | bpr | 298 | double tot, mean, totb, totl, totw, d; |
7407 | bpr | 299 | char *p1; |
10 | reyssat | 300 | |
7407 | bpr | 301 | _scoreparm(p); |
302 | if(*score_class==0 || *score_user==0) return; |
||
303 | if(getscoreuser(score_class,score_user)<0) return; |
||
304 | for(p1=p,i=0;i<totsheets && p1-p<MAX_LINELEN-32;i++) { |
||
305 | if(scoresum[i]==0) { |
||
7657 | bpr | 306 | ovlstrcpy(p1,"0 0 0 0\n"); p1+=strlen(p1); continue; |
10 | reyssat | 307 | } |
7407 | bpr | 308 | if(score_sheet!=0 && i!=score_sheet-1) continue; |
309 | if(scoresum[i]<=0) *p1++='\n'; |
||
7657 | bpr | 310 | tot=mean=totb=totl=totw=0; jend=sheetstart[i]+shexocnt[i]; |
7407 | bpr | 311 | for(j=sheetstart[i];j<jend;j++) { |
12495 | bpr | 312 | /* if mean<1 then ignore score. |
313 | * if mean<2 then half score. |
||
314 | */ |
||
7407 | bpr | 315 | if(rscore[j].mean>=1) { |
7646 | bpr | 316 | double dt=rscore[j].score; |
317 | float db=rscore[j].best; |
||
7657 | bpr | 318 | float dl=rscore[j].level; |
319 | if(rscore[j].mean<2) {dt=dt/2; db=db/2; dl=dl/2;} |
||
15847 | bpr | 320 | d=dt*rscore[j].weight*rscore[j].active; |
321 | /* quality; barycenter with coefficients d */ |
||
7646 | bpr | 322 | mean+=rscore[j].mean*d; |
12495 | bpr | 323 | /* cumulative score */ |
7646 | bpr | 324 | tot+=d; |
12495 | bpr | 325 | /* best */ |
15847 | bpr | 326 | totb+=db*rscore[j].weight*rscore[j].active; |
12495 | bpr | 327 | /* level */ |
15847 | bpr | 328 | totl+=dl*rscore[j].weight*rscore[j].active; |
329 | totw+=rscore[j].weight*rscore[j].active; |
||
7407 | bpr | 330 | } |
331 | } |
||
7638 | bpr | 332 | if(tot>0) {d=mean/tot;} else d=0; |
12495 | bpr | 333 | /* cumulative score */ |
7407 | bpr | 334 | p1=moneyprint(p1,rint(100*tot/scoresum[i])); *p1++=' '; |
12495 | bpr | 335 | /* quality */ |
7638 | bpr | 336 | p1=moneyprint(p1,d); *p1++=' '; |
12495 | bpr | 337 | /* best */ |
7657 | bpr | 338 | p1=moneyprint(p1,rint(100*totb/scoresum[i])); *p1++=' '; |
12495 | bpr | 339 | /* level */ |
7657 | bpr | 340 | p1=moneyprint(p1,rint(10*totl/totw)); |
341 | |||
342 | *p1++='\n'; |
||
7407 | bpr | 343 | } |
344 | *p1=0; |
||
10 | reyssat | 345 | } |
12273 | bpr | 346 | /* [seed1,score1;seed2,score2;...] at most MAX_SCORESEED */ |
347 | void calc_getseedscores(char *p) |
||
348 | { |
||
349 | _getscore(p,sr_seedscores); |
||
350 | } |
||
351 | /* last seed (0 if there is no seed)*/ |
||
352 | void calc_getseedlast(char *p) |
||
353 | { |
||
354 | _getscore(p,sr_seedlast); |
||
355 | } |
||
356 | /* last score (-1 if does not exist) */ |
||
357 | void calc_getseedscorelast(char *p) |
||
358 | { |
||
359 | _getscore(p,sr_seedscorelast); |
||
360 | } |
||
10 | reyssat | 361 | |
12295 | bpr | 362 | /* number of occurences of the last seed */ |
363 | void calc_getseedlastcnt(char *p) |
||
364 | { |
||
365 | _getscore(p,sr_seedlastcnt); |
||
366 | } |
||
367 | |||
7407 | bpr | 368 | /* Returns the status of a sheet, or -1 if error */ |
10 | reyssat | 369 | int getsheetstatus(char *classe, int sheet) |
370 | { |
||
7407 | bpr | 371 | char *p, *st, buf[MAX_LINELEN+1], namebuf[MAX_FNAME+1]; |
372 | int i; |
||
10 | reyssat | 373 | |
7407 | bpr | 374 | if(isexam || score_isexam) st="exam"; else st="sheet"; |
375 | mkfname(namebuf,"%s/%s/%ss/.%ss",class_base,classe,st,st); |
||
376 | direct_datafile=1;datafile_fnd_record(namebuf,sheet,buf);direct_datafile=0; |
||
377 | p=find_word_start(buf); if(*p==0) return -1; |
||
378 | i=*p-'0'; if(i>5 || i<0) i=-1; |
||
379 | if((isexam || score_isexam) && i==0) { |
||
380 | p=getvar("wims_user"); if(p!=NULL && strcmp(p,"supervisor")==0) i=1; |
||
381 | } |
||
382 | return i; |
||
10 | reyssat | 383 | } |
384 | |||
13011 | bpr | 385 | /* return 1 if a word of bf2 is a substring of host |
386 | and if time restrictions are verified for wims_user |
||
8155 | bpr | 387 | * Content of bf2 is destroyed. |
388 | */ |
||
10303 | guerimand | 389 | int _subword(char bf2[],char *ftbuf) |
10 | reyssat | 390 | { |
7407 | bpr | 391 | char *p1, *p2; |
392 | for(p1=strchr(bf2,'\\'); p1!=NULL; p1=strchr(p1+1,'\\')) { |
||
393 | char buf[MAX_LINELEN+1], buf2[MAX_LINELEN+1], fbuf[MAX_FNAME+1]; |
||
394 | char *classp, *classp2, *userp, *scp; |
||
395 | classp=getvar("wims_class"); userp=getvar("wims_user"); |
||
396 | if(classp==NULL || userp==NULL || *classp==0 || *userp==0) break; |
||
397 | scp=getvar("wims_superclass"); |
||
398 | if(scp!=NULL && *scp!=0) classp2=scp; else classp2=classp; |
||
399 | if(p1>bf2 && !isspace(*(p1-1))) continue; |
||
400 | if(!isalnum(*(p1+1))) continue; |
||
401 | p2=find_word_end(p1); if(p2>=p1+MAX_NAMELEN) continue; |
||
402 | memmove(buf2, p1+1, p2-p1-1); buf2[p2-p1-1]=0; |
||
10303 | guerimand | 403 | /* get value of technical variable */ |
404 | snprintf(buf,sizeof(buf),"user_techvar_%s",buf2); |
||
7407 | bpr | 405 | if(strcmp(userp,"supervisor")==0) |
406 | mkfname(fbuf,"%s/%s/supervisor",class_base,classp); |
||
407 | else |
||
408 | mkfname(fbuf,"%s/%s/.users/%s",class_base,classp2,userp); |
||
10303 | guerimand | 409 | getdef(fbuf,buf,buf2); |
10365 | bpr | 410 | if(buf2[0]==0) ovlstrcpy(buf2,"EMPTY"); /* in case of no value defined for the user*/ |
10303 | guerimand | 411 | /* get time restriction for this value */ |
412 | snprintf(buf,sizeof(buf),"techvar_%s",buf2); |
||
13011 | bpr | 413 | /* mkfname(fbuf,"%s/%s/.E%s",class_base,classp,sheet); |
414 | * read time restriction corresponding to the value of |
||
415 | * technical variable in the file of the sheet or exam |
||
416 | */ |
||
10379 | bpr | 417 | getdef(ftbuf,buf,buf2); |
10303 | guerimand | 418 | if(buf2[0]==0) ovlstrcpy(buf2,"none"); |
419 | /*string_modify(bf2,p1,p2,buf2);*/ |
||
420 | bf2=buf2; |
||
7407 | bpr | 421 | p1+=strlen(buf2); |
422 | } |
||
423 | if((isexam || score_isexam) && bf2[0]=='#') return 1; |
||
424 | if(wordchr(bf2,"none")!=NULL) return 0; |
||
425 | if(wordchr(bf2,"all")!=NULL) return 1; |
||
426 | p1=find_word_start(bf2); if(*p1==0) return 1; |
||
13011 | bpr | 427 | /* check host and time */ |
7407 | bpr | 428 | return checkhostt(p1); |
10 | reyssat | 429 | } |
430 | |||
13011 | bpr | 431 | /* Returns 1 if score registration is open for the user |
432 | * in variable wims_user, 0 otherwise. |
||
433 | */ |
||
10 | reyssat | 434 | int _getscorestatus(char *classe, int sheet) |
435 | { |
||
7407 | bpr | 436 | char nbuf[MAX_LINELEN+1], gbuf[MAX_LINELEN+1]; |
10303 | guerimand | 437 | char ftbuf[MAX_FNAME+1]=""; |
7407 | bpr | 438 | char *es; |
10 | reyssat | 439 | |
7407 | bpr | 440 | if(classe==NULL || *classe==0 || sheet<=0) return 1; |
441 | if(getsheetstatus(classe,sheet)!=1) return 0; |
||
442 | if(*remote_addr==0) return 0; |
||
443 | if(isexam || score_isexam) { /* exam simulation */ |
||
444 | accessfile(nbuf,"r","%s/%s/.E%d",class_base,classe,sheet); |
||
445 | if(nbuf[0]=='#') return 1; |
||
446 | } |
||
12814 | bpr | 447 | /* Global restriction data */ |
7407 | bpr | 448 | accessfile(nbuf,"r","%s/%s/.security",class_base,classe); |
449 | if(nbuf[0]) { |
||
450 | _getdef(nbuf,"allow",gbuf); |
||
10303 | guerimand | 451 | if(*find_word_start(gbuf)!=0 && _subword(gbuf,ftbuf)==0) |
7407 | bpr | 452 | return 0; |
453 | _getdef(nbuf,"except",gbuf); |
||
10303 | guerimand | 454 | if(*find_word_start(gbuf)!=0 && _subword(gbuf,ftbuf)==1) |
7407 | bpr | 455 | return 0; |
456 | } |
||
13011 | bpr | 457 | /* Sheet restriction data; take in account the technical variables */ |
7407 | bpr | 458 | if(isexam || score_isexam) es="E"; else es=""; |
459 | accessfile(nbuf,"r","%s/%s/.%s%d",class_base,classe,es,sheet); |
||
460 | if(*find_word_start(nbuf)==0) return 1; |
||
12814 | bpr | 461 | /* preparing score restriction file name :*/ |
10303 | guerimand | 462 | mkfname(ftbuf,"%s/%s/.%s%d",class_base,classe,es,sheet); |
463 | return _subword(nbuf,ftbuf); |
||
10 | reyssat | 464 | } |
465 | |||
13011 | bpr | 466 | /* Returns 1 if score registration is open for wims_user, 0 otherwise.*/ |
10 | reyssat | 467 | int getscorestatus(char *classe, int sheet) |
468 | { |
||
7407 | bpr | 469 | if(score_status<0 || score_statussheet!=sheet |
470 | || score_statusisexam!=isexam) { |
||
471 | score_statussheet=sheet; score_statusisexam=isexam; |
||
472 | score_status=_getscorestatus(classe,sheet); score_isexam=0; |
||
473 | if(score_status==1 && (cmd_type==cmd_new || cmd_type==cmd_renew |
||
7646 | bpr | 474 | || isexam)) { |
7407 | bpr | 475 | char *p; |
476 | p=getvar("wims_scorereg"); |
||
477 | if(p==NULL || strcmp(p,"suspend")!=0) |
||
7646 | bpr | 478 | setvar("wims_scoring","pending"); |
7407 | bpr | 479 | else setvar("wims_scoring",""); |
10 | reyssat | 480 | } |
7407 | bpr | 481 | } |
482 | if(isexam && score_status==0) { |
||
483 | char *p; |
||
13557 | obado | 484 | p=getvar("wims_user"); |
485 | if(p==NULL || strcmp(p,"supervisor")!=0) |
||
486 | user_error("exam_closed"); |
||
7407 | bpr | 487 | } |
488 | return score_status; |
||
10 | reyssat | 489 | } |
490 | |||
7407 | bpr | 491 | /* Whether score registering is open */ |
10 | reyssat | 492 | void calc_getscorestatus(char *p) |
493 | { |
||
7407 | bpr | 494 | _scoreparm(p); |
495 | if(*score_class==0 || score_sheet==0 || *score_user==0) { |
||
496 | *p=0; return; |
||
497 | } |
||
498 | if(getscorestatus(score_class, score_sheet)) |
||
499 | ovlstrcpy(p,"yes"); |
||
500 | else ovlstrcpy(p,"no"); |
||
10 | reyssat | 501 | } |
502 | |||
13011 | bpr | 503 | /* whether there are too much tries for the exo return yes or no */ |
12213 | bpr | 504 | void calc_getscoremaxexotry(char *p) |
505 | { |
||
506 | _scoreparm(p); |
||
507 | if(*score_class==0 || *score_user==0 || score_sheet==0 || score_exo==0) return; |
||
508 | if(gettrycheck(score_class, score_user, score_sheet, score_exo)==1) |
||
509 | ovlstrcpy(p,"yes"); |
||
510 | else ovlstrcpy(p,"no"); |
||
511 | } |
||
512 | |||
3603 | reyssat | 513 | double exam_scoredata[MAX_EXOS]; |
10 | reyssat | 514 | |
7407 | bpr | 515 | /* get current exam score */ |
10 | reyssat | 516 | void exam_currscore(int esh) |
517 | { |
||
7407 | bpr | 518 | char *p, *bf, pb[MAX_FNAME+1]; |
519 | char *s, *p1, *p2, *e1, *e2; |
||
520 | int i; |
||
521 | for(i=0;i<MAX_EXOS;i++) exam_scoredata[i]=-1000; |
||
12814 | bpr | 522 | /* session_prefix is not yet defined here */ |
7407 | bpr | 523 | s=getvar("wims_session"); if(s==NULL || *s==0) return; |
524 | mystrncpy(pb,s,sizeof(pb)); |
||
525 | p=strchr(pb,'_'); if(p!=NULL) *p=0; |
||
526 | bf=readfile(mkfname(NULL,"%s/%s/examscore.%d",session_dir,pb,esh),NULL,WORKFILE_LIMIT); |
||
527 | if(bf==NULL) return; |
||
528 | for(p1=bf;*p1;p1=p2) { |
||
529 | p2=strchr(p1,'\n'); if(*p2) *p2++=0; |
||
530 | else p2=p1+strlen(p1); |
||
531 | p1=find_word_start(find_word_end(find_word_start(p1))); |
||
532 | e1=find_word_end(p1); if(*e1) *e1++=0; |
||
533 | e1=find_word_start(e1); e2=find_word_start(find_word_end(e1)); |
||
534 | *find_word_end(e1)=0; |
||
535 | i=atoi(p1); |
||
536 | if(i>=1 && i<=MAX_EXOS && |
||
537 | exam_scoredata[i-1]==-1000 && strcmp(e1,"score")==0) { |
||
538 | *find_word_end(e2)=0; |
||
539 | exam_scoredata[i-1]=atof(e2); |
||
10 | reyssat | 540 | } |
7407 | bpr | 541 | } |
542 | free(bf); |
||
10 | reyssat | 543 | } |
544 | |||
7407 | bpr | 545 | /* Gather exam score. */ |
10 | reyssat | 546 | void calc_examscore(char *p) |
547 | { |
||
7407 | bpr | 548 | char *p1; |
549 | int i; |
||
9692 | bpr | 550 | char *withoutip; |
7407 | bpr | 551 | |
552 | _scoreparm(p); *p=0; |
||
9692 | bpr | 553 | withoutip=getvar("wims_examscore_withoutip"); |
554 | |||
7407 | bpr | 555 | if(*score_class==0 || *score_user==0) return; |
556 | if(getscoreuser(score_class,score_user)<0) return; |
||
557 | p1=p; |
||
9692 | bpr | 558 | if(withoutip!=NULL && strcmp(withoutip,"yes")==0) { |
559 | for(i=0; i<examcnt && p1-p<MAX_LINELEN-32; i++) { |
||
560 | p1=moneyprint(p1,rscore[examstart+i].best); *p1++=' '; |
||
561 | } |
||
562 | } else { |
||
563 | for(i=0; i<examcnt && p1-p<MAX_LINELEN-32; i++) { |
||
564 | p1=moneyprint(p1,rscore[examstart+i].score); *p1++=' '; |
||
565 | } |
||
7407 | bpr | 566 | } |
567 | *p1++='\n'; |
||
568 | for(i=0; i<examcnt && p1-p<MAX_LINELEN-32; i++) { |
||
569 | p1=moneyprint(p1,rscore[examstart+i].require); *p1++=' '; |
||
570 | p1=moneyprint(p1,floor(rscore[examstart+i].mean/2)); *p1++=' '; |
||
571 | p1=moneyprint(p1,(int) rscore[examstart+i].mean%2); *p1++='\n'; |
||
572 | } |
||
573 | *p1=0; |
||
10 | reyssat | 574 | } |
575 | |||
7407 | bpr | 576 | /* check score dependency. |
8155 | bpr | 577 | * returns 1 if requirements are met. |
578 | */ |
||
10 | reyssat | 579 | int _depcheck(char *ds, struct scoreresult *rs, int ecnt) |
580 | { |
||
7407 | bpr | 581 | char *p1, *p2, *p3, *p4, *pp; |
582 | int perc, t, sum; |
||
583 | double tgot, ttot, tmean; |
||
584 | |||
585 | for(p1=ds; *p1; p1=p3) { |
||
586 | p2=strchr(p1,':'); if(p2==NULL) break; |
||
587 | *p2++=0; p2=find_word_start(p2); |
||
588 | for(p3=p2; myisdigit(*p3); p3++); |
||
589 | if(p3<=p2) break; |
||
15707 | bpr | 590 | if(*p3) *p3++=0; |
591 | perc=atoi(p2); |
||
7407 | bpr | 592 | if(perc<=0 || perc>100) break; |
593 | for(pp=p1; *pp; pp++) if(!myisdigit(*pp)) *pp=' '; |
||
594 | tgot=ttot=tmean=0; sum=0; |
||
595 | for(pp=find_word_start(p1); *pp; pp=find_word_start(p4)) { |
||
596 | p4=find_word_end(pp); if(*p4) *p4++=0; |
||
597 | t=atoi(pp); if(t<=0 || t>ecnt) goto lend; |
||
598 | t--; |
||
599 | ttot+=rs[t].require; tgot+=rs[t].score; tmean+=rs[t].mean; |
||
600 | sum++; |
||
10 | reyssat | 601 | } |
7407 | bpr | 602 | if(ttot<10) continue; |
603 | if(tgot/ttot*sqrt(tmean/(sum*10))*100<perc) { |
||
604 | for(pp=p1;pp<p2-1;pp++) if(!*pp) *pp=','; |
||
605 | *pp=0; setvar("dep_list",p1); |
||
606 | return 0; |
||
607 | } |
||
608 | lend: ; |
||
609 | } |
||
610 | return 1; |
||
10 | reyssat | 611 | } |
612 | |||
613 | int depcheck(char *sh, int exo, char *deps) |
||
614 | { |
||
7407 | bpr | 615 | char buf[MAX_LINELEN+1]; |
616 | char *s, sbuf[64]; |
||
617 | int i, is; |
||
618 | |||
619 | s=getvar("wims_session"); |
||
620 | if(s==NULL || *s==0 || strstr(s,"robot")!=NULL) return 0; |
||
621 | mystrncpy(sbuf,s,sizeof(sbuf)); |
||
622 | s=strchr(sbuf,'_'); if(s) *s=0; |
||
623 | accessfile(buf,"r","../sessions/%s/exodep.%s",sbuf,sh); |
||
624 | if(buf[0]==0) { /* no dep file found */ |
||
625 | is=atoi(sh); if(is<=0 || is>totsheets) return 0; |
||
626 | s=getvar("wims_class"); if(s==NULL || *s==0) return 0; |
||
627 | getscoreuser(s,""); |
||
628 | return _depcheck(deps,rscore+sheetstart[is-1],shexocnt[is-1]); |
||
629 | } |
||
630 | for(i=1,s=strchr(buf,':'); s && i<exo; i++, s=strchr(s+1,':')); |
||
631 | if(s==NULL) return 0; /* bad file or exo number */ |
||
632 | if(myisdigit(*++s)) return 0; else return 1; |
||
10 | reyssat | 633 | } |
634 | |||
635 | int exam_depcheck(char *deps, int exam) |
||
636 | { |
||
12409 | bpr | 637 | static struct scoreresult esc[MAX_EXOS]; |
7407 | bpr | 638 | int i; |
639 | exam_currscore(exam); |
||
640 | for(i=0;i<MAX_EXOS;i++) { |
||
641 | esc[i].require=esc[i].mean=10; |
||
642 | if(exam_scoredata[i]==-1000) esc[i].score=0; |
||
643 | else esc[i].score=exam_scoredata[i]; |
||
644 | } |
||
645 | return _depcheck(deps,esc,MAX_EXOS); |
||
10 | reyssat | 646 | } |
12213 | bpr | 647 | |
12276 | bpr | 648 | /* public sheet gives she=0 */ |
12495 | bpr | 649 | /* return 1 if score is no more taken in account because of exotrymax */ |
12213 | bpr | 650 | int gettrycheck(char *classe, char *user, int she, int exo) { |
651 | char *s; |
||
652 | int sh, ex, i; |
||
13232 | bpr | 653 | if(classe==NULL || *classe==0 || user==NULL || *user==0) return 0; |
12276 | bpr | 654 | if (she<=0) return 0; |
13232 | bpr | 655 | if(strcmp(user,"supervisor")==0) return 0; |
12213 | bpr | 656 | s=getvar("exotrymax"); |
12527 | bpr | 657 | if(s==NULL || *s==0) return 0; |
12213 | bpr | 658 | getscoreuser(classe,user); |
12527 | bpr | 659 | char *p=getvar("wims_scorereg"); |
12213 | bpr | 660 | for(i=0;i<scorecnt;i++) { |
15847 | bpr | 661 | sh=rscore[i].sh+1; |
12213 | bpr | 662 | if (she!=sh) continue; |
15847 | bpr | 663 | ex=rscore[i].exo+1; |
12213 | bpr | 664 | if(exo!=ex) continue; |
12381 | bpr | 665 | if(cmd_type==cmd_new || cmd_type==cmd_renew) |
12527 | bpr | 666 | if(rscore[i].new >= atoi(s)) { |
667 | if(strcmp(p,"suspend")!=0) setvar("wims_scorereg","exotrymax"); |
||
668 | return 1; |
||
669 | } |
||
670 | if(rscore[i].new > atoi(s)){ |
||
671 | if(strcmp(p,"suspend")!=0) setvar("wims_scorereg","exotrymax"); |
||
13015 | bpr | 672 | return 1; |
12527 | bpr | 673 | } |
12508 | bpr | 674 | } |
12213 | bpr | 675 | return 0; |
676 | } |
||
12273 | bpr | 677 | |
678 | /* return seed if the seed should be kept and NULL if not */ |
||
12369 | bpr | 679 | char *getseedscore(char *classe, char *user, int she, int exo) { |
12273 | bpr | 680 | char *s; |
681 | int sh, ex, i; |
||
12276 | bpr | 682 | if (she<=0) return NULL; |
12273 | bpr | 683 | if(strcmp(user,"supervisor")==0) return NULL; |
684 | s=getvar("seedrepeat"); |
||
12990 | bpr | 685 | if(s==NULL || *s==0 || atoi(s)<=0) return NULL; |
12273 | bpr | 686 | getscoreuser(classe,user); |
687 | for(i=0;i<scorecnt;i++) { |
||
15847 | bpr | 688 | sh=rscore[i].sh+1; |
12273 | bpr | 689 | if (she!=sh) continue; |
15847 | bpr | 690 | ex=rscore[i].exo+1; |
12273 | bpr | 691 | if(exo!=ex) continue; |
12432 | bpr | 692 | if(atoi(rscore[i].seedlast)==0) { |
693 | char *seed=getvar("wims_seed"); |
||
694 | return seed; |
||
695 | } |
||
12390 | bpr | 696 | if(rscore[i].seedlastcnt > MAX_SEEDSCORE) return NULL; |
12445 | bpr | 697 | if(atoi(s)>0 && rscore[i].seedlastcnt >= atoi(s) && cmd_type!=cmd_next) return NULL; |
12432 | bpr | 698 | if(rscore[i].seedscorelast < 10) return rscore[i].seedlast; |
12273 | bpr | 699 | }; |
700 | return NULL; |
||
701 | } |