2017-12-09 00:21:58 +00:00
package sync
import (
"fmt"
"path"
"strings"
2017-12-17 15:10:59 +00:00
"unicode"
2017-12-09 00:21:58 +00:00
"srs.epita.fr/fic-server/libfic"
)
2017-12-17 15:10:59 +00:00
func isFullGraphic ( s string ) bool {
for _ , c := range s {
if ! unicode . IsGraphic ( c ) {
return false
}
}
return true
}
2017-12-09 00:21:58 +00:00
func SyncExerciceKeys ( i Importer , exercice fic . Exercice ) [ ] string {
var errs [ ] string
if _ , err := exercice . WipeKeys ( ) ; err != nil {
errs = append ( errs , err . Error ( ) )
} else if flags , err := getFileContent ( i , path . Join ( exercice . Path , "flags.txt" ) ) ; err != nil {
errs = append ( errs , fmt . Sprintf ( "%q: unable to read flags: %s" , path . Base ( exercice . Path ) , err ) )
} else {
for nline , flag := range strings . Split ( flags , "\n" ) {
flag_splt := strings . SplitN ( string ( flag ) , "\t" , 2 )
if len ( flag_splt ) > 2 {
errs = append ( errs , fmt . Sprintf ( "%q: error in flags file at line %d: invalid format" , path . Base ( exercice . Path ) , nline + 1 ) )
continue
}
if len ( flag_splt ) == 1 {
2017-12-17 15:10:59 +00:00
errs = append ( errs , fmt . Sprintf ( "%q: error in flags file at line %d: no separator found" , path . Base ( exercice . Path ) , nline + 1 ) )
continue
}
var label , rawkey string
if len ( flag_splt [ 0 ] ) == 0 {
label = "Flag"
2017-12-09 00:21:58 +00:00
} else {
label = flag_splt [ 0 ]
}
2017-12-17 15:10:59 +00:00
rawkey = flag_splt [ 1 ]
2017-12-09 00:21:58 +00:00
2017-12-17 15:10:59 +00:00
if ! isFullGraphic ( rawkey ) {
errs = append ( errs , fmt . Sprintf ( "%q: WARNING in flags file at line %d: non-printable characters in flag, is this really expected?" , path . Base ( exercice . Path ) , nline + 1 ) )
2017-12-09 00:21:58 +00:00
}
if _ , err := exercice . AddRawKey ( label , rawkey ) ; err != nil {
errs = append ( errs , fmt . Sprintf ( "%q: error in flags file at line %d: %s" , path . Base ( exercice . Path ) , nline + 1 , err ) )
continue
}
}
}
return errs
}
2017-12-16 02:39:57 +00:00
2018-01-08 00:34:22 +00:00
func SyncExerciceMCQ ( i Importer , exercice fic . Exercice ) ( errs [ ] string ) {
2017-12-16 02:39:57 +00:00
if _ , err := exercice . WipeMCQs ( ) ; err != nil {
errs = append ( errs , err . Error ( ) )
return errs
}
// Unique Choice Questions (checkbox)
if ucq , err := getFileContent ( i , path . Join ( exercice . Path , "flags-ucq.txt" ) ) ; err != nil {
2018-01-08 00:34:22 +00:00
if i . exists ( path . Join ( exercice . Path , "flags-ucq.txt" ) ) {
errs = append ( errs , fmt . Sprintf ( "%q: unable to read ucq: %s" , path . Base ( exercice . Path ) , err ) )
}
2017-12-17 15:28:31 +00:00
} else if flag , err := exercice . AddMCQ ( "" ) ; err != nil {
2017-12-16 02:39:57 +00:00
errs = append ( errs , fmt . Sprintf ( "%q: unable to add ucq: %s" , path . Base ( exercice . Path ) , err ) )
} else {
for nline , quest := range strings . Split ( ucq , "\n" ) {
if len ( quest ) == 0 {
continue
}
if len ( quest ) < 2 {
errs = append ( errs , fmt . Sprintf ( "%q: error in ucq file at line %d: missing response" , path . Base ( exercice . Path ) , nline + 1 ) )
continue
}
// Expect 0 or 1
if quest [ 0 ] != 48 && quest [ 0 ] != 49 {
errs = append ( errs , fmt . Sprintf ( "%q: error in ucq file at line %d: invalid format: first character has to be either 0 or 1" , path . Base ( exercice . Path ) , nline + 1 ) )
continue
}
if _ , err := flag . AddEntry ( quest [ 1 : ] , quest [ 0 ] == 49 ) ; err != nil {
errs = append ( errs , fmt . Sprintf ( "%q: error in ucq file at line %d: %s" , path . Base ( exercice . Path ) , nline + 1 , err ) )
}
}
}
// Multiple Choice Questions (radio)
if mcq , err := getFileContent ( i , path . Join ( exercice . Path , "flags-mcq.txt" ) ) ; err != nil {
2018-01-08 00:34:22 +00:00
if i . exists ( path . Join ( exercice . Path , "flags-mcq.txt" ) ) {
errs = append ( errs , fmt . Sprintf ( "%q: unable to read mcq: %s" , path . Base ( exercice . Path ) , err ) )
}
2017-12-16 02:39:57 +00:00
} else {
for nline , quest := range strings . Split ( mcq , "\n" ) {
quest_splt := strings . Split ( string ( quest ) , "\t" )
if len ( quest_splt ) < 2 {
errs = append ( errs , fmt . Sprintf ( "%q: error in mcq file at line %d: not enough responses" , path . Base ( exercice . Path ) , nline + 1 ) )
continue
}
2017-12-17 15:28:31 +00:00
if flag , err := exercice . AddMCQ ( quest_splt [ 0 ] ) ; err != nil {
2017-12-16 02:39:57 +00:00
errs = append ( errs , fmt . Sprintf ( "%q: error in mcq file at line %d: %s" , path . Base ( exercice . Path ) , nline + 1 , err ) )
continue
} else {
hasOne := false
for cid , choice := range quest_splt [ 1 : ] {
// Expect 0 or 1
if choice [ 0 ] != 48 && choice [ 0 ] != 49 {
errs = append ( errs , fmt . Sprintf ( "%q: error in mcq file at line %d,%d: invalid format: first character has to be either 0 or 1" , path . Base ( exercice . Path ) , nline + 1 , cid ) )
continue
}
2017-12-17 15:10:59 +00:00
if len ( quest ) < 2 {
errs = append ( errs , fmt . Sprintf ( "%q: error in mcq file at line %d: missing label" , path . Base ( exercice . Path ) , nline + 1 ) )
continue
}
2017-12-16 02:39:57 +00:00
if _ , err := flag . AddEntry ( choice [ 1 : ] , choice [ 0 ] == 49 ) ; err != nil {
errs = append ( errs , fmt . Sprintf ( "%q: error in mcq file at line %d,%d: %s" , path . Base ( exercice . Path ) , nline + 1 , cid , err ) )
continue
}
if choice [ 0 ] == 49 {
2017-12-17 15:28:31 +00:00
hasOne = true
2017-12-16 02:39:57 +00:00
}
}
if ! hasOne {
errs = append ( errs , fmt . Sprintf ( "%q: warning in mcq file at line %d: no valid answer defined, is this really expected?" , path . Base ( exercice . Path ) , nline + 1 ) )
}
}
}
}
return errs
}