Subversion Repositories wimsdev

Rev

Rev 18153 | 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
    if (sh >= MAX_SHEETS) break;
87
    while(osh<sh)
88
      {++osh; scoresum[osh]=shexocnt[osh]=0; sheetstart[osh]=i;}
89
    scoresum[sh]+=rscore[i].require*rscore[i].weight*rscore[i].active;
90
    shexocnt[sh]++;
7407 bpr 91
  }
15847 bpr 92
  totsheets=osh+1;
93
 
94
  examstart=i;  examcnt=scorecnt-examstart;
7407 bpr 95
  mystrncpy(rscore_class,classe,sizeof(rscore_class));
96
  mystrncpy(rscore_user,user,sizeof(rscore_user));
97
  return 0;
10 reyssat 98
}
7602 bpr 99
/* work : exo */
10 reyssat 100
char *scorepname[]={
12222 bpr 101
  "class","user","sheet","work","exam"
10 reyssat 102
};
103
#define scorepname_no (sizeof(scorepname)/sizeof(scorepname[0]))
104
char score_class[MAX_CLASSLEN+1];
18153 bpr 105
int score_sheet,score_exo,score_isexam,score_exam;
10 reyssat 106
char score_user[256];
107
 
7407 bpr 108
/* Uniformed treatment of score command parameters
109
 * format: class=? user=? sheet=? work=?
8155 bpr 110
 * all are optional.
111
 */
10 reyssat 112
void _scoreparm(char *p)
113
{
114
    int i;
115
    char *pn, *pe, *pd, *pf;
116
    char sav;
7407 bpr 117
 
18153 bpr 118
    score_sheet=score_exo=score_isexam=score_exam=score_ispublic=0; *score_class=0;
10 reyssat 119
    score_user[0]=0;
120
    for(i=0;i<scorepname_no;i++) {
16749 bpr 121
      pf=p;
122
      ahead:
123
      pn=strstr(pf,scorepname[i]); pf=pn+1;
124
      if(pn==NULL) continue;
125
      if(pn>p && !isspace(*(pn-1))) goto ahead;
126
      pe=find_word_start(pn+strlen(scorepname[i]));
127
      if(*pe!='=') goto ahead;
128
      pd=find_word_start(pe+1);
129
      pf=find_word_end(pd);
130
      if(pf<=pd) continue;
131
      sav=*pf; *pf=0;
132
      switch(i) {
133
        case 0: /* class */
134
          mystrncpy(score_class,pd,sizeof(score_class)); break;
135
        case 1: /* user */
136
          mystrncpy(score_user,pd,sizeof(score_user)); break;
137
        case 2: { /* sheet */
7149 bpr 138
          if(*pd=='P') {pd++; score_ispublic=1;}
139
          score_sheet=atoi(pd);
140
          break;
16749 bpr 141
        }
142
        case 3: /* work=exo */
143
          score_exo=atoi(pd); break;
144
        case 4: /* exam */
18153 bpr 145
          score_isexam=1;score_exam=atoi(pd); break;
7149 bpr 146
     }
147
     *pf=sav; ovlstrcpy(pn, pf);
10 reyssat 148
    }
149
    *p=0;
16749 bpr 150
    /* the commands are OK from a non trusted module if the user and the
151
    class are not precised, so it can be only the user in his class */
10 reyssat 152
    if((*score_class!=0 || score_user[0]!=0) && !trusted_module()) {
16749 bpr 153
      module_error("not_trusted"); return;
10 reyssat 154
    }
155
    if(*score_class==0) {
16749 bpr 156
      char *classe;
157
      classe=getvar("wims_class");
158
      if(classe==NULL || *classe==0) return;
159
      else mystrncpy(score_class,classe,sizeof(score_class));
10 reyssat 160
    }
161
    if(score_user[0]==0) {
7149 bpr 162
     char *user;
163
     user=getvar("wims_user");
164
     if(user!=NULL) mystrncpy(score_user,user,sizeof(score_user));
10 reyssat 165
    }
166
}
167
 
7407 bpr 168
/* gather score: relatif to some of the
169
 *  user class work sheet exam
8155 bpr 170
 *  dtype can be require weight score mean remain best last level try
7407 bpr 171
 */
172
 
10 reyssat 173
void _getscore(char *p,int dtype)
174
{
12222 bpr 175
  int i,sh,ex,osh;
176
  float d;
12273 bpr 177
  char dc[SEEDSIZE];
178
  char ds[SEEDSCORES];
12222 bpr 179
  char *p1;
10 reyssat 180
 
12222 bpr 181
  _scoreparm(p);
182
  if(*score_class==0 || *score_user==0) return;
183
  if(getscoreuser(score_class,score_user)<0) return;
184
  for(i=osh=0,p1=p;i<scorecnt && p1-p<MAX_LINELEN-32;i++) {
15847 bpr 185
    sh=rscore[i].sh+1; if(sh<1 || sh>MAX_SHEETS) break;
12222 bpr 186
    if(score_sheet!=0) {
187
      if(sh<score_sheet) continue;
188
      if(sh>score_sheet || sh>MAX_SHEETS) break;
189
    }
15847 bpr 190
    ex=rscore[i].exo+1;
12222 bpr 191
    if(score_exo!=0 && ex!=score_exo) continue;
192
    if(osh!=0 && sh!=osh) *p1++='\n';
193
    switch(dtype) {
194
      case sr_require: {d=rscore[i].require; break;}
195
      case sr_weight: {d=rscore[i].weight; break;}
196
      case sr_score: {d=rscore[i].score; break;}
197
      case sr_mean: {d=rscore[i].mean; break;}
198
      case sr_remain: {d=rscore[i].require-rscore[i].score; break;}
199
      case sr_last: {d=rscore[i].last; break;}
200
      case sr_try: {d=rscore[i].try; break;}
12230 bpr 201
      case sr_new: {d=rscore[i].new; break;}
12222 bpr 202
      case sr_best: {d=rscore[i].best; break;}
12273 bpr 203
      case sr_level: {d=rscore[i].level; break;}
204
      case sr_seedscorelast: {d=rscore[i].seedscorelast; break;}
12295 bpr 205
      case sr_seedlastcnt: {d=rscore[i].seedlastcnt; break;}
12273 bpr 206
      case sr_seedlast: { mystrncpy(dc,rscore[i].seedlast,SEEDSIZE);
207
        break;
208
      }
209
      case sr_seedscores: {
210
        mystrncpy(ds,rscore[i].seedscores,SEEDSCORES); break;
211
      }
12222 bpr 212
      default: {d=0; break;}
213
    }
12273 bpr 214
    switch(dtype) {
215
      case sr_seedlast:
216
        { snprintf(p1,SEEDSIZE, "%s", dc); p1+=strlen(p1); break; }
217
       case sr_seedscores:
218
        { snprintf(p1,SEEDSCORES, "%s", ds); p1+=strlen(p1); break; }
219
      default:
220
        { p1=moneyprint(p1,d); }
221
    }
222
    *p1++=' ';
12222 bpr 223
    osh=sh;
224
  }
225
  *p1++='\n'; *p1=0;
10 reyssat 226
}
227
 
7407 bpr 228
/* gather user score. */
10 reyssat 229
void calc_getscore(char *p)
230
{
7407 bpr 231
  _getscore(p,sr_score);
10 reyssat 232
}
233
 
7407 bpr 234
/* gather user score average. */
10 reyssat 235
void calc_getscoremean(char *p)
236
{
7407 bpr 237
  _getscore(p,sr_mean);
10 reyssat 238
}
239
 
7407 bpr 240
/* gather remaining of score to get for user. */
10 reyssat 241
void calc_getscoreremain(char *p)
242
{
7407 bpr 243
  _getscore(p,sr_remain);
10 reyssat 244
}
245
 
7407 bpr 246
/* Require score table. */
10 reyssat 247
void calc_getscorerequire(char *p)
248
{
7407 bpr 249
  _getscore(p,sr_require);
10 reyssat 250
}
251
 
7407 bpr 252
/* Score weight table. */
10 reyssat 253
void calc_getscoreweight(char *p)
254
{
7407 bpr 255
  _getscore(p,sr_weight);
10 reyssat 256
}
14126 obado 257
/* user last score */
7602 bpr 258
void calc_getscorelast(char *p)
259
{
260
  _getscore(p,sr_last);
261
}
12196 bpr 262
/* gather user score try numbers with score activated. */
7602 bpr 263
void calc_getscoretry(char *p)
264
{
265
  _getscore(p,sr_try);
266
}
12220 bpr 267
/* gather all user try numbers (terminated or not, but with notation activated)*/
12197 bpr 268
void calc_getscorealltries(char *p)
12196 bpr 269
{
12230 bpr 270
  _getscore(p,sr_new);
12196 bpr 271
}
7602 bpr 272
 
7657 bpr 273
/* if the required points are 10* N, gather N user best scores */
7638 bpr 274
void calc_getscorebest(char *p)
275
{
276
  _getscore(p,sr_best);
277
}
278
 
7657 bpr 279
/* gather user score average. */
280
void calc_getscorelevel(char *p)
281
{
282
  _getscore(p,sr_level);
283
}
284
 
7638 bpr 285
/* percentage of work done for each sheet:
7657 bpr 286
 * score mean best level
287
 * as follows
14126 obado 288
 * score=100*cumulative_points/required_points (< 100)
7665 bpr 289
 * mean=quality (<10)
290
 * best=10*(required/10 best_scores)/required_points (< 100)
14134 obado 291
 * level=minimum of the required/10 best_scores (< 100)
7638 bpr 292
 */
7657 bpr 293
 
294
 void calc_getscorepercent(char *p)
10 reyssat 295
{
7407 bpr 296
  int i,j,jend;
7657 bpr 297
  double tot, mean, totb, totl, totw, d;
7407 bpr 298
  char *p1;
10 reyssat 299
 
7407 bpr 300
  _scoreparm(p);
301
  if(*score_class==0 || *score_user==0) return;
302
  if(getscoreuser(score_class,score_user)<0) return;
303
  for(p1=p,i=0;i<totsheets && p1-p<MAX_LINELEN-32;i++) {
304
    if(scoresum[i]==0) {
7657 bpr 305
      ovlstrcpy(p1,"0 0 0 0\n"); p1+=strlen(p1); continue;
10 reyssat 306
    }
7407 bpr 307
    if(score_sheet!=0 && i!=score_sheet-1) continue;
308
    if(scoresum[i]<=0) *p1++='\n';
7657 bpr 309
    tot=mean=totb=totl=totw=0; jend=sheetstart[i]+shexocnt[i];
7407 bpr 310
    for(j=sheetstart[i];j<jend;j++) {
12495 bpr 311
      /* if mean<1 then ignore score.
312
      * if mean<2 then half score.
313
      */
7407 bpr 314
      if(rscore[j].mean>=1) {
7646 bpr 315
        double dt=rscore[j].score;
316
        float db=rscore[j].best;
7657 bpr 317
        float dl=rscore[j].level;
318
        if(rscore[j].mean<2) {dt=dt/2; db=db/2; dl=dl/2;}
15847 bpr 319
        d=dt*rscore[j].weight*rscore[j].active;
320
        /* quality; barycenter with coefficients d */
7646 bpr 321
        mean+=rscore[j].mean*d;
12495 bpr 322
        /* cumulative score */
7646 bpr 323
        tot+=d;
12495 bpr 324
        /* best */
15847 bpr 325
        totb+=db*rscore[j].weight*rscore[j].active;
12495 bpr 326
        /* level */
15847 bpr 327
        totl+=dl*rscore[j].weight*rscore[j].active;
328
        totw+=rscore[j].weight*rscore[j].active;
7407 bpr 329
      }
330
    }
7638 bpr 331
    if(tot>0) {d=mean/tot;} else d=0;
12495 bpr 332
    /* cumulative score */
7407 bpr 333
    p1=moneyprint(p1,rint(100*tot/scoresum[i])); *p1++=' ';
12495 bpr 334
    /* quality */
7638 bpr 335
    p1=moneyprint(p1,d); *p1++=' ';
12495 bpr 336
    /* best */
7657 bpr 337
    p1=moneyprint(p1,rint(100*totb/scoresum[i])); *p1++=' ';
12495 bpr 338
    /* level */
7657 bpr 339
    p1=moneyprint(p1,rint(10*totl/totw));
340
 
341
   *p1++='\n';
7407 bpr 342
  }
343
  *p1=0;
10 reyssat 344
}
12273 bpr 345
/* [seed1,score1;seed2,score2;...] at most MAX_SCORESEED */
346
void calc_getseedscores(char *p)
347
{
348
  _getscore(p,sr_seedscores);
349
}
350
/* last seed (0 if there is no seed)*/
351
void calc_getseedlast(char *p)
352
{
353
  _getscore(p,sr_seedlast);
354
}
355
/* last score (-1 if does not exist) */
356
void calc_getseedscorelast(char *p)
357
{
358
  _getscore(p,sr_seedscorelast);
359
}
10 reyssat 360
 
12295 bpr 361
/* number of occurences of the last seed */
362
void calc_getseedlastcnt(char *p)
363
{
364
  _getscore(p,sr_seedlastcnt);
365
}
366
 
7407 bpr 367
/* Returns the status of a sheet, or -1 if error */
10 reyssat 368
int getsheetstatus(char *classe, int sheet)
369
{
7407 bpr 370
  char *p, *st, buf[MAX_LINELEN+1], namebuf[MAX_FNAME+1];
18087 bpr 371
  int i,j,res,lnb;
18414 bpr 372
  char *classp, *classp2, *scp;
18087 bpr 373
  char *p1,buf1[MAX_LINELEN],buf2[MAX_LINELEN];
374
  char buf3[MAX_LINELEN],buf4[MAX_LINELEN];
375
  if(isexam || score_isexam) {st="exam"; lnb=8;} else {st="sheet";lnb=9;};
7407 bpr 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
  }
18081 bpr 383
  res=i;
384
  if (res == 0 || res > 2)
385
    goto ret;
386
  if (strcmp(score_user,"supervisor")==0 || score_user[0]==0)
387
    goto ret;
18087 bpr 388
  fnd_line(buf,lnb,buf1);
389
  rows2lines(buf1);
18414 bpr 390
  classp=getvar("wims_class"); scp=getvar("wims_superclass");
391
  if(scp!=NULL && *scp!=0) classp2=scp; else classp2=classp;
392
  mkfname(namebuf,"%s/%s/.users/%s",class_base,classp2,score_user);
18081 bpr 393
  for(i=1;;++i){
18087 bpr 394
    fnd_line(buf1,i,buf);
18081 bpr 395
    if(*buf==0) break;
396
    for (j=1;;++j){
18087 bpr 397
            fnd_item(buf,j,buf2);
398
            if (buf2[0]==0) {res = 3; goto ret;}
399
            p1=strchr(buf2,'=');
18081 bpr 400
            if(p1==NULL) break;
401
            *p1=0;
18087 bpr 402
            snprintf(buf3,sizeof(buf3),"%s_%s","user_techvar",buf2);
403
            getdef(namebuf,buf3,buf4);
404
            if(strcmp(buf4,p1+1)) break;
18081 bpr 405
          }
406
  }
407
  ret:
408
  return res;
10 reyssat 409
}
410
 
13011 bpr 411
/* return 1 if a word of bf2 is a substring of host
412
  and if time restrictions are verified for wims_user
8155 bpr 413
 * Content of bf2 is destroyed.
414
 */
10303 guerimand 415
int _subword(char bf2[],char *ftbuf)
10 reyssat 416
{
7407 bpr 417
  char *p1, *p2;
418
  for(p1=strchr(bf2,'\\'); p1!=NULL; p1=strchr(p1+1,'\\')) {
419
    char buf[MAX_LINELEN+1], buf2[MAX_LINELEN+1], fbuf[MAX_FNAME+1];
420
    char *classp, *classp2, *userp, *scp;
421
    classp=getvar("wims_class"); userp=getvar("wims_user");
422
    if(classp==NULL || userp==NULL || *classp==0 || *userp==0) break;
423
    scp=getvar("wims_superclass");
424
    if(scp!=NULL && *scp!=0) classp2=scp; else classp2=classp;
425
    if(p1>bf2 && !isspace(*(p1-1))) continue;
426
    if(!isalnum(*(p1+1))) continue;
427
    p2=find_word_end(p1); if(p2>=p1+MAX_NAMELEN) continue;
428
    memmove(buf2, p1+1, p2-p1-1); buf2[p2-p1-1]=0;
18081 bpr 429
    /* get value of technical variable for user */
10303 guerimand 430
    snprintf(buf,sizeof(buf),"user_techvar_%s",buf2);
7407 bpr 431
    if(strcmp(userp,"supervisor")==0)
432
      mkfname(fbuf,"%s/%s/supervisor",class_base,classp);
433
    else
434
      mkfname(fbuf,"%s/%s/.users/%s",class_base,classp2,userp);
10303 guerimand 435
    getdef(fbuf,buf,buf2);
18081 bpr 436
    /* end value for the user */
10365 bpr 437
    if(buf2[0]==0) ovlstrcpy(buf2,"EMPTY"); /* in case of no value defined for the user*/
10303 guerimand 438
    /* get time restriction for this value */
439
    snprintf(buf,sizeof(buf),"techvar_%s",buf2);
13011 bpr 440
    /* mkfname(fbuf,"%s/%s/.E%s",class_base,classp,sheet);
441
     * read time restriction corresponding to the value of
442
     * technical variable in the file of the sheet or exam
443
    */
10379 bpr 444
    getdef(ftbuf,buf,buf2);
18081 bpr 445
    /* value for techvar */
10303 guerimand 446
    if(buf2[0]==0) ovlstrcpy(buf2,"none");
447
    /*string_modify(bf2,p1,p2,buf2);*/
448
    bf2=buf2;
7407 bpr 449
    p1+=strlen(buf2);
450
  }
451
  if((isexam || score_isexam) && bf2[0]=='#') return 1;
452
  if(wordchr(bf2,"none")!=NULL) return 0;
453
  if(wordchr(bf2,"all")!=NULL) return 1;
454
  p1=find_word_start(bf2); if(*p1==0) return 1;
13011 bpr 455
  /* check host and time */
7407 bpr 456
  return checkhostt(p1);
10 reyssat 457
}
458
 
13011 bpr 459
/* Returns 1 if score registration is open for the user
460
 * in variable wims_user, 0 otherwise.
461
 */
10 reyssat 462
int _getscorestatus(char *classe, int sheet)
463
{
7407 bpr 464
  char nbuf[MAX_LINELEN+1], gbuf[MAX_LINELEN+1];
10303 guerimand 465
  char ftbuf[MAX_FNAME+1]="";
7407 bpr 466
  char *es;
10 reyssat 467
 
7407 bpr 468
  if(classe==NULL || *classe==0 || sheet<=0) return 1;
469
  if(getsheetstatus(classe,sheet)!=1) return 0;
470
  if(*remote_addr==0) return 0;
471
  if(isexam || score_isexam) {     /* exam simulation */
472
    accessfile(nbuf,"r","%s/%s/.E%d",class_base,classe,sheet);
473
    if(nbuf[0]=='#') return 1;
474
  }
12814 bpr 475
  /* Global restriction data */
7407 bpr 476
  accessfile(nbuf,"r","%s/%s/.security",class_base,classe);
477
  if(nbuf[0]) {
478
    _getdef(nbuf,"allow",gbuf);
10303 guerimand 479
    if(*find_word_start(gbuf)!=0 && _subword(gbuf,ftbuf)==0)
7407 bpr 480
      return 0;
481
    _getdef(nbuf,"except",gbuf);
10303 guerimand 482
    if(*find_word_start(gbuf)!=0 && _subword(gbuf,ftbuf)==1)
7407 bpr 483
      return 0;
484
  }
13011 bpr 485
  /* Sheet restriction data; take in account the technical variables */
7407 bpr 486
  if(isexam || score_isexam) es="E"; else es="";
487
  accessfile(nbuf,"r","%s/%s/.%s%d",class_base,classe,es,sheet);
488
  if(*find_word_start(nbuf)==0) return 1;
12814 bpr 489
  /* preparing score restriction file name :*/
10303 guerimand 490
  mkfname(ftbuf,"%s/%s/.%s%d",class_base,classe,es,sheet);
491
  return _subword(nbuf,ftbuf);
10 reyssat 492
}
493
 
13011 bpr 494
/* Returns 1 if score registration is open for wims_user, 0 otherwise.*/
10 reyssat 495
int getscorestatus(char *classe, int sheet)
496
{
7407 bpr 497
  if(score_status<0 || score_statussheet!=sheet
498
     || score_statusisexam!=isexam) {
499
    score_statussheet=sheet; score_statusisexam=isexam;
500
    score_status=_getscorestatus(classe,sheet); score_isexam=0;
17457 guerimand 501
    if(score_status!=0 && (cmd_type==cmd_new || cmd_type==cmd_renew
7646 bpr 502
               || isexam)) {
7407 bpr 503
      char *p;
504
      p=getvar("wims_scorereg");
505
      if(p==NULL || strcmp(p,"suspend")!=0)
7646 bpr 506
         setvar("wims_scoring","pending");
7407 bpr 507
      else setvar("wims_scoring","");
10 reyssat 508
    }
7407 bpr 509
  }
510
  if(isexam && score_status==0) {
511
    char *p;
13557 obado 512
    p=getvar("wims_user");
513
    if(p==NULL || strcmp(p,"supervisor")!=0)
514
      user_error("exam_closed");
7407 bpr 515
  }
516
  return score_status;
10 reyssat 517
}
518
 
7407 bpr 519
/* Whether score registering is open */
10 reyssat 520
void calc_getscorestatus(char *p)
521
{
7407 bpr 522
  _scoreparm(p);
523
  if(*score_class==0 || score_sheet==0 || *score_user==0) {
524
    *p=0; return;
525
  }
526
  if(getscorestatus(score_class, score_sheet))
527
    ovlstrcpy(p,"yes");
528
  else ovlstrcpy(p,"no");
10 reyssat 529
}
530
 
18056 bpr 531
/* get status of a sheet in a class: can be 0, 1, 2 or 3
18091 bpr 532
  (in preparation, active, expired or hidden) */
18056 bpr 533
void calc_getsheetstatus(char *p)
534
{
535
  _scoreparm(p);
18087 bpr 536
  if(*score_class==0 || (score_sheet==0 && score_isexam==0)) {
18056 bpr 537
    *p=0; return;
538
  }
18153 bpr 539
  snprintf(p,20,"%d",getsheetstatus(score_class, score_sheet?score_sheet:score_exam));
18056 bpr 540
}
541
 
13011 bpr 542
/* whether there are too much tries for the exo return yes or no */
12213 bpr 543
void calc_getscoremaxexotry(char *p)
544
{
545
  _scoreparm(p);
546
  if(*score_class==0 || *score_user==0 || score_sheet==0 || score_exo==0) return;
547
  if(gettrycheck(score_class, score_user, score_sheet, score_exo)==1)
548
    ovlstrcpy(p,"yes");
549
  else ovlstrcpy(p,"no");
550
}
551
 
16696 bpr 552
double exam_scoredata[MAX_EXAMS];
10 reyssat 553
 
7407 bpr 554
/* get current exam score */
10 reyssat 555
void exam_currscore(int esh)
556
{
7407 bpr 557
  char *p, *bf, pb[MAX_FNAME+1];
558
  char *s, *p1, *p2, *e1, *e2;
559
  int i;
16696 bpr 560
  for(i=0;i<MAX_EXAMS;i++) exam_scoredata[i]=-1000;
12814 bpr 561
  /* session_prefix is not yet defined here */
7407 bpr 562
  s=getvar("wims_session"); if(s==NULL || *s==0) return;
563
  mystrncpy(pb,s,sizeof(pb));
564
  p=strchr(pb,'_'); if(p!=NULL) *p=0;
565
  bf=readfile(mkfname(NULL,"%s/%s/examscore.%d",session_dir,pb,esh),NULL,WORKFILE_LIMIT);
566
  if(bf==NULL) return;
567
  for(p1=bf;*p1;p1=p2) {
568
    p2=strchr(p1,'\n'); if(*p2) *p2++=0;
569
    else p2=p1+strlen(p1);
570
    p1=find_word_start(find_word_end(find_word_start(p1)));
571
    e1=find_word_end(p1); if(*e1) *e1++=0;
572
    e1=find_word_start(e1); e2=find_word_start(find_word_end(e1));
573
    *find_word_end(e1)=0;
574
    i=atoi(p1);
16696 bpr 575
    if(i>=1 && i<=MAX_EXAMS &&
7407 bpr 576
       exam_scoredata[i-1]==-1000 && strcmp(e1,"score")==0) {
577
      *find_word_end(e2)=0;
578
      exam_scoredata[i-1]=atof(e2);
10 reyssat 579
    }
7407 bpr 580
  }
581
  free(bf);
10 reyssat 582
}
583
 
7407 bpr 584
/* Gather exam score. */
10 reyssat 585
void calc_examscore(char *p)
586
{
7407 bpr 587
  char *p1;
588
  int i;
9692 bpr 589
  char *withoutip;
7407 bpr 590
 
591
  _scoreparm(p); *p=0;
9692 bpr 592
  withoutip=getvar("wims_examscore_withoutip");
593
 
7407 bpr 594
  if(*score_class==0 || *score_user==0) return;
595
  if(getscoreuser(score_class,score_user)<0) return;
596
  p1=p;
9692 bpr 597
  if(withoutip!=NULL && strcmp(withoutip,"yes")==0) {
598
    for(i=0; i<examcnt && p1-p<MAX_LINELEN-32; i++) {
599
    p1=moneyprint(p1,rscore[examstart+i].best); *p1++=' ';
600
    }
601
  } else {
602
    for(i=0; i<examcnt && p1-p<MAX_LINELEN-32; i++) {
603
      p1=moneyprint(p1,rscore[examstart+i].score); *p1++=' ';
604
    }
7407 bpr 605
  }
606
  *p1++='\n';
607
  for(i=0; i<examcnt && p1-p<MAX_LINELEN-32; i++) {
608
    p1=moneyprint(p1,rscore[examstart+i].require); *p1++=' ';
609
    p1=moneyprint(p1,floor(rscore[examstart+i].mean/2)); *p1++=' ';
610
    p1=moneyprint(p1,(int) rscore[examstart+i].mean%2); *p1++='\n';
611
  }
612
  *p1=0;
10 reyssat 613
}
614
 
7407 bpr 615
/* check score dependency.
8155 bpr 616
 * returns 1 if requirements are met.
617
 */
10 reyssat 618
int _depcheck(char *ds, struct scoreresult *rs, int ecnt)
619
{
7407 bpr 620
  char *p1, *p2, *p3, *p4, *pp;
621
  int perc, t, sum;
622
  double tgot, ttot, tmean;
623
 
624
  for(p1=ds; *p1; p1=p3) {
625
    p2=strchr(p1,':'); if(p2==NULL) break;
626
    *p2++=0; p2=find_word_start(p2);
627
    for(p3=p2; myisdigit(*p3); p3++);
628
    if(p3<=p2) break;
15707 bpr 629
    if(*p3) *p3++=0;
630
    perc=atoi(p2);
7407 bpr 631
    if(perc<=0 || perc>100) break;
632
    for(pp=p1; *pp; pp++) if(!myisdigit(*pp)) *pp=' ';
633
    tgot=ttot=tmean=0; sum=0;
634
    for(pp=find_word_start(p1); *pp; pp=find_word_start(p4)) {
635
      p4=find_word_end(pp); if(*p4) *p4++=0;
636
      t=atoi(pp); if(t<=0 || t>ecnt) goto lend;
637
      t--;
638
      ttot+=rs[t].require; tgot+=rs[t].score; tmean+=rs[t].mean;
639
      sum++;
10 reyssat 640
    }
7407 bpr 641
    if(ttot<10) continue;
642
    if(tgot/ttot*sqrt(tmean/(sum*10))*100<perc) {
643
      for(pp=p1;pp<p2-1;pp++) if(!*pp) *pp=',';
644
      *pp=0; setvar("dep_list",p1);
645
      return 0;
646
    }
647
  lend: ;
648
  }
649
  return 1;
10 reyssat 650
}
651
 
652
int depcheck(char *sh, int exo, char *deps)
653
{
7407 bpr 654
  char buf[MAX_LINELEN+1];
655
  char *s, sbuf[64];
656
  int i, is;
657
 
658
  s=getvar("wims_session");
659
  if(s==NULL || *s==0 || strstr(s,"robot")!=NULL) return 0;
660
  mystrncpy(sbuf,s,sizeof(sbuf));
661
  s=strchr(sbuf,'_'); if(s) *s=0;
662
  accessfile(buf,"r","../sessions/%s/exodep.%s",sbuf,sh);
663
  if(buf[0]==0) {     /* no dep file found */
664
    is=atoi(sh); if(is<=0 || is>totsheets) return 0;
665
    s=getvar("wims_class"); if(s==NULL || *s==0) return 0;
666
    getscoreuser(s,"");
667
    return _depcheck(deps,rscore+sheetstart[is-1],shexocnt[is-1]);
668
  }
669
  for(i=1,s=strchr(buf,':'); s && i<exo; i++, s=strchr(s+1,':'));
670
  if(s==NULL) return 0;     /* bad file or exo number */
671
  if(myisdigit(*++s)) return 0; else return 1;
10 reyssat 672
}
673
 
674
int exam_depcheck(char *deps, int exam)
675
{
16696 bpr 676
  static struct scoreresult esc[MAX_EXAMS];
7407 bpr 677
  int i;
678
  exam_currscore(exam);
16696 bpr 679
  for(i=0;i<MAX_EXAMS;i++) {
7407 bpr 680
    esc[i].require=esc[i].mean=10;
681
    if(exam_scoredata[i]==-1000) esc[i].score=0;
682
    else esc[i].score=exam_scoredata[i];
683
  }
16696 bpr 684
  return _depcheck(deps,esc,MAX_EXAMS);
10 reyssat 685
}
12213 bpr 686
 
12276 bpr 687
/* public sheet gives she=0 */
12495 bpr 688
/* return 1 if score is no more taken in account because of exotrymax */
12213 bpr 689
int gettrycheck(char *classe, char *user, int she, int exo) {
690
  char *s;
691
  int sh, ex, i;
13232 bpr 692
  if(classe==NULL || *classe==0 || user==NULL || *user==0) return 0;
12276 bpr 693
  if (she<=0) return 0;
13232 bpr 694
    if(strcmp(user,"supervisor")==0) return 0;
12213 bpr 695
  s=getvar("exotrymax");
12527 bpr 696
  if(s==NULL || *s==0) return 0;
12213 bpr 697
  getscoreuser(classe,user);
12527 bpr 698
  char *p=getvar("wims_scorereg");
12213 bpr 699
  for(i=0;i<scorecnt;i++) {
15847 bpr 700
    sh=rscore[i].sh+1;
12213 bpr 701
    if (she!=sh) continue;
15847 bpr 702
    ex=rscore[i].exo+1;
12213 bpr 703
    if(exo!=ex) continue;
12381 bpr 704
    if(cmd_type==cmd_new || cmd_type==cmd_renew)
12527 bpr 705
      if(rscore[i].new >= atoi(s)) {
706
        if(strcmp(p,"suspend")!=0) setvar("wims_scorereg","exotrymax");
707
        return 1;
708
    }
709
    if(rscore[i].new > atoi(s)){
710
      if(strcmp(p,"suspend")!=0) setvar("wims_scorereg","exotrymax");
13015 bpr 711
      return 1;
12527 bpr 712
    }
12508 bpr 713
  }
12213 bpr 714
  return 0;
715
}
12273 bpr 716
 
717
/* return seed if the seed should be kept and NULL if not */
12369 bpr 718
char *getseedscore(char *classe, char *user, int she, int exo) {
12273 bpr 719
  char *s;
720
  int sh, ex, i;
12276 bpr 721
  if (she<=0) return NULL;
12273 bpr 722
  if(strcmp(user,"supervisor")==0) return NULL;
723
  s=getvar("seedrepeat");
12990 bpr 724
  if(s==NULL || *s==0 || atoi(s)<=0) return NULL;
12273 bpr 725
  getscoreuser(classe,user);
726
  for(i=0;i<scorecnt;i++) {
15847 bpr 727
    sh=rscore[i].sh+1;
12273 bpr 728
    if (she!=sh) continue;
15847 bpr 729
    ex=rscore[i].exo+1;
12273 bpr 730
    if(exo!=ex) continue;
12432 bpr 731
    if(atoi(rscore[i].seedlast)==0) {
732
      char *seed=getvar("wims_seed");
733
      return seed;
734
    }
12390 bpr 735
    if(rscore[i].seedlastcnt > MAX_SEEDSCORE) return NULL;
12445 bpr 736
    if(atoi(s)>0 && rscore[i].seedlastcnt >= atoi(s) && cmd_type!=cmd_next) return NULL;
12432 bpr 737
    if(rscore[i].seedscorelast < 10) return rscore[i].seedlast;
12273 bpr 738
  };
739
  return NULL;
740
}