diff --git a/admin/api/exercice.go b/admin/api/exercice.go index a1ab5153..d7c7ebd6 100644 --- a/admin/api/exercice.go +++ b/admin/api/exercice.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "strings" + "time" "srs.epita.fr/fic-server/admin/sync" "srs.epita.fr/fic-server/libfic" @@ -14,12 +15,17 @@ import ( func init() { router.GET("/api/exercices/", apiHandler(listExercices)) + router.GET("/api/resolutions.json", apiHandler(exportResolutionMovies)) router.GET("/api/exercices/:eid", apiHandler(exerciceHandler(showExercice))) router.PUT("/api/exercices/:eid", apiHandler(exerciceHandler(updateExercice))) router.PATCH("/api/exercices/:eid", apiHandler(exerciceHandler(partUpdateExercice))) router.DELETE("/api/exercices/:eid", apiHandler(exerciceHandler(deleteExercice))) + router.GET("/api/exercices/:eid/stats", apiHandler(exerciceHandler(getExerciceStats))) + router.GET("/api/exercices/:eid/history.json", apiHandler(exerciceHandler(getExerciceHistory))) + router.DELETE("/api/exercices/:eid/history.json", apiHandler(exerciceHandler(delExerciceHistory))) + router.GET("/api/exercices/:eid/files", apiHandler(exerciceHandler(listExerciceFiles))) router.POST("/api/exercices/:eid/files", apiHandler(exerciceHandler(createExerciceFile))) router.GET("/api/exercices/:eid/files/:fid", apiHandler(exerciceFileHandler(showExerciceFile))) @@ -85,6 +91,28 @@ func listExercices(_ httprouter.Params, body []byte) (interface{}, error) { return fic.GetExercices() } +// Generate the csv to export with: +// curl -s http://127.0.0.1:8081/api/resolutions.json | jq -r ".[] | [ .theme,.title, @uri \"https://fic.srs.epita.fr/resolution/\\(.videoURI)\" ] | join(\";\")" +func exportResolutionMovies(_ httprouter.Params, body []byte) (interface{}, error) { + if exercices, err := fic.GetExercices(); err != nil { + return nil, err + } else { + export := []map[string]string{} + for _, exercice := range exercices { + if theme, err := fic.GetTheme(exercice.IdTheme); err != nil { + return nil, err + } else { + export = append(export, map[string]string{ + "videoURI": exercice.VideoURI, + "theme": theme.Name, + "title": exercice.Title, + }) + } + } + return export, nil + } +} + func listExerciceFiles(exercice fic.Exercice, body []byte) (interface{}, error) { return exercice.GetFiles() } @@ -109,6 +137,35 @@ func showExercice(exercice fic.Exercice, body []byte) (interface{}, error) { return exercice, nil } +func getExerciceStats(exercice fic.Exercice, body []byte) (interface{}, error) { + team_tries, tries := exercice.TriesByTeam() + return map[string]interface{}{ + "solved": exercice.SolvedTeams(), + "total_tried": tries, + "team_tries": team_tries, + }, nil +} + +func getExerciceHistory(exercice fic.Exercice, body []byte) (interface{}, error) { + return exercice.GetHistory() +} + +type uploadedExerciceHistory struct { + IdTeam int64 `json:"team_id"` + Kind string + Time time.Time + Secondary *int64 +} + +func delExerciceHistory(exercice fic.Exercice, body []byte) (interface{}, error) { + var uh uploadedExerciceHistory + if err := json.Unmarshal(body, &uh); err != nil { + return nil, err + } + + return exercice.DelHistoryItem(uh.IdTeam, uh.Kind, uh.Time, uh.Secondary) +} + func deleteExercice(exercice fic.Exercice, _ []byte) (interface{}, error) { return exercice.Delete() } diff --git a/admin/api/team.go b/admin/api/team.go index dcffb055..8c32692d 100644 --- a/admin/api/team.go +++ b/admin/api/team.go @@ -238,10 +238,27 @@ func setTeamMember(team fic.Team, body []byte) (interface{}, error) { } type uploadedHistory struct { - Kind string - Time time.Time - Primary *int64 - Secondary *int64 + Kind string + Time time.Time + Primary *int64 + Secondary *int64 + Coefficient float32 +} + +func updateHistory(team *fic.Team, body []byte) (interface{}, error) { + var uh uploadedHistory + if err := json.Unmarshal(body, &uh); err != nil { + return nil, err + } + + var givenId int64 + if uh.Secondary != nil { + givenId = *uh.Secondary + } else if uh.Primary != nil { + givenId = *uh.Primary + } + + return team.UpdateHistoryCoeff(uh.Kind, uh.Time, givenId, uh.Coefficient) } func delHistory(team *fic.Team, body []byte) (interface{}, error) { diff --git a/admin/fill_exercices.sh b/admin/fill_exercices.sh deleted file mode 100755 index e2ce2141..00000000 --- a/admin/fill_exercices.sh +++ /dev/null @@ -1,262 +0,0 @@ -#!/bin/bash - -BASEURL="http://localhost:8081" -BASEURI="https://owncloud.srs.epita.fr/remote.php/webdav/FIC 2018" -BASEFILE="/mnt/fic/" -CLOUDPASS="$CLOUD_USER:$CLOUD_PASS" - -new_theme() { - NAME=`echo $1 | sed 's/"/\\\\"/g'` - AUTHORS=`echo $2 | sed 's/"/\\\\"/g'` - curl -f -s -d "{\"name\": \"$NAME\", \"authors\": \"$AUTHORS\"}" "${BASEURL}/api/themes" | - grep -Eo '"id":[0-9]+,' | grep -Eo "[0-9]+" -} - -new_exercice() { - THEME="$1" - TITLE=`echo "$2" | sed 's/"/\\\\"/g'` - STATEMENT=`echo "$3" | sed 's/"/\\\\"/g' | sed ':a;N;$!ba;s/\n/
/g'` - DEPEND="$4" - GAIN="$5" - VIDEO="$6" - - curl -f -s -d "{\"title\": \"$TITLE\", \"statement\": \"$STATEMENT\", \"depend\": $DEPEND, \"gain\": $GAIN, \"videoURI\": \"$VIDEO\"}" "${BASEURL}/api/themes/$THEME/exercices" | - grep -Eo '"id":[0-9]+,' | grep -Eo "[0-9]+" -} - -new_file() ( - THEME="$1" - EXERCICE="$2" - URI="$3" - DIGEST="$4" - ARGS="$5" - - FIRST= - PARTS=$(echo "$ARGS" | while read arg - do - [ -n "$arg" ] && { - [ -z "${FIRST}" ] || echo -n "," - echo "\"$arg\"" - } - FIRST=1 - done) - - [ -n "${DIGEST}" ] && DIGEST=", \"digest\": \"${DIGEST}\"" - - cat <&2 -{"path": "${BASEFILE}${URI}"${DIGEST}, "parts": [${PARTS}]} -EOF - -# curl -f -s -d "{\"URI\": \"${BASEFILE}${URI}\"}" "${BASEURL}/api/themes/$THEME/$EXERCICE/files" | - curl -f -s -d @- "${BASEURL}/api/themes/$THEME/exercices/$EXERCICE/files" </g'` - COST="$5" - URI="$6" - - [ -n "${CONTENT}" ] && CONTENT=", \"content\": \"${CONTENT}\"" - [ -n "${URI}" ] && URI=", \"path\": \"${BASEFILE}${URI}\"" - - curl -f -s -d "{\"title\": \"$TITLE\"$CONTENT$URI, \"cost\": $COST}" "${BASEURL}/api/themes/$THEME/exercices/$EXERCICE/hints" | - grep -Eo '"id":[0-9]+,' | grep -Eo "[0-9]+" -} - -new_key() { - THEME="$1" - EXERCICE="$2" - TYPE="$3" - KEY=`echo $4 | sed 's#\\\\#\\\\\\\\#g' | sed 's/"/\\\\"/g'` - - curl -f -s -d "{\"type\": \"$TYPE\", \"key\": \"$KEY\"}" "${BASEURL}/api/themes/$THEME/exercices/$EXERCICE/keys" | - grep -Eo '"id":[0-9]+,' | grep -Eo "[0-9]+" -} - -get_dir_from_cloud() { - curl -f -s -X PROPFIND -u "${CLOUDPASS}" "${BASEURI}$1" | xmllint --format - | grep 'd:href' | sed -E 's/^.*>(.*)<.*$/\1/' -} -get_dir() { - ls "${BASEFILE}$1" 2> /dev/null -} -#alias get_dir=get_dir_from_cloud - -get_file_from_cloud() { - curl -f -s -u "${CLOUDPASS}" "${BASEURI}$1" | tr -d '\r' -} -get_file() { - cat "${BASEFILE}$1" 2> /dev/null | tr -d '\r' - echo -} -#alias get_file=get_file_from_cloud - -unhtmlentities() { - cat | sed -E 's/%20/ /g' | sed -E "s/%27/'/g" | sed -E 's/%c3%a9/é/g' | sed -E 's/%c3%a8/è/g' -} - -# Theme -{ - if [ $# -ge 1 ]; then - echo $1 - else - get_dir "" - fi -} | while read f; do basename "$f"; done | while read THEME_URI -do - THM_BASEURI="/${THEME_URI}/" - THEME_NAME=$(echo "${THEME_URI#*-}" | unhtmlentities) - THEME_AUTHORS=$(get_file "${THM_BASEURI}/AUTHORS.txt" | sed '/^$/d;s/$/, /' | tr -d '\n' | sed 's/, $//') - THEME_ID=`new_theme "$THEME_NAME" "$THEME_AUTHORS"` - if [ -z "$THEME_ID" ]; then - echo -e "\e[31;01m!!! An error occured during theme add\e[00m" - continue - else - echo -e "\e[33m>>> New theme created:\e[00m $THEME_ID - $THEME_NAME" - fi - - LAST=null - EXO_NUM=0 - { - if [ $# -ge 2 ]; then - echo "$2" - else - get_dir "${THM_BASEURI}" - fi - } | while read f; do basename "$f"; done | while read EXO_URI - do - case ${EXO_URI} in - [0-9]-*) - ;; - *) - continue;; - esac - - #EXO_NUM=$((EXO_NUM + 1)) - EXO_NUM=${EXO_URI%-*} - EXO_NAME=$(echo "${EXO_URI#*-}" | unhtmlentities) - echo - echo -e "\e[36m--- Filling exercice ${EXO_NUM} in theme ${THEME_NAME}\e[00m" - - EXO_BASEURI="${EXO_URI}/" - - EXO_VIDEO=$(get_dir "${THM_BASEURI}${EXO_BASEURI}/resolution/" | grep -E "\.(mov|mkv|mp4|avi|flv|ogv|webm)$" | while read f; do basename "$f"; done | tail -1) - [ -n "$EXO_VIDEO" ] && EXO_VIDEO="/resolution${THM_BASEURI}${EXO_BASEURI}resolution/${EXO_VIDEO}" - - if [ "${LAST}" = "null" ]; then - echo ">>> Assuming this exercice has no dependency" - else - echo ">>> Assuming this exercice depends on the last entry (id=${LAST})" - fi - - EXO_GAIN=$((3 * (2 ** $EXO_NUM) - 1)) - HINT_COST=$(($EXO_GAIN / 4)) - echo ">>> Using default gain: ${EXO_GAIN} points" - - EXO_SCENARIO=$(get_file "${THM_BASEURI}${EXO_BASEURI}/scenario.txt") - - EXO_ID=`new_exercice "${THEME_ID}" "${EXO_NAME}" "${EXO_SCENARIO}" "${LAST}" "${EXO_GAIN}" "${EXO_VIDEO}"` - if [ -z "$EXO_ID" ]; then - echo -e "\e[31;01m!!! An error occured during exercice add.\e[00m" - continue - else - echo -e "\e[32m>>> New exercice created:\e[00m $EXO_ID - $EXO_NAME" - fi - - - # Keys - get_file "${THM_BASEURI}${EXO_BASEURI}/flags.txt" | while read KEYLINE - do - [ -z "${KEYLINE}" ] && continue - - KEY_NAME=$(echo "$KEYLINE" | cut -d$'\t' -f 1) - KEY_RAW=$(echo "$KEYLINE" | cut -d$'\t' -f 2-) - - if [ -z "${KEY_RAW}" ] || [ "${KEY_NAME}" = "${KEY_RAW}" ]; then - KEY_NAME=$(echo "$KEYLINE" | cut -d : -f 1) - KEY_RAW=$(echo "$KEYLINE" | cut -d : -f 2-) - fi - - if [ -z "${KEY_NAME}" ]; then - KEY_NAME="Flag" - fi - - KEY_ID=`new_key "${THEME_ID}" "${EXO_ID}" "${KEY_NAME}" "${KEY_RAW}"` - if [ -z "$KEY_ID" ]; then - echo -e "\e[31;01m!!! An error occured during key import!\e[00m (name=${KEYNAME};raw=${KEY_RAW})" - else - echo -e "\e[32m>>> New key added:\e[00m $KEY_ID - $KEY_NAME" - fi - done - - - # Hints - HINTS=$(get_dir "${THM_BASEURI}${EXO_BASEURI}/hints/" | sed -E 's#(.*)#hints/\1#') - [ -z "${HINTS}" ] && HINTS=$(get_dir "${THM_BASEURI}${EXO_BASEURI}/" | grep ^hint.) - [ -z "${HINTS}" ] && HINTS="hint.txt" - HINT_COUNT=1 - echo "${HINTS}" | while read HINT - do - EXO_HINT=$(get_file "${THM_BASEURI}${EXO_BASEURI}/${HINT}") - if [ -n "$EXO_HINT" ]; then - EXO_HINT_TYPE=$(echo "${EXO_HINT}" | file --mime-type -b -) - if echo "${EXO_HINT_TYPE}" | grep text/ && [ $(echo "${EXO_HINT}" | wc -l) -lt 25 ]; then - HINT_ID=`new_hint "${THEME_ID}" "${EXO_ID}" "Astuce #${HINT_COUNT}" "${EXO_HINT}" "${HINT_COST}"` - else - HINT_ID=`new_hint "${THEME_ID}" "${EXO_ID}" "Astuce #${HINT_COUNT}" "" "${HINT_COST}" "${THM_BASEURI}${EXO_BASEURI}/${HINT}"` - fi - - if [ -z "$HINT_ID" ]; then - echo -e "\e[31;01m!!! An error occured during hint import!\e[00m (title=Astuce #${HINT_COUNT};content::${EXO_HINT_TYPE};cost=${HINT_COST})" - else - echo -e "\e[32m>>> New hint added:\e[00m $HINT_ID - Astuce #${HINT_COUNT}" - fi - fi - HINT_COUNT=$(($HINT_COUNT + 1)) - done - - - # Files: splited - get_dir "${THM_BASEURI}${EXO_BASEURI}files/" | grep -v DIGESTS.txt | grep '[0-9][0-9]$' | sed -E 's/\.?([0-9][0-9])$//' | sort | uniq | while read f; do basename "$f"; done | while read FILE_URI - do - DIGEST=$(get_file "${THM_BASEURI}${EXO_BASEURI}files/DIGESTS.txt" | grep "${FILE_URI}\$" | awk '{ print $1; }') - - PARTS= - for part in $(get_dir "${THM_BASEURI}${EXO_BASEURI}files/" | grep "${FILE_URI}" | sort) - do - PARTS="${PARTS}${BASEFILE}${THM_BASEURI}${EXO_BASEURI}files/${part} -" - done - echo -e "\e[35mImport splited file ${THM_BASEURI}${EXO_BASEURI}files/${FILE_URI} from\e[00m `echo ${PARTS} | tr '\n' ' '`" - - FILE_ID=`new_file "${THEME_ID}" "${EXO_ID}" "${THM_BASEURI}${EXO_BASEURI}files/${FILE_URI}" "${DIGEST}" "${PARTS}"` - if [ -z "$FILE_ID" ]; then - echo -e "\e[31;01m!!! An error occured during file import! Please check path.\e[00m" - else - echo -e "\e[32m>>> New file added:\e[00m $FILE_ID - $FILE_URI" - fi - done - - # Files: entire - get_dir "${THM_BASEURI}${EXO_BASEURI}files/" | grep -v DIGESTS.txt | grep -v '[0-9][0-9]$' | while read f; do basename "$f"; done | while read FILE_URI - do - DIGEST=$(get_file "${THM_BASEURI}${EXO_BASEURI}files/DIGESTS.txt" | grep "${FILE_URI}\$" | awk '{ print $1; }') - - echo "Import file ${THM_BASEURI}${EXO_BASEURI}files/${FILE_URI}" - FILE_ID=`new_file "${THEME_ID}" "${EXO_ID}" "${THM_BASEURI}${EXO_BASEURI}files/${FILE_URI}" "${DIGEST}"` - if [ -z "$FILE_ID" ]; then - echo -e "\e[31;01m!!! An error occured during file import! Please check path.\e[00m" - else - echo -e "\e[32m>>> New file added:\e[00m $FILE_ID - $FILE_URI" - fi - done - - - LAST=$EXO_ID - done - echo -done diff --git a/admin/get_files.sh b/admin/get_files.sh deleted file mode 100755 index 68c032cb..00000000 --- a/admin/get_files.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -BASEURL="http://localhost:8081" -BASEURI="https://srs.epita.fr/owncloud/remote.php/webdav/FIC 2016" -CLOUDUSER='fic' -CLOUDPASS='f>t\nV33R|(+?$i*' - -if [ $# -gt 0 ] -then - WHERE=$1 -else - WHERE="files" -fi - -curl -q -f ${BASEURL}/api/themes/files-bindings | while read l -do - FROM=$(echo "$l" | cut -d ";" -f 1) - DEST=$(echo "$l" | cut -d ";" -f 2) - - mkdir -p $(dirname "${WHERE}${DEST}") - - wget -O "${WHERE}${DEST}" --user "${CLOUDUSER}" --password "${CLOUDPASS}" "${BASEURI}${FROM}" -done diff --git a/admin/index.go b/admin/index.go index 0461becf..595d0b2f 100644 --- a/admin/index.go +++ b/admin/index.go @@ -32,8 +32,8 @@ const indextpl = `