From 8c95782effc11d5836e44b67692dae26fbf09db1 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 2 Dec 2018 11:43:24 +0100 Subject: [PATCH] Implement and display headlines in interface --- admin/api/exercice.go | 6 +++++- admin/api/theme.go | 11 ++--------- admin/static/js/app.js | 4 ++-- admin/sync/exercices.go | 11 +++++++++-- admin/sync/themes.go | 22 +++++++++++++++++----- frontend/static/views/defi.html | 3 ++- frontend/static/views/home.html | 2 +- frontend/static/views/tag.html | 2 +- frontend/static/views/theme.html | 5 +++-- libfic/db.go | 2 ++ libfic/exercice.go | 26 ++++++++++++++------------ libfic/theme.go | 31 ++++++++++++++++--------------- libfic/theme_export.go | 18 +++++++++++------- 13 files changed, 85 insertions(+), 58 deletions(-) diff --git a/admin/api/exercice.go b/admin/api/exercice.go index 7636f29a..039cc1df 100644 --- a/admin/api/exercice.go +++ b/admin/api/exercice.go @@ -144,6 +144,10 @@ func partUpdateExercice(exercice fic.Exercice, body []byte) (interface{}, error) exercice.Statement = ue.Statement } + if len(ue.Headline) > 0 { + exercice.Headline = ue.Headline + } + if len(ue.Overview) > 0 { exercice.Overview = ue.Overview } @@ -199,7 +203,7 @@ func createExercice(theme fic.Theme, body []byte) (interface{}, error) { } } - return theme.AddExercice(ue.Title, ue.URLId, ue.Path, ue.Statement, ue.Overview, depend, ue.Gain, ue.VideoURI) + return theme.AddExercice(ue.Title, ue.URLId, ue.Path, ue.Statement, ue.Overview, ue.Headline, depend, ue.Gain, ue.VideoURI) } type uploadedHint struct { diff --git a/admin/api/theme.go b/admin/api/theme.go index 2c32b69e..e95f0993 100644 --- a/admin/api/theme.go +++ b/admin/api/theme.go @@ -146,15 +146,8 @@ func showThemedExercice(theme fic.Theme, exercice fic.Exercice, body []byte) (in return exercice, nil } -type uploadedTheme struct { - Name string - URLId string - Authors string - Intro string -} - func createTheme(_ httprouter.Params, body []byte) (interface{}, error) { - var ut uploadedTheme + var ut fic.Theme if err := json.Unmarshal(body, &ut); err != nil { return nil, err } @@ -163,7 +156,7 @@ func createTheme(_ httprouter.Params, body []byte) (interface{}, error) { return nil, errors.New("Theme's name not filled") } - return fic.CreateTheme(ut.Name, ut.URLId, "", ut.Authors, ut.Intro, "") + return fic.CreateTheme(ut.Name, ut.URLId, "", ut.Authors, ut.Intro, ut.Headline, ut.Image) } func updateTheme(theme fic.Theme, body []byte) (interface{}, error) { diff --git a/admin/static/js/app.js b/admin/static/js/app.js index 383f5c9b..0b2c4be0 100644 --- a/admin/static/js/app.js +++ b/admin/static/js/app.js @@ -929,7 +929,7 @@ angular.module("FICApp") }) .controller("ThemeController", function($scope, Theme, $routeParams, $location, $rootScope, $http) { $scope.theme = Theme.get({ themeId: $routeParams.themeId }); - $scope.fields = ["name", "urlid", "authors", "intro", "image"]; + $scope.fields = ["name", "urlid", "authors", "headline", "intro", "image"]; $scope.saveTheme = function() { if (this.theme.id) { @@ -1044,7 +1044,7 @@ angular.module("FICApp") $scope.exercice = Exercice.get({ exerciceId: $routeParams.exerciceId }); } $scope.exercices = Exercice.query(); - $scope.fields = ["title", "urlid", "statement", "overview", "depend", "gain", "coefficient", "videoURI", "issue", "issuekind"]; + $scope.fields = ["title", "urlid", "statement", "headline", "overview", "depend", "gain", "coefficient", "videoURI", "issue", "issuekind"]; $scope.showTags = false; $scope.toggleTags = function(val) { diff --git a/admin/sync/exercices.go b/admin/sync/exercices.go index b32873c8..3a018c85 100644 --- a/admin/sync/exercices.go +++ b/admin/sync/exercices.go @@ -59,6 +59,11 @@ func SyncExercices(i Importer, theme fic.Theme) []string { if err != nil { errs = append(errs, fmt.Sprintf("%q: overview.txt: %s", edir, err)) } + ovrvw := strings.Split(overview, "\n") + headline := ovrvw[0] + if len(ovrvw) > 1 { + overview = strings.Join(ovrvw[1:], "\n") + } statement, err := getFileContent(i, path.Join(theme.Path, edir, "statement.txt")) if err != nil { @@ -111,18 +116,20 @@ func SyncExercices(i Importer, theme fic.Theme) []string { // Markdown pre-formating statement = string(blackfriday.Run([]byte(statement))) overview = string(blackfriday.Run([]byte(overview))) + headline = string(blackfriday.Run([]byte(headline))) e, err := theme.GetExerciceByTitle(ename) if err != nil { - if e, err = theme.AddExercice(ename, fic.ToURLid(ename), path.Join(theme.Path, edir), statement, overview, depend, gain, videoURI); err != nil { + if e, err = theme.AddExercice(ename, fic.ToURLid(ename), path.Join(theme.Path, edir), statement, overview, headline, depend, gain, videoURI); err != nil { errs = append(errs, fmt.Sprintf("%q: error on exercice add: %s", edir, err)) continue } - } else if e.Title != ename || e.URLId == "" || e.Statement != statement || e.Overview != overview || e.Gain != gain || e.VideoURI != videoURI { + } else if e.Title != ename || e.URLId == "" || e.Statement != statement || e.Overview != overview || e.Headline != headline || e.Gain != gain || e.VideoURI != videoURI { e.Title = ename e.URLId = fic.ToURLid(ename) e.Statement = statement e.Overview = overview + e.Headline = headline e.Gain = gain e.VideoURI = videoURI if _, err := e.Update(); err != nil { diff --git a/admin/sync/themes.go b/admin/sync/themes.go index a200b0bd..b60abf47 100644 --- a/admin/sync/themes.go +++ b/admin/sync/themes.go @@ -62,6 +62,7 @@ func SyncThemes(i Importer) []string { for _, tdir := range themes { var authors []string var intro string + var headline string var image string var theme fic.Theme var tname string @@ -78,10 +79,19 @@ func SyncThemes(i Importer) []string { continue } else if intro, err = getFileContent(i, path.Join(tdir, "overview.txt")); err != nil { errs = append(errs, fmt.Sprintf("%q: unable to get theme's overview: %s", tname, err)) - } else if theme, err = fic.GetThemeByName(tname); err != nil { - if _, err := fic.CreateTheme(tname, fic.ToURLid(tname), tdir, strings.Join(authors, ", "), intro, image); err != nil { - errs = append(errs, fmt.Sprintf("%q: an error occurs during add: %s", tdir, err)) - continue + } else { + // Split headline from intro + ovrvw := strings.Split(intro, "\n") + headline = ovrvw[0] + if len(ovrvw) > 1 { + intro = strings.Join(ovrvw[1:], "\n") + } + + if theme, err = fic.GetThemeByName(tname); err != nil { + if _, err := fic.CreateTheme(tname, fic.ToURLid(tname), tdir, strings.Join(authors, ", "), intro, headline, image); err != nil { + errs = append(errs, fmt.Sprintf("%q: an error occurs during add: %s", tdir, err)) + continue + } } } @@ -90,6 +100,7 @@ func SyncThemes(i Importer) []string { // Format overview (markdown) intro = string(blackfriday.Run([]byte(intro))) + headline = string(blackfriday.Run([]byte(headline))) if i.exists(path.Join(tdir, "heading.jpg")) { image = path.Join(tdir, "heading.jpg") @@ -108,10 +119,11 @@ func SyncThemes(i Importer) []string { } } - if theme.Name != tname || theme.Authors != authors_str || theme.Intro != intro || theme.Image != image { + if theme.Name != tname || theme.Authors != authors_str || theme.Headline != headline || theme.Intro != intro || theme.Image != image { theme.Name = tname theme.Authors = authors_str theme.Intro = intro + theme.Headline = headline theme.Image = image theme.Path = tdir if _, err := theme.Update(); err != nil { diff --git a/frontend/static/views/defi.html b/frontend/static/views/defi.html index d9cc5327..7ac608c7 100644 --- a/frontend/static/views/defi.html +++ b/frontend/static/views/defi.html @@ -20,7 +20,8 @@ Vous n'avez pas encore accès à cet exercice.
-

+

+

{{ themes[current_theme].exercices[current_exercice].title }}

diff --git a/frontend/static/views/home.html b/frontend/static/views/home.html index 7d0d91fa..8d42f513 100644 --- a/frontend/static/views/home.html +++ b/frontend/static/views/home.html @@ -22,7 +22,7 @@ {{ theme.name }} #tag -

Sunt omnis est quibusdam aperiam quos minima numquam. Omnis eos corrupti corrupti quia ut.

+

diff --git a/frontend/static/views/tag.html b/frontend/static/views/tag.html index ba20e793..ec156239 100644 --- a/frontend/static/views/tag.html +++ b/frontend/static/views/tag.html @@ -6,7 +6,7 @@ {{ex.exercice.title}} #{{ tag }} -

Sunt omnis est quibusdam aperiam quos minima numquam. Omnis eos corrupti corrupti quia ut.

+

diff --git a/frontend/static/views/theme.html b/frontend/static/views/theme.html index 61ed3952..c872b40d 100644 --- a/frontend/static/views/theme.html +++ b/frontend/static/views/theme.html @@ -1,5 +1,6 @@
-

+

+

@@ -17,6 +18,6 @@ -

Sunt omnis est quibusdam aperiam quos minima numquam.

+

diff --git a/libfic/db.go b/libfic/db.go index 41e991b6..9692a829 100644 --- a/libfic/db.go +++ b/libfic/db.go @@ -72,6 +72,7 @@ CREATE TABLE IF NOT EXISTS themes( name VARCHAR(255) NOT NULL, url_id VARCHAR(191) NOT NULL UNIQUE, path VARCHAR(191) NOT NULL UNIQUE, + headline TEXT NOT NULL, intro TEXT NOT NULL, image VARCHAR(255) NOT NULL, authors TEXT NOT NULL @@ -116,6 +117,7 @@ CREATE TABLE IF NOT EXISTS exercices( id_exercice INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, id_theme INTEGER NOT NULL, title VARCHAR(255) NOT NULL, + headline TEXT NOT NULL, url_id VARCHAR(255) NOT NULL, path VARCHAR(191) NOT NULL UNIQUE, statement TEXT NOT NULL, diff --git a/libfic/exercice.go b/libfic/exercice.go index 30a4bb80..20bae160 100644 --- a/libfic/exercice.go +++ b/libfic/exercice.go @@ -26,6 +26,8 @@ type Exercice struct { Statement string `json:"statement"` // Overview is the challenge description shown to public Overview string `json:"overview"` + // Headline is the challenge headline to fill in small part + Headline string `json:"headline"` // Issue is an optional text describing an issue with the exercice Issue string `json:"issue"` // IssueKind is the criticity level of the previous issue @@ -45,7 +47,7 @@ type Exercice struct { // GetExercice retrieves the challenge with the given id. func GetExercice(id int64) (Exercice, error) { var e Exercice - if err := DBQueryRow("SELECT id_exercice, title, url_id, path, statement, overview, issue, issue_kind, depend, gain, coefficient_cur, video_uri FROM exercices WHERE id_exercice = ?", id).Scan(&e.Id, &e.Title, &e.URLId, &e.Path, &e.Statement, &e.Overview, &e.Issue, &e.IssueKind, &e.Depend, &e.Gain, &e.Coefficient, &e.VideoURI); err != nil { + if err := DBQueryRow("SELECT id_exercice, title, url_id, path, statement, overview, headline, issue, issue_kind, depend, gain, coefficient_cur, video_uri FROM exercices WHERE id_exercice = ?", id).Scan(&e.Id, &e.Title, &e.URLId, &e.Path, &e.Statement, &e.Overview, &e.Headline, &e.Issue, &e.IssueKind, &e.Depend, &e.Gain, &e.Coefficient, &e.VideoURI); err != nil { return Exercice{}, err } @@ -55,7 +57,7 @@ func GetExercice(id int64) (Exercice, error) { // GetExercice retrieves the challenge with the given id. func (t Theme) GetExercice(id int) (Exercice, error) { var e Exercice - if err := DBQueryRow("SELECT id_exercice, title, url_id, path, statement, overview, issue, issue_kind, depend, gain, coefficient_cur, video_uri FROM exercices WHERE id_theme = ? AND id_exercice = ?", t.Id, id).Scan(&e.Id, &e.Title, &e.URLId, &e.Path, &e.Statement, &e.Overview, &e.Issue, &e.IssueKind, &e.Depend, &e.Gain, &e.Coefficient, &e.VideoURI); err != nil { + if err := DBQueryRow("SELECT id_exercice, title, url_id, path, statement, overview, headline, issue, issue_kind, depend, gain, coefficient_cur, video_uri FROM exercices WHERE id_theme = ? AND id_exercice = ?", t.Id, id).Scan(&e.Id, &e.Title, &e.URLId, &e.Path, &e.Statement, &e.Overview, &e.Headline, &e.Issue, &e.IssueKind, &e.Depend, &e.Gain, &e.Coefficient, &e.VideoURI); err != nil { return Exercice{}, err } @@ -65,7 +67,7 @@ func (t Theme) GetExercice(id int) (Exercice, error) { // GetExerciceByTitle retrieves the challenge with the given title. func (t Theme) GetExerciceByTitle(title string) (Exercice, error) { var e Exercice - if err := DBQueryRow("SELECT id_exercice, title, url_id, path, statement, overview, issue, issue_kind, depend, gain, coefficient_cur, video_uri FROM exercices WHERE id_theme = ? AND title = ?", t.Id, title).Scan(&e.Id, &e.Title, &t.URLId, &e.Path, &e.Statement, &e.Overview, &e.Issue, &e.IssueKind, &e.Depend, &e.Gain, &e.Coefficient, &e.VideoURI); err != nil { + if err := DBQueryRow("SELECT id_exercice, title, url_id, path, statement, overview, headline, issue, issue_kind, depend, gain, coefficient_cur, video_uri FROM exercices WHERE id_theme = ? AND title = ?", t.Id, title).Scan(&e.Id, &e.Title, &t.URLId, &e.Path, &e.Statement, &e.Overview, &e.Headline, &e.Issue, &e.IssueKind, &e.Depend, &e.Gain, &e.Coefficient, &e.VideoURI); err != nil { return Exercice{}, err } @@ -74,7 +76,7 @@ func (t Theme) GetExerciceByTitle(title string) (Exercice, error) { // GetExercices returns the list of all challenges present in the database. func GetExercices() ([]Exercice, error) { - if rows, err := DBQuery("SELECT id_exercice, title, url_id, path, statement, overview, issue, issue_kind, depend, gain, coefficient_cur, video_uri FROM exercices"); err != nil { + if rows, err := DBQuery("SELECT id_exercice, title, url_id, path, statement, overview, headline, issue, issue_kind, depend, gain, coefficient_cur, video_uri FROM exercices"); err != nil { return nil, err } else { defer rows.Close() @@ -82,7 +84,7 @@ func GetExercices() ([]Exercice, error) { var exos = make([]Exercice, 0) for rows.Next() { var e Exercice - if err := rows.Scan(&e.Id, &e.Title, &e.URLId, &e.Path, &e.Statement, &e.Overview, &e.Issue, &e.IssueKind, &e.Depend, &e.Gain, &e.Coefficient, &e.VideoURI); err != nil { + if err := rows.Scan(&e.Id, &e.Title, &e.URLId, &e.Path, &e.Statement, &e.Overview, &e.Headline, &e.Issue, &e.IssueKind, &e.Depend, &e.Gain, &e.Coefficient, &e.VideoURI); err != nil { return nil, err } exos = append(exos, e) @@ -97,7 +99,7 @@ func GetExercices() ([]Exercice, error) { // GetExercices returns the list of all challenges in the Theme. func (t Theme) GetExercices() ([]Exercice, error) { - if rows, err := DBQuery("SELECT id_exercice, title, url_id, path, statement, overview, issue, issue_kind, depend, gain, coefficient_cur, video_uri FROM exercices WHERE id_theme = ?", t.Id); err != nil { + if rows, err := DBQuery("SELECT id_exercice, title, url_id, path, statement, overview, headline, issue, issue_kind, depend, gain, coefficient_cur, video_uri FROM exercices WHERE id_theme = ?", t.Id); err != nil { return nil, err } else { defer rows.Close() @@ -105,7 +107,7 @@ func (t Theme) GetExercices() ([]Exercice, error) { var exos = make([]Exercice, 0) for rows.Next() { var e Exercice - if err := rows.Scan(&e.Id, &e.Title, &e.URLId, &e.Path, &e.Statement, &e.Overview, &e.Issue, &e.IssueKind, &e.Depend, &e.Gain, &e.Coefficient, &e.VideoURI); err != nil { + if err := rows.Scan(&e.Id, &e.Title, &e.URLId, &e.Path, &e.Statement, &e.Overview, &e.Headline, &e.Issue, &e.IssueKind, &e.Depend, &e.Gain, &e.Coefficient, &e.VideoURI); err != nil { return nil, err } exos = append(exos, e) @@ -119,29 +121,29 @@ func (t Theme) GetExercices() ([]Exercice, error) { } // AddExercice creates and fills a new struct Exercice and registers it into the database. -func (t Theme) AddExercice(title string, urlId string, path string, statement string, overview string, depend *Exercice, gain int64, videoURI string) (Exercice, error) { +func (t Theme) AddExercice(title string, urlId string, path string, statement string, overview string, headline string, depend *Exercice, gain int64, videoURI string) (Exercice, error) { var dpd interface{} if depend == nil { dpd = nil } else { dpd = depend.Id } - if res, err := DBExec("INSERT INTO exercices (id_theme, title, url_id, path, statement, overview, issue, depend, gain, video_uri) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", t.Id, title, urlId, path, statement, overview, "", dpd, gain, videoURI); err != nil { + if res, err := DBExec("INSERT INTO exercices (id_theme, title, url_id, path, statement, overview, headline, issue, depend, gain, video_uri) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", t.Id, title, urlId, path, statement, overview, headline, "", dpd, gain, videoURI); err != nil { return Exercice{}, err } else if eid, err := res.LastInsertId(); err != nil { return Exercice{}, err } else { if depend == nil { - return Exercice{eid, title, urlId, path, statement, overview, "", "info", nil, gain, 1.0, videoURI}, nil + return Exercice{eid, title, urlId, path, statement, overview, headline, "", "info", nil, gain, 1.0, videoURI}, nil } else { - return Exercice{eid, title, urlId, path, statement, overview, "", "info", &depend.Id, gain, 1.0, videoURI}, nil + return Exercice{eid, title, urlId, path, statement, overview, headline, "", "info", &depend.Id, gain, 1.0, videoURI}, nil } } } // Update applies modifications back to the database. func (e Exercice) Update() (int64, error) { - if res, err := DBExec("UPDATE exercices SET title = ?, url_id = ?, path = ?, statement = ?, overview = ?, issue = ?, issue_kind = ?, depend = ?, gain = ?, coefficient_cur = ?, video_uri = ? WHERE id_exercice = ?", e.Title, e.URLId, e.Path, e.Statement, e.Overview, e.Issue, e.IssueKind, e.Depend, e.Gain, e.Coefficient, e.VideoURI, e.Id); err != nil { + if res, err := DBExec("UPDATE exercices SET title = ?, url_id = ?, path = ?, statement = ?, overview = ?, headline = ?, issue = ?, issue_kind = ?, depend = ?, gain = ?, coefficient_cur = ?, video_uri = ? WHERE id_exercice = ?", e.Title, e.URLId, e.Path, e.Statement, e.Overview, e.Headline, e.Issue, e.IssueKind, e.Depend, e.Gain, e.Coefficient, e.VideoURI, e.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err diff --git a/libfic/theme.go b/libfic/theme.go index 0b714e30..c578bc85 100644 --- a/libfic/theme.go +++ b/libfic/theme.go @@ -4,18 +4,19 @@ import () // Theme represents a group of challenges, to display to players type Theme struct { - Id int64 `json:"id"` - Name string `json:"name"` - URLId string `json:"urlid"` - Path string `json:"path"` - Authors string `json:"authors,omitempty"` - Intro string `json:"intro,omitempty"` - Image string `json:"image,omitempty"` + Id int64 `json:"id"` + Name string `json:"name"` + URLId string `json:"urlid"` + Path string `json:"path"` + Authors string `json:"authors,omitempty"` + Intro string `json:"intro,omitempty"` + Headline string `json:"headline,omitempty"` + Image string `json:"image,omitempty"` } // GetThemes returns a list of registered Themes from the database. func GetThemes() ([]Theme, error) { - if rows, err := DBQuery("SELECT id_theme, name, url_id, path, authors, intro, image FROM themes"); err != nil { + if rows, err := DBQuery("SELECT id_theme, name, url_id, path, authors, intro, headline, image FROM themes"); err != nil { return nil, err } else { defer rows.Close() @@ -23,7 +24,7 @@ func GetThemes() ([]Theme, error) { var themes = make([]Theme, 0) for rows.Next() { var t Theme - if err := rows.Scan(&t.Id, &t.Name, &t.URLId, &t.Path, &t.Authors, &t.Intro, &t.Image); err != nil { + if err := rows.Scan(&t.Id, &t.Name, &t.URLId, &t.Path, &t.Authors, &t.Intro, &t.Headline, &t.Image); err != nil { return nil, err } themes = append(themes, t) @@ -39,7 +40,7 @@ func GetThemes() ([]Theme, error) { // GetTheme retrieves a Theme from its identifier. func GetTheme(id int64) (Theme, error) { var t Theme - if err := DBQueryRow("SELECT id_theme, name, url_id, path, authors, intro, image FROM themes WHERE id_theme=?", id).Scan(&t.Id, &t.Name, &t.URLId, &t.Path, &t.Authors, &t.Intro, &t.Image); err != nil { + if err := DBQueryRow("SELECT id_theme, name, url_id, path, authors, intro, headline, image FROM themes WHERE id_theme=?", id).Scan(&t.Id, &t.Name, &t.URLId, &t.Path, &t.Authors, &t.Intro, &t.Headline, &t.Image); err != nil { return t, err } @@ -49,7 +50,7 @@ func GetTheme(id int64) (Theme, error) { // GetThemeByName retrieves a Theme from its title func GetThemeByName(name string) (Theme, error) { var t Theme - if err := DBQueryRow("SELECT id_theme, name, url_id, path, authors, intro, image FROM themes WHERE name=?", name).Scan(&t.Id, &t.Name, &t.URLId, &t.Path, &t.Authors, &t.Intro, &t.Image); err != nil { + if err := DBQueryRow("SELECT id_theme, name, url_id, path, authors, intro, headline, image FROM themes WHERE name=?", name).Scan(&t.Id, &t.Name, &t.URLId, &t.Path, &t.Authors, &t.Intro, &t.Headline, &t.Image); err != nil { return t, err } @@ -57,13 +58,13 @@ func GetThemeByName(name string) (Theme, error) { } // CreateTheme creates and fills a new struct Theme and registers it into the database. -func CreateTheme(name string, url_id string, path string, authors string, intro string, image string) (Theme, error) { - if res, err := DBExec("INSERT INTO themes (name, url_id, authors, path, intro, image) VALUES (?, ?, ?, ?, ?, ?)", name, url_id, authors, path, intro, image); err != nil { +func CreateTheme(name string, url_id string, path string, authors string, intro string, headline string, image string) (Theme, error) { + if res, err := DBExec("INSERT INTO themes (name, url_id, authors, path, intro, headline, image) VALUES (?, ?, ?, ?, ?, ?, ?)", name, url_id, authors, path, intro, headline, image); err != nil { return Theme{}, err } else if tid, err := res.LastInsertId(); err != nil { return Theme{}, err } else { - return Theme{tid, name, url_id, path, authors, intro, image}, nil + return Theme{tid, name, url_id, path, authors, intro, headline, image}, nil } } @@ -79,7 +80,7 @@ func (t *Theme) FixURLId() bool { // Update applies modifications back to the database. func (t Theme) Update() (int64, error) { - if res, err := DBExec("UPDATE themes SET name = ?, url_id = ?, authors = ?, path = ?, intro = ?, image = ? WHERE id_theme = ?", t.Name, t.URLId, t.Authors, t.Path, t.Intro, t.Image, t.Id); err != nil { + if res, err := DBExec("UPDATE themes SET name = ?, url_id = ?, authors = ?, path = ?, intro = ?, headline = ?, image = ? WHERE id_theme = ?", t.Name, t.URLId, t.Authors, t.Path, t.Intro, t.Headline, t.Image, t.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err diff --git a/libfic/theme_export.go b/libfic/theme_export.go index 51f61ac3..e9eb2c03 100644 --- a/libfic/theme_export.go +++ b/libfic/theme_export.go @@ -7,13 +7,14 @@ import ( // exportedExercice is a structure representing a challenge, as exposed to players. type exportedExercice struct { - Title string `json:"title"` - URLId string `json:"urlid"` - Tags []string `json:"tags"` - Gain int64 `json:"gain"` - Coeff float64 `json:"curcoeff"` - Solved int64 `json:"solved"` - Tried int64 `json:"tried"` + Title string `json:"title"` + Headline string `json:"headline,omitempty"` + URLId string `json:"urlid"` + Tags []string `json:"tags"` + Gain int64 `json:"gain"` + Coeff float64 `json:"curcoeff"` + Solved int64 `json:"solved"` + Tried int64 `json:"tried"` } // exportedTheme is a structure representing a Theme, as exposed to players. @@ -21,6 +22,7 @@ type exportedTheme struct { Name string `json:"name"` URLId string `json:"urlid"` Authors string `json:"authors"` + Headline string `json:"headline,omitempty"` Intro string `json:"intro"` Image string `json:"image,omitempty"` Exercices map[string]exportedExercice `json:"exercices"` @@ -41,6 +43,7 @@ func ExportThemes() (interface{}, error) { tags, _ := exercice.GetTags() exos[fmt.Sprintf("%d", exercice.Id)] = exportedExercice{ exercice.Title, + exercice.Headline, exercice.URLId, tags, exercice.Gain, @@ -59,6 +62,7 @@ func ExportThemes() (interface{}, error) { theme.Name, theme.URLId, theme.Authors, + theme.Headline, theme.Intro, imgpath, exos,