admin/sync: handle hint files download
This commit is contained in:
parent
6cc40be36a
commit
11d0fe8d1f
@ -1,31 +1,68 @@
|
|||||||
package sync
|
package sync
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"srs.epita.fr/fic-server/libfic"
|
"srs.epita.fr/fic-server/libfic"
|
||||||
|
|
||||||
|
"github.com/dchest/blake2b"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SyncExerciceHints(i Importer, exercice fic.Exercice) []string {
|
func SyncExerciceHints(i Importer, exercice fic.Exercice) (errs []string) {
|
||||||
var errs []string
|
|
||||||
|
|
||||||
if _, err := exercice.WipeHints(); err != nil {
|
if _, err := exercice.WipeHints(); err != nil {
|
||||||
errs = append(errs, err.Error())
|
errs = append(errs, err.Error())
|
||||||
} else if ! i.exists(path.Join(exercice.Path, "hints")) {
|
} else if ! i.exists(path.Join(exercice.Path, "hints")) {
|
||||||
return errs
|
return
|
||||||
} else if hints, err := i.listDir(path.Join(exercice.Path, "hints")); err != nil {
|
} else if hints, err := i.listDir(path.Join(exercice.Path, "hints")); err != nil {
|
||||||
errs = append(errs, err.Error())
|
errs = append(errs, err.Error())
|
||||||
} else {
|
} else {
|
||||||
for n, hfile := range hints {
|
for n, hfile := range hints {
|
||||||
if hint_cnt, err := getFileContent(i, path.Join(exercice.Path, "hints", hfile)); err != nil {
|
var hint_cnt string
|
||||||
|
|
||||||
|
if fi, err := i.stat(path.Join(exercice.Path, "hints", hfile)); err != nil {
|
||||||
|
errs = append(errs, fmt.Sprintf("%q: unable to add hint %q: %s", path.Base(exercice.Path), hfile, err))
|
||||||
|
} else if ! fi.IsDir() && fi.Size() > 512 {
|
||||||
|
// Handle big files as downloadable content
|
||||||
|
if res, err := i.importFile(path.Join(exercice.Path, "hints", hfile), func(filePath string, origin string) (interface{}, error) {
|
||||||
|
// Calculate hash
|
||||||
|
hash512 := blake2b.New512()
|
||||||
|
if fd, err := os.Open(filePath); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
defer fd.Close()
|
||||||
|
|
||||||
|
reader := bufio.NewReader(fd)
|
||||||
|
if _, err := io.Copy(hash512, reader); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result512 := hash512.Sum(nil)
|
||||||
|
|
||||||
|
return "$FILES" + hex.EncodeToString(result512) + strings.TrimPrefix(filePath, fic.FilesDir), nil
|
||||||
|
}); err != nil {
|
||||||
|
errs = append(errs, fmt.Sprintf("%q: unable to import hint file %q: %s", path.Base(exercice.Path), hfile, err))
|
||||||
|
continue
|
||||||
|
} else if s, ok := res.(string); !ok {
|
||||||
|
errs = append(errs, fmt.Sprintf("%q: unable to import hint file %q: invalid string returned as filename", path.Base(exercice.Path), hfile))
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
hint_cnt = s
|
||||||
|
}
|
||||||
|
} else if hint_cnt, err = getFileContent(i, path.Join(exercice.Path, "hints", hfile)); err != nil {
|
||||||
errs = append(errs, fmt.Sprintf("%q: unable to read hint file %q: %s", path.Base(exercice.Path), hfile, err))
|
errs = append(errs, fmt.Sprintf("%q: unable to read hint file %q: %s", path.Base(exercice.Path), hfile, err))
|
||||||
continue
|
continue
|
||||||
} else if _, err := exercice.AddHint(fmt.Sprintf("Astuce #%d", n + 1), hint_cnt, 1); err != nil {
|
}
|
||||||
|
|
||||||
|
if _, err := exercice.AddHint(fmt.Sprintf("Astuce #%d", n + 1), hint_cnt, 1); err != nil {
|
||||||
errs = append(errs, fmt.Sprintf("%q: unable to add hint %q: %s", path.Base(exercice.Path), hfile, err))
|
errs = append(errs, fmt.Sprintf("%q: unable to add hint %q: %s", path.Base(exercice.Path), hfile, err))
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return errs
|
return
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,7 @@ samp.cksum {
|
|||||||
max-width: 16vw;
|
max-width: 16vw;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
word-wrap: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 small.authors {
|
h1 small.authors {
|
||||||
|
@ -34,19 +34,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-xl" ng-if="(my.exercices[current_exercice] && my.exercices[current_exercice].hints.length)">
|
<div class="col-xl" ng-if="(my.exercices[current_exercice] && my.exercices[current_exercice].hints.length)" style="margin-bottom: 15px">
|
||||||
<div class="card border-info">
|
<div class="card border-info" style="margin-bottom: 15px">
|
||||||
<div class="card-header bg-info text-white">
|
<div class="card-header bg-info text-white">
|
||||||
<span class="glyphicon glyphicon-lamp" aria-hidden="true"></span> Indices
|
<span class="glyphicon glyphicon-lamp" aria-hidden="true"></span> Indices
|
||||||
</div>
|
</div>
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
<a target="_self" class="list-group-item" ng-repeat="hint in my.exercices[current_exercice].hints" ng-href="{{ hint.file }}">
|
<a target="_self" class="list-group-item text-light" ng-repeat="hint in my.exercices[current_exercice].hints" ng-href="{{ hint.file }}">
|
||||||
<button ng-click="hsubmit(hint)" class="float-right btn btn-info" ng-if="!(hint.content || hint.file)" ng-class="{disabled: hint.submitted}"><span class="glyphicon glyphicon-lock" aria-hidden="true"></span> Débloquer</button>
|
<button ng-click="hsubmit(hint)" class="float-right btn btn-info" ng-if="!(hint.content || hint.file)" ng-class="{disabled: hint.submitted}"><span class="glyphicon glyphicon-lock" aria-hidden="true"></span> Débloquer</button>
|
||||||
<button ng-click="hint.hidden = false;" class="pull-right btn btn-info" ng-if="hint.content && hint.hidden"><span class="glyphicon glyphicon-lock" aria-hidden="true"></span> Afficher</button>
|
<button ng-click="hint.hidden = false;" class="float-right btn btn-info" ng-if="hint.content && hint.hidden"><span class="glyphicon glyphicon-lock" aria-hidden="true"></span> Afficher</button>
|
||||||
<h1 class="pull-left" style="margin: 5px 7px 5px -5px" ng-if="hint.file"><span class="glyphicon glyphicon-download" aria-hidden="true"></span></h1>
|
<h1 class="float-left" style="margin: 5px 7px 5px -5px" ng-if="hint.file"><span class="glyphicon glyphicon-download" aria-hidden="true"></span></h1>
|
||||||
<h4 class="list-group-item-heading">{{ hint.title }}</h4>
|
<h4 class="list-group-item-heading">{{ hint.title }}</h4>
|
||||||
<p class="list-group-item-text" ng-if="hint.content && !hint.hidden" ng-bind-html="hint.content"></p>
|
<p class="list-group-item-text" ng-if="!hint.file && hint.content && !hint.hidden" ng-bind-html="hint.content"></p>
|
||||||
<p class="list-group-item-text" ng-if="hint.file">Cliquez ici pour télécharger l'indice.</p>
|
<p class="list-group-item-text" ng-if="hint.file">Cliquez ici pour télécharger l'indice. <samp class="cksum" title="Somme de contrôle BLAKE2b : {{ hint.content }}">{{ hint.content }}</samp></p>
|
||||||
<p class="list-group-item-text" ng-if="!(hint.content || hint.file) || (hint.content && hint.hidden)">Débloquer cet indice vous coûtera <ng-pluralize count="hint.cost" when="{'one': '{} point', 'other': '{} points'}"></ng-pluralize>.</p>
|
<p class="list-group-item-text" ng-if="!(hint.content || hint.file) || (hint.content && hint.hidden)">Débloquer cet indice vous coûtera <ng-pluralize count="hint.cost" when="{'one': '{} point', 'other': '{} points'}"></ng-pluralize>.</p>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,8 +16,10 @@ type EHint struct {
|
|||||||
|
|
||||||
func treatHintContent(h *EHint) {
|
func treatHintContent(h *EHint) {
|
||||||
if strings.HasPrefix(h.Content, "$FILES") {
|
if strings.HasPrefix(h.Content, "$FILES") {
|
||||||
h.File = path.Join(FilesDir, strings.TrimPrefix(h.Content, "$FILES"))
|
fpath := strings.TrimPrefix(h.Content, "$FILES")
|
||||||
h.Content = ""
|
h.Content = fpath[:128]
|
||||||
|
fpath = fpath[128:]
|
||||||
|
h.File = path.Join(FilesDir, fpath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user