Rev 13557 | Rev 14134 | 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 | { |
||
7407 | bpr | 48 | int i, j, osh, sh; |
49 | double s; |
||
50 | char *nowuser, *nowsheet, *nowexo, *nowscore; |
||
51 | char *pp; |
||
12196 | bpr | 52 | if(user==NULL || *user==0) { |
7407 | bpr | 53 | user=getvar("wims_user"); |
54 | if(user==NULL || *user==0) return -1; |
||
55 | } |
||
56 | if(strcmp(classe,rscore_class)==0 && strcmp(user,rscore_user)==0) return 0; |
||
57 | nowsheet=nowexo=nowscore=""; |
||
12495 | bpr | 58 | nowuser=getvar("wims_user"); |
59 | if(nowuser!=NULL && strcmp(user,nowuser)==0) { |
||
12196 | bpr | 60 | nowscore=getvar("module_score"); |
61 | if(nowscore!=NULL && *nowscore!=0) { |
||
62 | nowsheet=getvar("wims_sheet"); |
||
63 | if(nowsheet==NULL) nowsheet=""; |
||
64 | nowexo=getvar("wims_exo"); |
||
65 | if(nowexo==NULL) nowexo=""; |
||
10 | reyssat | 66 | } |
7407 | bpr | 67 | else nowscore=""; |
68 | } |
||
69 | snprintf(scorebuf+sizeof(int),sizeof(scorebuf)-sizeof(int), |
||
7646 | bpr | 70 | "-c%s -u%s getscore %s %s %s", |
71 | classe,user,nowsheet,nowexo,nowscore); |
||
72 | i=kerneld(scorebuf,sizeof(scorebuf)); |
||
73 | if(i<0) internal_error("getscoreuser(): daemon failure."); |
||
7407 | bpr | 74 | if(memcmp(scorebuf+sizeof(int),"OK",2)!=0) { |
75 | if(memcmp(scorebuf+sizeof(int),"ERROR",5)==0) { |
||
76 | module_error(find_word_start(scorebuf+sizeof(int)+8)); |
||
10 | reyssat | 77 | } |
7407 | bpr | 78 | else internal_error("getscoreuser(): communication error with wimslogd."); |
79 | } |
||
8340 | bpr | 80 | /* 3 is here the length of "OK " */ |
7407 | bpr | 81 | pp=scorebuf+sizeof(int)+3; rscore=(struct scoreresult *) pp; |
82 | scorecnt=(i-sizeof(int)-3)/sizeof(scoreresult); |
||
83 | if(scorecnt>MAX_CLASSEXOS) module_error("too_many_exercises"); |
||
84 | s=0; for(i=osh=0;i<scorecnt;i++) { |
||
85 | sh=(rscore[i].num>>8)+1; |
||
86 | if(sh<1 || sh>MAX_SHEETS) break; |
||
87 | if(osh>0 && osh<sh) {scoresum[osh-1]=s; s=0;} |
||
88 | for(;osh<sh && osh<MAX_SHEETS;osh++) sheetstart[osh]=i; |
||
89 | s+=rscore[i].require*rscore[i].weight; |
||
90 | } |
||
8338 | bpr | 91 | if(osh>0) scoresum[osh-1]=s; |
92 | totsheets=osh; |
||
7407 | bpr | 93 | for(j=0;j<totsheets-1;j++) shexocnt[j]=sheetstart[j+1]-sheetstart[j]; |
94 | shexocnt[totsheets-1]=i-sheetstart[totsheets-1]; |
||
95 | examstart=i; examcnt=scorecnt-examstart; |
||
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; |
||
8155 | bpr | 185 | /* 2^8 no_sheet + no_exo_in_the_sheet so limit no_exo to 2^8 */ |
12222 | bpr | 186 | for(i=osh=0,p1=p;i<scorecnt && p1-p<MAX_LINELEN-32;i++) { |
187 | sh=(rscore[i].num>>8)+1; if(sh<1 || sh>MAX_SHEETS) break; |
||
188 | if(score_sheet!=0) { |
||
189 | if(sh<score_sheet) continue; |
||
190 | if(sh>score_sheet || sh>MAX_SHEETS) break; |
||
191 | } |
||
192 | ex=((rscore[i].num)&255)+1; |
||
193 | if(score_exo!=0 && ex!=score_exo) continue; |
||
194 | if(osh!=0 && sh!=osh) *p1++='\n'; |
||
195 | switch(dtype) { |
||
196 | case sr_require: {d=rscore[i].require; break;} |
||
197 | case sr_weight: {d=rscore[i].weight; break;} |
||
198 | case sr_score: {d=rscore[i].score; break;} |
||
199 | case sr_mean: {d=rscore[i].mean; break;} |
||
200 | case sr_remain: {d=rscore[i].require-rscore[i].score; break;} |
||
201 | case sr_last: {d=rscore[i].last; break;} |
||
202 | case sr_try: {d=rscore[i].try; break;} |
||
12230 | bpr | 203 | case sr_new: {d=rscore[i].new; break;} |
12222 | bpr | 204 | case sr_best: {d=rscore[i].best; break;} |
12273 | bpr | 205 | case sr_level: {d=rscore[i].level; break;} |
206 | case sr_seedscorelast: {d=rscore[i].seedscorelast; break;} |
||
12295 | bpr | 207 | case sr_seedlastcnt: {d=rscore[i].seedlastcnt; break;} |
12273 | bpr | 208 | case sr_seedlast: { mystrncpy(dc,rscore[i].seedlast,SEEDSIZE); |
209 | break; |
||
210 | } |
||
211 | case sr_seedscores: { |
||
212 | mystrncpy(ds,rscore[i].seedscores,SEEDSCORES); break; |
||
213 | } |
||
12222 | bpr | 214 | default: {d=0; break;} |
215 | } |
||
12273 | bpr | 216 | switch(dtype) { |
217 | case sr_seedlast: |
||
218 | { snprintf(p1,SEEDSIZE, "%s", dc); p1+=strlen(p1); break; } |
||
219 | case sr_seedscores: |
||
220 | { snprintf(p1,SEEDSCORES, "%s", ds); p1+=strlen(p1); break; } |
||
221 | default: |
||
222 | { p1=moneyprint(p1,d); } |
||
223 | } |
||
224 | *p1++=' '; |
||
12222 | bpr | 225 | osh=sh; |
226 | } |
||
227 | *p1++='\n'; *p1=0; |
||
10 | reyssat | 228 | } |
229 | |||
7407 | bpr | 230 | /* gather user score. */ |
10 | reyssat | 231 | void calc_getscore(char *p) |
232 | { |
||
7407 | bpr | 233 | _getscore(p,sr_score); |
10 | reyssat | 234 | } |
235 | |||
7407 | bpr | 236 | /* gather user score average. */ |
10 | reyssat | 237 | void calc_getscoremean(char *p) |
238 | { |
||
7407 | bpr | 239 | _getscore(p,sr_mean); |
10 | reyssat | 240 | } |
241 | |||
7407 | bpr | 242 | /* gather remaining of score to get for user. */ |
10 | reyssat | 243 | void calc_getscoreremain(char *p) |
244 | { |
||
7407 | bpr | 245 | _getscore(p,sr_remain); |
10 | reyssat | 246 | } |
247 | |||
7407 | bpr | 248 | /* Require score table. */ |
10 | reyssat | 249 | void calc_getscorerequire(char *p) |
250 | { |
||
7407 | bpr | 251 | _getscore(p,sr_require); |
10 | reyssat | 252 | } |
253 | |||
7407 | bpr | 254 | /* Score weight table. */ |
10 | reyssat | 255 | void calc_getscoreweight(char *p) |
256 | { |
||
7407 | bpr | 257 | _getscore(p,sr_weight); |
10 | reyssat | 258 | } |
14126 | obado | 259 | /* user last score */ |
7602 | bpr | 260 | void calc_getscorelast(char *p) |
261 | { |
||
262 | _getscore(p,sr_last); |
||
263 | } |
||
12196 | bpr | 264 | /* gather user score try numbers with score activated. */ |
7602 | bpr | 265 | void calc_getscoretry(char *p) |
266 | { |
||
267 | _getscore(p,sr_try); |
||
268 | } |
||
12220 | bpr | 269 | /* gather all user try numbers (terminated or not, but with notation activated)*/ |
12197 | bpr | 270 | void calc_getscorealltries(char *p) |
12196 | bpr | 271 | { |
12230 | bpr | 272 | _getscore(p,sr_new); |
12196 | bpr | 273 | } |
7602 | bpr | 274 | |
7657 | bpr | 275 | /* if the required points are 10* N, gather N user best scores */ |
7638 | bpr | 276 | void calc_getscorebest(char *p) |
277 | { |
||
278 | _getscore(p,sr_best); |
||
279 | } |
||
280 | |||
7657 | bpr | 281 | /* gather user score average. */ |
282 | void calc_getscorelevel(char *p) |
||
283 | { |
||
284 | _getscore(p,sr_level); |
||
285 | } |
||
286 | |||
7638 | bpr | 287 | /* percentage of work done for each sheet: |
7657 | bpr | 288 | * score mean best level |
289 | * as follows |
||
14126 | obado | 290 | * score=100*cumulative_points/required_points (< 100) |
7665 | bpr | 291 | * mean=quality (<10) |
292 | * best=10*(required/10 best_scores)/required_points (< 100) |
||
293 | * level=minimum of the required/10 best_scores (< 10) |
||
7638 | bpr | 294 | */ |
7657 | bpr | 295 | |
296 | void calc_getscorepercent(char *p) |
||
10 | reyssat | 297 | { |
7407 | bpr | 298 | int i,j,jend; |
7657 | bpr | 299 | double tot, mean, totb, totl, totw, d; |
7407 | bpr | 300 | char *p1; |
10 | reyssat | 301 | |
7407 | bpr | 302 | _scoreparm(p); |
303 | if(*score_class==0 || *score_user==0) return; |
||
304 | if(getscoreuser(score_class,score_user)<0) return; |
||
305 | for(p1=p,i=0;i<totsheets && p1-p<MAX_LINELEN-32;i++) { |
||
306 | if(scoresum[i]==0) { |
||
7657 | bpr | 307 | ovlstrcpy(p1,"0 0 0 0\n"); p1+=strlen(p1); continue; |
10 | reyssat | 308 | } |
7407 | bpr | 309 | if(score_sheet!=0 && i!=score_sheet-1) continue; |
310 | if(scoresum[i]<=0) *p1++='\n'; |
||
7657 | bpr | 311 | tot=mean=totb=totl=totw=0; jend=sheetstart[i]+shexocnt[i]; |
7407 | bpr | 312 | for(j=sheetstart[i];j<jend;j++) { |
12495 | bpr | 313 | /* if mean<1 then ignore score. |
314 | * if mean<2 then half score. |
||
315 | */ |
||
7407 | bpr | 316 | if(rscore[j].mean>=1) { |
7646 | bpr | 317 | double dt=rscore[j].score; |
318 | float db=rscore[j].best; |
||
7657 | bpr | 319 | float dl=rscore[j].level; |
320 | if(rscore[j].mean<2) {dt=dt/2; db=db/2; dl=dl/2;} |
||
7646 | bpr | 321 | d=dt*rscore[j].weight; |
12495 | bpr | 322 | /* quality */ |
7646 | bpr | 323 | mean+=rscore[j].mean*d; |
12495 | bpr | 324 | /* cumulative score */ |
7646 | bpr | 325 | tot+=d; |
12495 | bpr | 326 | /* best */ |
7646 | bpr | 327 | totb+=db*rscore[j].weight; |
12495 | bpr | 328 | /* level */ |
7657 | bpr | 329 | totl+=dl*rscore[j].weight; |
330 | totw+=rscore[j].weight; |
||
7407 | bpr | 331 | } |
332 | } |
||
7638 | bpr | 333 | if(tot>0) {d=mean/tot;} else d=0; |
12495 | bpr | 334 | /* cumulative score */ |
7407 | bpr | 335 | p1=moneyprint(p1,rint(100*tot/scoresum[i])); *p1++=' '; |
12495 | bpr | 336 | /* quality */ |
7638 | bpr | 337 | p1=moneyprint(p1,d); *p1++=' '; |
12495 | bpr | 338 | /* best */ |
7657 | bpr | 339 | p1=moneyprint(p1,rint(100*totb/scoresum[i])); *p1++=' '; |
12495 | bpr | 340 | /* level */ |
7657 | bpr | 341 | p1=moneyprint(p1,rint(10*totl/totw)); |
342 | |||
343 | *p1++='\n'; |
||
7407 | bpr | 344 | } |
345 | *p1=0; |
||
10 | reyssat | 346 | } |
12273 | bpr | 347 | /* [seed1,score1;seed2,score2;...] at most MAX_SCORESEED */ |
348 | void calc_getseedscores(char *p) |
||
349 | { |
||
350 | _getscore(p,sr_seedscores); |
||
351 | } |
||
352 | /* last seed (0 if there is no seed)*/ |
||
353 | void calc_getseedlast(char *p) |
||
354 | { |
||
355 | _getscore(p,sr_seedlast); |
||
356 | } |
||
357 | /* last score (-1 if does not exist) */ |
||
358 | void calc_getseedscorelast(char *p) |
||
359 | { |
||
360 | _getscore(p,sr_seedscorelast); |
||
361 | } |
||
10 | reyssat | 362 | |
12295 | bpr | 363 | /* number of occurences of the last seed */ |
364 | void calc_getseedlastcnt(char *p) |
||
365 | { |
||
366 | _getscore(p,sr_seedlastcnt); |
||
367 | } |
||
368 | |||
7407 | bpr | 369 | /* Returns the status of a sheet, or -1 if error */ |
10 | reyssat | 370 | int getsheetstatus(char *classe, int sheet) |
371 | { |
||
7407 | bpr | 372 | char *p, *st, buf[MAX_LINELEN+1], namebuf[MAX_FNAME+1]; |
373 | int i; |
||
10 | reyssat | 374 | |
7407 | bpr | 375 | if(isexam || score_isexam) st="exam"; else st="sheet"; |
376 | mkfname(namebuf,"%s/%s/%ss/.%ss",class_base,classe,st,st); |
||
377 | direct_datafile=1;datafile_fnd_record(namebuf,sheet,buf);direct_datafile=0; |
||
378 | p=find_word_start(buf); if(*p==0) return -1; |
||
379 | i=*p-'0'; if(i>5 || i<0) i=-1; |
||
380 | if((isexam || score_isexam) && i==0) { |
||
381 | p=getvar("wims_user"); if(p!=NULL && strcmp(p,"supervisor")==0) i=1; |
||
382 | } |
||
383 | return i; |
||
10 | reyssat | 384 | } |
385 | |||
13011 | bpr | 386 | /* return 1 if a word of bf2 is a substring of host |
387 | and if time restrictions are verified for wims_user |
||
8155 | bpr | 388 | * Content of bf2 is destroyed. |
389 | */ |
||
10303 | guerimand | 390 | int _subword(char bf2[],char *ftbuf) |
10 | reyssat | 391 | { |
7407 | bpr | 392 | char *p1, *p2; |
393 | for(p1=strchr(bf2,'\\'); p1!=NULL; p1=strchr(p1+1,'\\')) { |
||
394 | char buf[MAX_LINELEN+1], buf2[MAX_LINELEN+1], fbuf[MAX_FNAME+1]; |
||
395 | char *classp, *classp2, *userp, *scp; |
||
396 | classp=getvar("wims_class"); userp=getvar("wims_user"); |
||
397 | if(classp==NULL || userp==NULL || *classp==0 || *userp==0) break; |
||
398 | scp=getvar("wims_superclass"); |
||
399 | if(scp!=NULL && *scp!=0) classp2=scp; else classp2=classp; |
||
400 | if(p1>bf2 && !isspace(*(p1-1))) continue; |
||
401 | if(!isalnum(*(p1+1))) continue; |
||
402 | p2=find_word_end(p1); if(p2>=p1+MAX_NAMELEN) continue; |
||
403 | memmove(buf2, p1+1, p2-p1-1); buf2[p2-p1-1]=0; |
||
10303 | guerimand | 404 | /* get value of technical variable */ |
405 | snprintf(buf,sizeof(buf),"user_techvar_%s",buf2); |
||
7407 | bpr | 406 | if(strcmp(userp,"supervisor")==0) |
407 | mkfname(fbuf,"%s/%s/supervisor",class_base,classp); |
||
408 | else |
||
409 | mkfname(fbuf,"%s/%s/.users/%s",class_base,classp2,userp); |
||
10303 | guerimand | 410 | getdef(fbuf,buf,buf2); |
10365 | bpr | 411 | if(buf2[0]==0) ovlstrcpy(buf2,"EMPTY"); /* in case of no value defined for the user*/ |
10303 | guerimand | 412 | /* get time restriction for this value */ |
413 | snprintf(buf,sizeof(buf),"techvar_%s",buf2); |
||
13011 | bpr | 414 | /* mkfname(fbuf,"%s/%s/.E%s",class_base,classp,sheet); |
415 | * read time restriction corresponding to the value of |
||
416 | * technical variable in the file of the sheet or exam |
||
417 | */ |
||
10379 | bpr | 418 | getdef(ftbuf,buf,buf2); |
10303 | guerimand | 419 | if(buf2[0]==0) ovlstrcpy(buf2,"none"); |
420 | /*string_modify(bf2,p1,p2,buf2);*/ |
||
421 | bf2=buf2; |
||
7407 | bpr | 422 | p1+=strlen(buf2); |
423 | } |
||
424 | if((isexam || score_isexam) && bf2[0]=='#') return 1; |
||
425 | if(wordchr(bf2,"none")!=NULL) return 0; |
||
426 | if(wordchr(bf2,"all")!=NULL) return 1; |
||
427 | p1=find_word_start(bf2); if(*p1==0) return 1; |
||
13011 | bpr | 428 | /* check host and time */ |
7407 | bpr | 429 | return checkhostt(p1); |
10 | reyssat | 430 | } |
431 | |||
13011 | bpr | 432 | /* Returns 1 if score registration is open for the user |
433 | * in variable wims_user, 0 otherwise. |
||
434 | */ |
||
10 | reyssat | 435 | int _getscorestatus(char *classe, int sheet) |
436 | { |
||
7407 | bpr | 437 | char nbuf[MAX_LINELEN+1], gbuf[MAX_LINELEN+1]; |
10303 | guerimand | 438 | char ftbuf[MAX_FNAME+1]=""; |
7407 | bpr | 439 | char *es; |
10 | reyssat | 440 | |
7407 | bpr | 441 | if(classe==NULL || *classe==0 || sheet<=0) return 1; |
442 | if(getsheetstatus(classe,sheet)!=1) return 0; |
||
443 | if(*remote_addr==0) return 0; |
||
444 | if(isexam || score_isexam) { /* exam simulation */ |
||
445 | accessfile(nbuf,"r","%s/%s/.E%d",class_base,classe,sheet); |
||
446 | if(nbuf[0]=='#') return 1; |
||
447 | } |
||
12814 | bpr | 448 | /* Global restriction data */ |
7407 | bpr | 449 | accessfile(nbuf,"r","%s/%s/.security",class_base,classe); |
450 | if(nbuf[0]) { |
||
451 | _getdef(nbuf,"allow",gbuf); |
||
10303 | guerimand | 452 | if(*find_word_start(gbuf)!=0 && _subword(gbuf,ftbuf)==0) |
7407 | bpr | 453 | return 0; |
454 | _getdef(nbuf,"except",gbuf); |
||
10303 | guerimand | 455 | if(*find_word_start(gbuf)!=0 && _subword(gbuf,ftbuf)==1) |
7407 | bpr | 456 | return 0; |
457 | } |
||
13011 | bpr | 458 | /* Sheet restriction data; take in account the technical variables */ |
7407 | bpr | 459 | if(isexam || score_isexam) es="E"; else es=""; |
460 | accessfile(nbuf,"r","%s/%s/.%s%d",class_base,classe,es,sheet); |
||
461 | if(*find_word_start(nbuf)==0) return 1; |
||
12814 | bpr | 462 | /* preparing score restriction file name :*/ |
10303 | guerimand | 463 | mkfname(ftbuf,"%s/%s/.%s%d",class_base,classe,es,sheet); |
464 | return _subword(nbuf,ftbuf); |
||
10 | reyssat | 465 | } |
466 | |||
13011 | bpr | 467 | /* Returns 1 if score registration is open for wims_user, 0 otherwise.*/ |
10 | reyssat | 468 | int getscorestatus(char *classe, int sheet) |
469 | { |
||
7407 | bpr | 470 | if(score_status<0 || score_statussheet!=sheet |
471 | || score_statusisexam!=isexam) { |
||
472 | score_statussheet=sheet; score_statusisexam=isexam; |
||
473 | score_status=_getscorestatus(classe,sheet); score_isexam=0; |
||
474 | if(score_status==1 && (cmd_type==cmd_new || cmd_type==cmd_renew |
||
7646 | bpr | 475 | || isexam)) { |
7407 | bpr | 476 | char *p; |
477 | p=getvar("wims_scorereg"); |
||
478 | if(p==NULL || strcmp(p,"suspend")!=0) |
||
7646 | bpr | 479 | setvar("wims_scoring","pending"); |
7407 | bpr | 480 | else setvar("wims_scoring",""); |
10 | reyssat | 481 | } |
7407 | bpr | 482 | } |
483 | if(isexam && score_status==0) { |
||
484 | char *p; |
||
13557 | obado | 485 | p=getvar("wims_user"); |
486 | if(p==NULL || strcmp(p,"supervisor")!=0) |
||
487 | user_error("exam_closed"); |
||
7407 | bpr | 488 | } |
489 | return score_status; |
||
10 | reyssat | 490 | } |
491 | |||
7407 | bpr | 492 | /* Whether score registering is open */ |
10 | reyssat | 493 | void calc_getscorestatus(char *p) |
494 | { |
||
7407 | bpr | 495 | _scoreparm(p); |
496 | if(*score_class==0 || score_sheet==0 || *score_user==0) { |
||
497 | *p=0; return; |
||
498 | } |
||
499 | if(getscorestatus(score_class, score_sheet)) |
||
500 | ovlstrcpy(p,"yes"); |
||
501 | else ovlstrcpy(p,"no"); |
||
10 | reyssat | 502 | } |
503 | |||
13011 | bpr | 504 | /* whether there are too much tries for the exo return yes or no */ |
12213 | bpr | 505 | void calc_getscoremaxexotry(char *p) |
506 | { |
||
507 | _scoreparm(p); |
||
508 | if(*score_class==0 || *score_user==0 || score_sheet==0 || score_exo==0) return; |
||
509 | if(gettrycheck(score_class, score_user, score_sheet, score_exo)==1) |
||
510 | ovlstrcpy(p,"yes"); |
||
511 | else ovlstrcpy(p,"no"); |
||
512 | } |
||
513 | |||
3603 | reyssat | 514 | double exam_scoredata[MAX_EXOS]; |
10 | reyssat | 515 | |
7407 | bpr | 516 | /* get current exam score */ |
10 | reyssat | 517 | void exam_currscore(int esh) |
518 | { |
||
7407 | bpr | 519 | char *p, *bf, pb[MAX_FNAME+1]; |
520 | char *s, *p1, *p2, *e1, *e2; |
||
521 | int i; |
||
522 | for(i=0;i<MAX_EXOS;i++) exam_scoredata[i]=-1000; |
||
12814 | bpr | 523 | /* session_prefix is not yet defined here */ |
7407 | bpr | 524 | s=getvar("wims_session"); if(s==NULL || *s==0) return; |
525 | mystrncpy(pb,s,sizeof(pb)); |
||
526 | p=strchr(pb,'_'); if(p!=NULL) *p=0; |
||
527 | bf=readfile(mkfname(NULL,"%s/%s/examscore.%d",session_dir,pb,esh),NULL,WORKFILE_LIMIT); |
||
528 | if(bf==NULL) return; |
||
529 | for(p1=bf;*p1;p1=p2) { |
||
530 | p2=strchr(p1,'\n'); if(*p2) *p2++=0; |
||
531 | else p2=p1+strlen(p1); |
||
532 | p1=find_word_start(find_word_end(find_word_start(p1))); |
||
533 | e1=find_word_end(p1); if(*e1) *e1++=0; |
||
534 | e1=find_word_start(e1); e2=find_word_start(find_word_end(e1)); |
||
535 | *find_word_end(e1)=0; |
||
536 | i=atoi(p1); |
||
537 | if(i>=1 && i<=MAX_EXOS && |
||
538 | exam_scoredata[i-1]==-1000 && strcmp(e1,"score")==0) { |
||
539 | *find_word_end(e2)=0; |
||
540 | exam_scoredata[i-1]=atof(e2); |
||
10 | reyssat | 541 | } |
7407 | bpr | 542 | } |
543 | free(bf); |
||
10 | reyssat | 544 | } |
545 | |||
7407 | bpr | 546 | /* Gather exam score. */ |
10 | reyssat | 547 | void calc_examscore(char *p) |
548 | { |
||
7407 | bpr | 549 | char *p1; |
550 | int i; |
||
9692 | bpr | 551 | char *withoutip; |
7407 | bpr | 552 | |
553 | _scoreparm(p); *p=0; |
||
9692 | bpr | 554 | withoutip=getvar("wims_examscore_withoutip"); |
555 | |||
7407 | bpr | 556 | if(*score_class==0 || *score_user==0) return; |
557 | if(getscoreuser(score_class,score_user)<0) return; |
||
558 | p1=p; |
||
9692 | bpr | 559 | if(withoutip!=NULL && strcmp(withoutip,"yes")==0) { |
560 | for(i=0; i<examcnt && p1-p<MAX_LINELEN-32; i++) { |
||
561 | p1=moneyprint(p1,rscore[examstart+i].best); *p1++=' '; |
||
562 | } |
||
563 | } else { |
||
564 | for(i=0; i<examcnt && p1-p<MAX_LINELEN-32; i++) { |
||
565 | p1=moneyprint(p1,rscore[examstart+i].score); *p1++=' '; |
||
566 | } |
||
7407 | bpr | 567 | } |
568 | *p1++='\n'; |
||
569 | for(i=0; i<examcnt && p1-p<MAX_LINELEN-32; i++) { |
||
570 | p1=moneyprint(p1,rscore[examstart+i].require); *p1++=' '; |
||
571 | p1=moneyprint(p1,floor(rscore[examstart+i].mean/2)); *p1++=' '; |
||
572 | p1=moneyprint(p1,(int) rscore[examstart+i].mean%2); *p1++='\n'; |
||
573 | } |
||
574 | *p1=0; |
||
10 | reyssat | 575 | } |
576 | |||
7407 | bpr | 577 | /* check score dependency. |
8155 | bpr | 578 | * returns 1 if requirements are met. |
579 | */ |
||
10 | reyssat | 580 | int _depcheck(char *ds, struct scoreresult *rs, int ecnt) |
581 | { |
||
7407 | bpr | 582 | char *p1, *p2, *p3, *p4, *pp; |
583 | int perc, t, sum; |
||
584 | double tgot, ttot, tmean; |
||
585 | |||
586 | for(p1=ds; *p1; p1=p3) { |
||
587 | p2=strchr(p1,':'); if(p2==NULL) break; |
||
588 | *p2++=0; p2=find_word_start(p2); |
||
589 | for(p3=p2; myisdigit(*p3); p3++); |
||
590 | if(p3<=p2) break; |
||
591 | *p3++=0; perc=atoi(p2); |
||
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++) { |
661 | sh=(rscore[i].num>>8)+1; |
||
662 | if (she!=sh) continue; |
||
663 | ex=((rscore[i].num)&255)+1; |
||
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++) { |
||
688 | sh=(rscore[i].num>>8)+1; |
||
689 | if (she!=sh) continue; |
||
690 | ex=((rscore[i].num)&255)+1; |
||
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 | } |