From aa0e7406c15da8ac26c3f3596e04c7441b7ad2a8 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 17 Jan 2023 18:26:04 +0100 Subject: [PATCH] Detect theme and exercice language at runtime (not stored) --- admin/sync/exercice_files.go | 8 ++++---- admin/sync/exercice_hints.go | 4 ++-- admin/sync/exercice_keys.go | 12 ++++++------ admin/sync/exercices.go | 19 ++++++++++++++---- admin/sync/hooks.go | 16 +++++++-------- admin/sync/themes.go | 12 +++++++++++- libfic/exercice.go | 7 ++++--- libfic/theme.go | 1 + repochecker/epita/files.go | 2 +- repochecker/epita/flags.go | 4 ++-- repochecker/file-inspector/files.go | 2 +- repochecker/grammalecte/flags.go | 30 ++++++++++++++++++++++++----- repochecker/grammalecte/main.go | 6 ++++++ repochecker/grammalecte/markdown.go | 6 +++++- repochecker/pcap-inspector/files.go | 2 +- repochecker/videos/subtitles.go | 8 ++++++-- repochecker/videos/video.go | 2 +- 17 files changed, 99 insertions(+), 42 deletions(-) diff --git a/admin/sync/exercice_files.go b/admin/sync/exercice_files.go index 104c08ec..73b564e3 100644 --- a/admin/sync/exercice_files.go +++ b/admin/sync/exercice_files.go @@ -153,7 +153,7 @@ func CheckExerciceFiles(i Importer, exercice *fic.Exercice, exceptions *CheckExc if f, exists := paramsFiles[fname]; exists { // Call checks hooks for _, hk := range hooks.mdTextHooks { - for _, err := range hk(f.Disclaimer, exceptions) { + for _, err := range hk(f.Disclaimer, exercice.Language, exceptions) { errs = append(errs, NewFileError(exercice, fname, err)) } } @@ -167,7 +167,7 @@ func CheckExerciceFiles(i Importer, exercice *fic.Exercice, exceptions *CheckExc // Call checks hooks for _, h := range hooks.fileHooks { - for _, e := range h(file, exceptions) { + for _, e := range h(file, exercice, exceptions) { errs = append(errs, NewFileError(exercice, fname, e)) } } @@ -213,7 +213,7 @@ func SyncExerciceFiles(i Importer, exercice *fic.Exercice, exceptions *CheckExce // Call checks hooks for _, hk := range hooks.mdTextHooks { - for _, err := range hk(f.Disclaimer, exceptions) { + for _, err := range hk(f.Disclaimer, exercice.Language, exceptions) { errs = append(errs, NewFileError(exercice, fname, err)) } } @@ -234,7 +234,7 @@ func SyncExerciceFiles(i Importer, exercice *fic.Exercice, exceptions *CheckExce // Call checks hooks for _, h := range hooks.fileHooks { - for _, e := range h(file, exceptions) { + for _, e := range h(file, exercice, exceptions) { errs = append(errs, NewFileError(exercice, fname, e)) } } diff --git a/admin/sync/exercice_hints.go b/admin/sync/exercice_hints.go index 9c7fb353..5f342f68 100644 --- a/admin/sync/exercice_hints.go +++ b/admin/sync/exercice_hints.go @@ -85,7 +85,7 @@ func buildExerciceHints(i Importer, exercice *fic.Exercice, exceptions *CheckExc } else { // Call checks hooks for _, hk := range hooks.mdTextHooks { - for _, err := range hk(h.Content, exceptions) { + for _, err := range hk(h.Content, exercice.Language, exceptions) { errs = append(errs, NewHintError(exercice, h, n, err)) } } @@ -97,7 +97,7 @@ func buildExerciceHints(i Importer, exercice *fic.Exercice, exceptions *CheckExc // Call checks hooks for _, hook := range hooks.hintHooks { - for _, e := range hook(h, exceptions) { + for _, e := range hook(h, exercice, exceptions) { errs = append(errs, NewHintError(exercice, h, n, e)) } } diff --git a/admin/sync/exercice_keys.go b/admin/sync/exercice_keys.go index b9ed1037..5f827644 100644 --- a/admin/sync/exercice_keys.go +++ b/admin/sync/exercice_keys.go @@ -104,7 +104,7 @@ func buildLabelFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, exc // Call checks hooks for _, h := range hooks.mdTextHooks { - for _, err := range h(flag.Label, exceptions.Filter2ndCol(strconv.Itoa(flagline))) { + for _, err := range h(flag.Label, exercice.Language, exceptions.Filter2ndCol(strconv.Itoa(flagline))) { errs = append(errs, NewFlagError(exercice, &flag, flagline, err)) } } @@ -139,7 +139,7 @@ func buildLabelFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, exc // Call checks hooks for _, h := range hooks.flagLabelHooks { - for _, e := range h(f, exceptions.Filter2ndCol(strconv.Itoa(flagline))) { + for _, e := range h(f, exercice, exceptions.Filter2ndCol(strconv.Itoa(flagline))) { errs = append(errs, NewFlagError(exercice, &flag, flagline, e)) } } @@ -199,7 +199,7 @@ func buildKeyFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, defau // Call checks hooks for _, h := range hooks.flagKeyHooks { - for _, e := range h(fk, raw, exceptions.Filter2ndCol(strconv.Itoa(flagline))) { + for _, e := range h(fk, raw, exercice, exceptions.Filter2ndCol(strconv.Itoa(flagline))) { errs = append(errs, NewFlagError(exercice, &flag, flagline, e)) } } @@ -242,7 +242,7 @@ func buildKeyFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, defau // Call checks hooks for _, h := range hooks.flagChoiceHooks { - for _, e := range h(fc, exceptions.Filter2ndCol(strconv.Itoa(flagline))) { + for _, e := range h(fc, exercice, exceptions.Filter2ndCol(strconv.Itoa(flagline))) { errs = append(errs, NewFlagError(exercice, &flag, flagline, e)) } } @@ -263,7 +263,7 @@ func buildKeyFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, defau // Call checks hooks for _, h := range hooks.flagKeyWithChoicesHooks { - for _, e := range h(fk, raw, choices, exceptions.Filter2ndCol(strconv.Itoa(flagline))) { + for _, e := range h(fk, raw, choices, exercice, exceptions.Filter2ndCol(strconv.Itoa(flagline))) { errs = append(errs, NewFlagError(exercice, &flag, flagline, e)) } } @@ -441,7 +441,7 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl // Call checks hooks for _, h := range hooks.flagMCQHooks { - for _, e := range h(&addedFlag, addedFlag.Entries, exceptions) { + for _, e := range h(&addedFlag, addedFlag.Entries, exercice, exceptions) { errs = append(errs, NewFlagError(exercice, &flag, nline+1, e)) } } diff --git a/admin/sync/exercices.go b/admin/sync/exercices.go index 5e4cc852..e3005131 100644 --- a/admin/sync/exercices.go +++ b/admin/sync/exercices.go @@ -109,6 +109,17 @@ func BuildExercice(i Importer, theme *fic.Theme, epath string, dmap *map[int64]* exceptions = exceptions.GetExerciceExceptions(e) //log.Printf("Kept repochecker exceptions for this exercice: %v", exceptions) + e.Language = theme.Language + // Overwrite language if language.txt exists + if language, err := GetFileContent(i, path.Join(epath, "language.txt")); err == nil { + language = strings.TrimSpace(language) + if strings.Contains(language, "\n") { + errs = append(errs, NewExerciceError(e, fmt.Errorf("language.txt: Language can't contain new lines"), theme)) + } else { + e.Language = language + } + } + // Overwrite title if title.txt exists if myTitle, err := GetFileContent(i, path.Join(epath, "title.txt")); err == nil { myTitle = strings.TrimSpace(myTitle) @@ -142,7 +153,7 @@ func BuildExercice(i Importer, theme *fic.Theme, epath string, dmap *map[int64]* // Call checks hooks for _, h := range hooks.mdTextHooks { - for _, err := range h(e.Overview, exceptions.GetFileExceptions("overview.md", "overview.txt")) { + for _, err := range h(e.Overview, e.Language, exceptions.GetFileExceptions("overview.md", "overview.txt")) { errs = append(errs, NewExerciceError(e, fmt.Errorf("overview.md: %w", err))) } } @@ -172,7 +183,7 @@ func BuildExercice(i Importer, theme *fic.Theme, epath string, dmap *map[int64]* } else { // Call checks hooks for _, h := range hooks.mdTextHooks { - for _, err := range h(e.Statement, exceptions.GetFileExceptions("statement.md", "statement.txt")) { + for _, err := range h(e.Statement, e.Language, exceptions.GetFileExceptions("statement.md", "statement.txt")) { errs = append(errs, NewExerciceError(e, fmt.Errorf("statement.md: %w", err))) } } @@ -192,7 +203,7 @@ func BuildExercice(i Importer, theme *fic.Theme, epath string, dmap *map[int64]* } else if len(e.Finished) > 0 { // Call checks hooks for _, h := range hooks.mdTextHooks { - for _, err := range h(e.Finished, exceptions.GetFileExceptions("finished.md", "finished.txt")) { + for _, err := range h(e.Finished, e.Language, exceptions.GetFileExceptions("finished.md", "finished.txt")) { errs = append(errs, NewExerciceError(e, fmt.Errorf("finished.md: %w", err))) } } @@ -291,7 +302,7 @@ func BuildExercice(i Importer, theme *fic.Theme, epath string, dmap *map[int64]* } else { // Call checks hooks for _, h := range hooks.mdTextHooks { - for _, err := range h(e.Resolution, exceptions.GetFileExceptions("resolution.md"), p.GetRawFlags()...) { + for _, err := range h(e.Resolution, e.Language, exceptions.GetFileExceptions("resolution.md"), p.GetRawFlags()...) { errs = append(errs, NewExerciceError(e, fmt.Errorf("resolution.md: %w", err))) } } diff --git a/admin/sync/hooks.go b/admin/sync/hooks.go index 9f80b7f9..db6f09a9 100644 --- a/admin/sync/hooks.go +++ b/admin/sync/hooks.go @@ -9,14 +9,14 @@ import ( var hooks = &CheckHooks{customHooks: map[string]CustomCheckHook{}} -type CheckFlagChoiceHook func(*fic.FlagChoice, *CheckExceptions) []error -type CheckFlagKeyHook func(*fic.FlagKey, string, *CheckExceptions) []error -type CheckFlagKeyWithChoicesHook func(*fic.FlagKey, string, []*fic.FlagChoice, *CheckExceptions) []error -type CheckFlagLabelHook func(*fic.FlagLabel, *CheckExceptions) []error -type CheckFlagMCQHook func(*fic.MCQ, []*fic.MCQ_entry, *CheckExceptions) []error -type CheckFileHook func(*fic.EFile, *CheckExceptions) []error -type CheckHintHook func(*fic.EHint, *CheckExceptions) []error -type CheckMDTextHook func(string, *CheckExceptions, ...string) []error +type CheckFlagChoiceHook func(*fic.FlagChoice, *fic.Exercice, *CheckExceptions) []error +type CheckFlagKeyHook func(*fic.FlagKey, string, *fic.Exercice, *CheckExceptions) []error +type CheckFlagKeyWithChoicesHook func(*fic.FlagKey, string, []*fic.FlagChoice, *fic.Exercice, *CheckExceptions) []error +type CheckFlagLabelHook func(*fic.FlagLabel, *fic.Exercice, *CheckExceptions) []error +type CheckFlagMCQHook func(*fic.MCQ, []*fic.MCQ_entry, *fic.Exercice, *CheckExceptions) []error +type CheckFileHook func(*fic.EFile, *fic.Exercice, *CheckExceptions) []error +type CheckHintHook func(*fic.EHint, *fic.Exercice, *CheckExceptions) []error +type CheckMDTextHook func(string, string, *CheckExceptions, ...string) []error type CheckExerciceHook func(*fic.Exercice, *CheckExceptions) []error type CustomCheckHook func(interface{}, *CheckExceptions) []error diff --git a/admin/sync/themes.go b/admin/sync/themes.go index 1e3796c8..994a6d28 100644 --- a/admin/sync/themes.go +++ b/admin/sync/themes.go @@ -112,6 +112,16 @@ func BuildTheme(i Importer, tdir string) (th *fic.Theme, exceptions *CheckExcept // Get exceptions exceptions = LoadException(i, th) + // Overwrite language + if language, err := GetFileContent(i, path.Join(tdir, "language.txt")); err == nil { + language = strings.TrimSpace(language) + if strings.Contains(language, "\n") { + errs = append(errs, NewThemeError(th, fmt.Errorf("language.txt: Language can't contain new lines"))) + } else { + th.Language = language + } + } + // Extract theme's label if tname, err := GetFileContent(i, path.Join(tdir, "title.txt")); err == nil { th.Name = fixnbsp(tname) @@ -144,7 +154,7 @@ func BuildTheme(i Importer, tdir string) (th *fic.Theme, exceptions *CheckExcept } else { // Call checks hooks for _, h := range hooks.mdTextHooks { - for _, err := range h(intro, exceptions.GetFileExceptions("overview.md", "overview.txt")) { + for _, err := range h(intro, th.Language, exceptions.GetFileExceptions("overview.md", "overview.txt")) { errs = append(errs, NewThemeError(th, fmt.Errorf("overview.md: %w", err))) } } diff --git a/libfic/exercice.go b/libfic/exercice.go index 23cece3f..47080986 100644 --- a/libfic/exercice.go +++ b/libfic/exercice.go @@ -20,9 +20,10 @@ var ExerciceCurrentCoefficient = 1.0 // Exercice represents a challenge inside a Theme. type Exercice struct { - Id int64 `json:"id"` - IdTheme int64 `json:"id_theme"` - Title string `json:"title"` + Id int64 `json:"id"` + IdTheme int64 `json:"id_theme"` + Language string `json:"lang,omitempty"` + Title string `json:"title"` // WIP indicates if the exercice is in development or not WIP bool `json:"wip"` // URLid is used to reference the challenge from the URL path diff --git a/libfic/theme.go b/libfic/theme.go index 0298aefa..fe438e7c 100644 --- a/libfic/theme.go +++ b/libfic/theme.go @@ -5,6 +5,7 @@ import () // Theme represents a group of challenges, to display to players type Theme struct { Id int64 `json:"id"` + Language string `json:"lang,omitempty"` Name string `json:"name"` URLId string `json:"urlid"` Path string `json:"path"` diff --git a/repochecker/epita/files.go b/repochecker/epita/files.go index 03e7253b..1057d821 100644 --- a/repochecker/epita/files.go +++ b/repochecker/epita/files.go @@ -9,7 +9,7 @@ import ( "srs.epita.fr/fic-server/libfic" ) -func EPITACheckFile(file *fic.EFile, exceptions *sync.CheckExceptions) (errs []error) { +func EPITACheckFile(file *fic.EFile, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) { // Enforce file format if path.Ext(file.Name) == ".rar" || path.Ext(file.Name) == ".7z" { errs = append(errs, fmt.Errorf("this file use a forbidden archive type.")) diff --git a/repochecker/epita/flags.go b/repochecker/epita/flags.go index 6437a6aa..6c0d0ec8 100644 --- a/repochecker/epita/flags.go +++ b/repochecker/epita/flags.go @@ -10,7 +10,7 @@ import ( "srs.epita.fr/fic-server/libfic" ) -func EPITACheckKeyFlag(flag *fic.FlagKey, raw string, exceptions *sync.CheckExceptions) (errs []error) { +func EPITACheckKeyFlag(flag *fic.FlagKey, raw string, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) { if (flag.Label[0] == 'Q' || flag.Label[0] == 'q') && (flag.Label[1] == 'U' || flag.Label[1] == 'u') || (flag.Label[0] == 'W' || flag.Label[0] == 'w') && (flag.Label[1] == 'H' || flag.Label[1] == 'h') { errs = append(errs, fmt.Errorf("Label should not begin with %s. This seem to be a question. Reword your label as a description of the expected flag, `:` are automatically appended.", flag.Label[0:2])) @@ -47,7 +47,7 @@ func EPITACheckKeyFlag(flag *fic.FlagKey, raw string, exceptions *sync.CheckExce return } -func EPITACheckKeyFlagWithChoices(flag *fic.FlagKey, raw string, choices []*fic.FlagChoice, exceptions *sync.CheckExceptions) (errs []error) { +func EPITACheckKeyFlagWithChoices(flag *fic.FlagKey, raw string, choices []*fic.FlagChoice, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) { if !exceptions.HasException(":bruteforcable-choices") { if len(choices) < 10 && flag.ChoicesCost == 0 { errs = append(errs, fmt.Errorf("requires at least 10 choices to avoid brute-force")) diff --git a/repochecker/file-inspector/files.go b/repochecker/file-inspector/files.go index 67f4389a..5e54bd93 100644 --- a/repochecker/file-inspector/files.go +++ b/repochecker/file-inspector/files.go @@ -8,7 +8,7 @@ import ( "srs.epita.fr/fic-server/libfic" ) -func InspectFile(file *fic.EFile, exceptions *sync.CheckExceptions) (errs []error) { +func InspectFile(file *fic.EFile, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) { if filepath.Ext(file.Name) == ".tar" || strings.HasSuffix(file.Name, ".tar.gz") || strings.HasSuffix(file.Name, ".tar.bz2") { // Check there is more than 1 file in tarball errs = append(errs, checkTarball(file, exceptions)...) diff --git a/repochecker/grammalecte/flags.go b/repochecker/grammalecte/flags.go index 8897ce42..e225c0c7 100644 --- a/repochecker/grammalecte/flags.go +++ b/repochecker/grammalecte/flags.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "log" + "strings" "unicode" "srs.epita.fr/fic-server/admin/sync" @@ -11,7 +12,11 @@ import ( lib "srs.epita.fr/fic-server/repochecker/grammalecte/lib" ) -func GrammalecteCheckKeyFlag(flag *fic.FlagKey, raw string, exceptions *sync.CheckExceptions) (errs []error) { +func GrammalecteCheckKeyFlag(flag *fic.FlagKey, raw string, exercice *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) { + if !isRecognizedLanguage(exercice.Language) { + return + } + label, _, _, _ := flag.AnalyzeFlagLabel() for _, err := range grammalecte("label ", label, -1, exceptions, &CommonOpts) { if e, ok := err.(lib.GrammarError); ok && e.RuleId == "poncfin_règle1" { @@ -28,7 +33,11 @@ func GrammalecteCheckKeyFlag(flag *fic.FlagKey, raw string, exceptions *sync.Che return } -func GrammalecteCheckFlagChoice(choice *fic.FlagChoice, exceptions *sync.CheckExceptions) (errs []error) { +func GrammalecteCheckFlagChoice(choice *fic.FlagChoice, exercice *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) { + if !isRecognizedLanguage(exercice.Language) { + return + } + errs = append(errs, grammalecte("label ", choice.Label, -1, exceptions, &CommonOpts)...) if len(errs) == 0 && !unicode.IsUpper(bytes.Runes([]byte(choice.Label))[0]) && !exceptions.HasException(":label_majuscule") { @@ -38,7 +47,11 @@ func GrammalecteCheckFlagChoice(choice *fic.FlagChoice, exceptions *sync.CheckEx return } -func GrammalecteCheckHint(hint *fic.EHint, exceptions *sync.CheckExceptions) (errs []error) { +func GrammalecteCheckHint(hint *fic.EHint, exercice *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) { + if !isRecognizedLanguage(exercice.Language) { + return + } + if len(hint.Title) > 0 { errs = append(errs, grammalecte("title ", hint.Title, -1, exceptions, &CommonOpts)...) if len(errs) == 0 && !unicode.IsUpper(bytes.Runes([]byte(hint.Title))[0]) && !exceptions.HasException(":title_majuscule") { @@ -52,8 +65,15 @@ func GrammalecteCheckHint(hint *fic.EHint, exceptions *sync.CheckExceptions) (er } func GrammalecteCheckGrammar(data interface{}, exceptions *sync.CheckExceptions) []error { - if s, ok := data.(string); ok { - return grammalecte("", s, 0, exceptions, &CommonOpts) + if s, ok := data.(struct { + Str string + Language string + }); ok { + if s.Language != "" && strings.HasPrefix(s.Language, "fr") { + return nil + } + + return grammalecte("", s.Str, 0, exceptions, &CommonOpts) } else { log.Printf("Unknown data given to GrammalecteCheckGrammar: %T", data) return nil diff --git a/repochecker/grammalecte/main.go b/repochecker/grammalecte/main.go index f0f3565c..219befc2 100644 --- a/repochecker/grammalecte/main.go +++ b/repochecker/grammalecte/main.go @@ -4,6 +4,7 @@ import ( "log" "os" "os/exec" + "strings" "time" "srs.epita.fr/fic-server/admin/sync" @@ -104,6 +105,11 @@ func runGrammalecteServer() error { return nil } +func isRecognizedLanguage(lang string) bool { + // Grammalecte can only check french texts + return lang == "" || strings.HasPrefix(lang, "fr") +} + func RegisterChecksHooks(h *sync.CheckHooks) { if err := runGrammalecteServer(); err != nil { log.Fatal("Unable to start grammalecte-server:", err) diff --git a/repochecker/grammalecte/markdown.go b/repochecker/grammalecte/markdown.go index 1969c938..25fa01cb 100644 --- a/repochecker/grammalecte/markdown.go +++ b/repochecker/grammalecte/markdown.go @@ -17,7 +17,11 @@ import ( "github.com/yuin/goldmark/util" ) -func GrammalecteCheckMDText(str string, exceptions *sync.CheckExceptions, forbiddenStrings ...string) (errs []error) { +func GrammalecteCheckMDText(str string, lang string, exceptions *sync.CheckExceptions, forbiddenStrings ...string) (errs []error) { + if !isRecognizedLanguage(lang) { + return + } + if exceptions != nil { for k := range *exceptions { tmp := strings.SplitN(k, ":", 3) diff --git a/repochecker/pcap-inspector/files.go b/repochecker/pcap-inspector/files.go index f2239006..fc6f1661 100644 --- a/repochecker/pcap-inspector/files.go +++ b/repochecker/pcap-inspector/files.go @@ -109,7 +109,7 @@ func CheckTextFile(fd *os.File) (errs []error) { return } -func InspectFileForIPAddr(file *fic.EFile, exceptions *sync.CheckExceptions) (errs []error) { +func InspectFileForIPAddr(file *fic.EFile, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) { fd, closer, err := sync.GetFile(sync.GlobalImporter, file.GetOrigin()) if err != nil { log.Printf("Unable to open %q: %s", file.GetOrigin(), err.Error()) diff --git a/repochecker/videos/subtitles.go b/repochecker/videos/subtitles.go index 689c5824..7c5ea5c5 100644 --- a/repochecker/videos/subtitles.go +++ b/repochecker/videos/subtitles.go @@ -11,9 +11,10 @@ import ( ffmpeg "github.com/u2takey/ffmpeg-go" "srs.epita.fr/fic-server/admin/sync" + "srs.epita.fr/fic-server/libfic" ) -func CheckGrammarSubtitleTrack(path string, exceptions *sync.CheckExceptions) (errs []error) { +func CheckGrammarSubtitleTrack(path string, exercice *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) { tmpfile, err := ioutil.TempFile("", "resolution-*.srt") if err != nil { errs = append(errs, fmt.Errorf("unable to create a temporary file: %w", err)) @@ -39,7 +40,10 @@ func CheckGrammarSubtitleTrack(path string, exceptions *sync.CheckExceptions) (e for _, item := range subtitles.Items { lines = append(lines, item.String()) } - for _, e := range hooks.CallCustomHook("CheckGrammar", strings.Join(lines, "\n"), exceptions) { + for _, e := range hooks.CallCustomHook("CheckGrammar", struct { + Str string + Language string + }{Str: strings.Join(lines, "\n"), Language: exercice.Language}, exceptions) { errs = append(errs, fmt.Errorf("subtitle-track: %w", e)) } diff --git a/repochecker/videos/video.go b/repochecker/videos/video.go index eaf34fb0..292c3f98 100644 --- a/repochecker/videos/video.go +++ b/repochecker/videos/video.go @@ -143,7 +143,7 @@ func checkResolutionVideo(e *fic.Exercice, exceptions *sync.CheckExceptions) (er if !subtitles_seen && !exceptions.HasException(":subtitle:no_track") { errs = append(errs, fmt.Errorf("no subtitles track found")) } else if subtitles_seen { - errs = append(errs, CheckGrammarSubtitleTrack(path, exceptions)...) + errs = append(errs, CheckGrammarSubtitleTrack(path, e, exceptions)...) } return