sync: Add partner's info
This commit is contained in:
parent
f2bf07fd28
commit
74d77dce9f
@ -1405,7 +1405,7 @@ angular.module("FICApp")
|
|||||||
})
|
})
|
||||||
.controller("ThemeController", function($scope, Theme, $routeParams, $location, $rootScope, $http) {
|
.controller("ThemeController", function($scope, Theme, $routeParams, $location, $rootScope, $http) {
|
||||||
$scope.theme = Theme.get({ themeId: $routeParams.themeId });
|
$scope.theme = Theme.get({ themeId: $routeParams.themeId });
|
||||||
$scope.fields = ["name", "urlid", "authors", "headline", "intro", "image"];
|
$scope.fields = ["name", "urlid", "authors", "headline", "intro", "image", "partner_txt", "partner_href", "partner_img"];
|
||||||
|
|
||||||
$scope.saveTheme = function() {
|
$scope.saveTheme = function() {
|
||||||
if (this.theme.id) {
|
if (this.theme.id) {
|
||||||
|
@ -153,6 +153,22 @@ func BuildTheme(i Importer, tdir string) (th *fic.Theme, errs []string) {
|
|||||||
errs = append(errs, fmt.Sprintf("%q: heading.jpg: No such file", tdir))
|
errs = append(errs, fmt.Sprintf("%q: heading.jpg: No such file", tdir))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if i.exists(path.Join(tdir, "partner.jpg")) {
|
||||||
|
th.PartnerImage = path.Join(tdir, "partner.jpg")
|
||||||
|
} else if i.exists(path.Join(tdir, "partner.png")) {
|
||||||
|
th.PartnerImage = path.Join(tdir, "partner.png")
|
||||||
|
}
|
||||||
|
|
||||||
|
if i.exists(path.Join(tdir, "partner.txt")) {
|
||||||
|
if txt, err := getFileContent(i, path.Join(tdir, "partner.txt")); err != nil {
|
||||||
|
errs = append(errs, fmt.Sprintf("%q: unable to get partner's text: %s", th.Name, err))
|
||||||
|
} else {
|
||||||
|
th.PartnerText, err = ProcessMarkdown(i, txt, tdir)
|
||||||
|
if err != nil {
|
||||||
|
errs = append(errs, fmt.Sprintf("%q: partner.txt: an error occurs during markdown formating: %s", tdir, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,6 +205,16 @@ func SyncThemes(i Importer) []string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(btheme.PartnerImage) > 0 {
|
||||||
|
if _, err := i.importFile(btheme.PartnerImage,
|
||||||
|
func(filePath string, origin string) (interface{}, error) {
|
||||||
|
btheme.PartnerImage = strings.TrimPrefix(filePath, fic.FilesDir)
|
||||||
|
return nil, nil
|
||||||
|
}); err != nil {
|
||||||
|
errs = append(errs, fmt.Sprintf("%q: unable to import partner image: %s", tdir, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var theme fic.Theme
|
var theme fic.Theme
|
||||||
if theme, err = fic.GetThemeByPath(btheme.Path); err != nil {
|
if theme, err = fic.GetThemeByPath(btheme.Path); err != nil {
|
||||||
if _, err := fic.CreateTheme(*btheme); err != nil {
|
if _, err := fic.CreateTheme(*btheme); err != nil {
|
||||||
|
@ -12,7 +12,13 @@
|
|||||||
import {
|
import {
|
||||||
Alert,
|
Alert,
|
||||||
Badge,
|
Badge,
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
CardBody,
|
||||||
|
CardTitle,
|
||||||
|
Col,
|
||||||
Icon,
|
Icon,
|
||||||
|
Row,
|
||||||
} from 'sveltestrap';
|
} from 'sveltestrap';
|
||||||
|
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
@ -23,12 +29,37 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if theme && theme.exercices}
|
{#if theme && theme.exercices}
|
||||||
<div class="card niceborder text-indent mt-2 mb-4">
|
<Card class="niceborder text-indent mt-2 mb-4">
|
||||||
|
|
||||||
<div class="card-body bg-dark text-light">
|
<CardBody class="bg-dark text-light">
|
||||||
<p class="mt-4 mx-3 card-text lead text-justify">{@html theme.headline}</p>
|
<Row>
|
||||||
<p class="mb-4 mx-3 card-text text-justify">{@html theme.intro}</p>
|
<Col>
|
||||||
</div>
|
<p class="mt-4 mx-3 card-text lead text-justify">{@html theme.headline}</p>
|
||||||
|
<p class="mb-4 mx-3 card-text text-justify">{@html theme.intro}</p>
|
||||||
|
</Col>
|
||||||
|
{#if theme.partner_txt || theme.partner_img || theme.partner_href}
|
||||||
|
<Col md="2" lg="3" class="d-none d-md-block">
|
||||||
|
<Card class="pt-3 px-3">
|
||||||
|
{#if theme.partner_img}
|
||||||
|
<img src="{theme.partner_img}" class="card-img-top">
|
||||||
|
{/if}
|
||||||
|
{#if theme.partner_txt || theme.partner_href}
|
||||||
|
<CardBody class="p-0 mt-3">
|
||||||
|
{#if theme.partner_txt}
|
||||||
|
{@html theme.partner_txt}
|
||||||
|
{/if}
|
||||||
|
{#if theme.partner_href}
|
||||||
|
<Button tag="a" color="primary" href="{theme.partner_href}">
|
||||||
|
Visiter le site
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
|
</CardBody>
|
||||||
|
{/if}
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
{/if}
|
||||||
|
</Row>
|
||||||
|
</CardBody>
|
||||||
|
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
{#each Object.keys(theme.exercices) as k, index}
|
{#each Object.keys(theme.exercices) as k, index}
|
||||||
@ -88,7 +119,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</Card>
|
||||||
{:else}
|
{:else}
|
||||||
<Alert color="danger" fade={false}>
|
<Alert color="danger" fade={false}>
|
||||||
<Icon name="dash-circle-fill" />
|
<Icon name="dash-circle-fill" />
|
||||||
|
@ -85,7 +85,10 @@ CREATE TABLE IF NOT EXISTS themes(
|
|||||||
headline TEXT NOT NULL,
|
headline TEXT NOT NULL,
|
||||||
intro TEXT NOT NULL,
|
intro TEXT NOT NULL,
|
||||||
image VARCHAR(255) NOT NULL,
|
image VARCHAR(255) NOT NULL,
|
||||||
authors TEXT NOT NULL
|
authors TEXT NOT NULL,
|
||||||
|
partner_img VARCHAR(255) NOT NULL,
|
||||||
|
partner_href VARCHAR(255) NOT NULL,
|
||||||
|
partner_text TEXT NOT NULL
|
||||||
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
|
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
|
||||||
`); err != nil {
|
`); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -4,24 +4,27 @@ import ()
|
|||||||
|
|
||||||
// Theme represents a group of challenges, to display to players
|
// Theme represents a group of challenges, to display to players
|
||||||
type Theme struct {
|
type Theme struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
URLId string `json:"urlid"`
|
URLId string `json:"urlid"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Authors string `json:"authors,omitempty"`
|
Authors string `json:"authors,omitempty"`
|
||||||
Intro string `json:"intro,omitempty"`
|
Intro string `json:"intro,omitempty"`
|
||||||
Headline string `json:"headline,omitempty"`
|
Headline string `json:"headline,omitempty"`
|
||||||
Image string `json:"image,omitempty"`
|
Image string `json:"image,omitempty"`
|
||||||
|
PartnerImage string `json:"partner_img,omitempty"`
|
||||||
|
PartnerLink string `json:"partner_href,omitempty"`
|
||||||
|
PartnerText string `json:"partner_txt,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CmpTheme returns true if given Themes are identicals.
|
// CmpTheme returns true if given Themes are identicals.
|
||||||
func CmpTheme(t1 Theme, t2 Theme) bool {
|
func CmpTheme(t1 Theme, t2 Theme) bool {
|
||||||
return !(t1.Name != t2.Name || t1.URLId != t2.URLId || t1.Path != t2.Path || t1.Authors != t2.Authors || t1.Intro != t2.Intro || t1.Headline != t2.Headline || t1.Image != t2.Image)
|
return !(t1.Name != t2.Name || t1.URLId != t2.URLId || t1.Path != t2.Path || t1.Authors != t2.Authors || t1.Intro != t2.Intro || t1.Headline != t2.Headline || t1.Image != t2.Image || t1.PartnerImage != t2.PartnerImage || t1.PartnerLink != t2.PartnerLink || t1.PartnerText != t2.PartnerText)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetThemes returns a list of registered Themes from the database.
|
// GetThemes returns a list of registered Themes from the database.
|
||||||
func GetThemes() ([]Theme, error) {
|
func GetThemes() ([]Theme, error) {
|
||||||
if rows, err := DBQuery("SELECT id_theme, name, url_id, path, authors, intro, headline, image FROM themes"); err != nil {
|
if rows, err := DBQuery("SELECT id_theme, name, url_id, path, authors, intro, headline, image, partner_img, partner_href, partner_text FROM themes"); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
@ -29,7 +32,7 @@ func GetThemes() ([]Theme, error) {
|
|||||||
var themes = make([]Theme, 0)
|
var themes = make([]Theme, 0)
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var t Theme
|
var t Theme
|
||||||
if err := rows.Scan(&t.Id, &t.Name, &t.URLId, &t.Path, &t.Authors, &t.Intro, &t.Headline, &t.Image); err != nil {
|
if err := rows.Scan(&t.Id, &t.Name, &t.URLId, &t.Path, &t.Authors, &t.Intro, &t.Headline, &t.Image, &t.PartnerImage, &t.PartnerLink, &t.PartnerText); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
themes = append(themes, t)
|
themes = append(themes, t)
|
||||||
@ -45,7 +48,7 @@ func GetThemes() ([]Theme, error) {
|
|||||||
// GetTheme retrieves a Theme from its identifier.
|
// GetTheme retrieves a Theme from its identifier.
|
||||||
func GetTheme(id int64) (Theme, error) {
|
func GetTheme(id int64) (Theme, error) {
|
||||||
var t Theme
|
var t Theme
|
||||||
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 {
|
if err := DBQueryRow("SELECT id_theme, name, url_id, path, authors, intro, headline, image, partner_img, partner_href, partner_text FROM themes WHERE id_theme=?", id).Scan(&t.Id, &t.Name, &t.URLId, &t.Path, &t.Authors, &t.Intro, &t.Headline, &t.Image, &t.PartnerImage, &t.PartnerLink, &t.PartnerText); err != nil {
|
||||||
return t, err
|
return t, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +58,7 @@ func GetTheme(id int64) (Theme, error) {
|
|||||||
// GetThemeByName retrieves a Theme from its title
|
// GetThemeByName retrieves a Theme from its title
|
||||||
func GetThemeByName(name string) (Theme, error) {
|
func GetThemeByName(name string) (Theme, error) {
|
||||||
var t Theme
|
var t Theme
|
||||||
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 {
|
if err := DBQueryRow("SELECT id_theme, name, url_id, path, authors, intro, headline, image, partner_img, partner_text FROM themes WHERE name=?", name).Scan(&t.Id, &t.Name, &t.URLId, &t.Path, &t.Authors, &t.Intro, &t.Headline, &t.Image, &t.PartnerImage, &t.PartnerText); err != nil {
|
||||||
return t, err
|
return t, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +68,7 @@ func GetThemeByName(name string) (Theme, error) {
|
|||||||
// GetThemeByPath retrieves a Theme from its dirname
|
// GetThemeByPath retrieves a Theme from its dirname
|
||||||
func GetThemeByPath(dirname string) (Theme, error) {
|
func GetThemeByPath(dirname string) (Theme, error) {
|
||||||
var t Theme
|
var t Theme
|
||||||
if err := DBQueryRow("SELECT id_theme, name, url_id, path, authors, intro, headline, image FROM themes WHERE path=?", dirname).Scan(&t.Id, &t.Name, &t.URLId, &t.Path, &t.Authors, &t.Intro, &t.Headline, &t.Image); err != nil {
|
if err := DBQueryRow("SELECT id_theme, name, url_id, path, authors, intro, headline, image, partner_img, partner_href, partner_text FROM themes WHERE path=?", dirname).Scan(&t.Id, &t.Name, &t.URLId, &t.Path, &t.Authors, &t.Intro, &t.Headline, &t.Image, &t.PartnerImage, &t.PartnerLink, &t.PartnerText); err != nil {
|
||||||
return t, err
|
return t, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +77,7 @@ func GetThemeByPath(dirname string) (Theme, error) {
|
|||||||
|
|
||||||
// CreateTheme creates and fills a new struct Theme and registers it into the database.
|
// CreateTheme creates and fills a new struct Theme and registers it into the database.
|
||||||
func CreateTheme(theme Theme) (Theme, error) {
|
func CreateTheme(theme Theme) (Theme, error) {
|
||||||
if res, err := DBExec("INSERT INTO themes (name, url_id, authors, path, intro, headline, image) VALUES (?, ?, ?, ?, ?, ?, ?)", theme.Name, theme.URLId, theme.Authors, theme.Path, theme.Intro, theme.Headline, theme.Image); err != nil {
|
if res, err := DBExec("INSERT INTO themes (name, url_id, authors, path, intro, headline, image, partner_img, partner_href, partner_text) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", theme.Name, theme.URLId, theme.Authors, theme.Path, theme.Intro, theme.Headline, theme.Image, theme.PartnerImage, theme.PartnerLink, theme.PartnerText); err != nil {
|
||||||
return Theme{}, err
|
return Theme{}, err
|
||||||
} else if theme.Id, err = res.LastInsertId(); err != nil {
|
} else if theme.Id, err = res.LastInsertId(); err != nil {
|
||||||
return Theme{}, err
|
return Theme{}, err
|
||||||
@ -95,7 +98,7 @@ func (t *Theme) FixURLId() bool {
|
|||||||
|
|
||||||
// Update applies modifications back to the database.
|
// Update applies modifications back to the database.
|
||||||
func (t Theme) Update() (int64, error) {
|
func (t Theme) Update() (int64, error) {
|
||||||
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 {
|
if res, err := DBExec("UPDATE themes SET name = ?, url_id = ?, authors = ?, path = ?, intro = ?, headline = ?, image = ?, partner_img = ?, partner_href = ?, partner_text = ? WHERE id_theme = ?", t.Name, t.URLId, t.Authors, t.Path, t.Intro, t.Headline, t.Image, t.PartnerImage, t.PartnerLink, t.PartnerText, t.Id); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
} else if nb, err := res.RowsAffected(); err != nil {
|
} else if nb, err := res.RowsAffected(); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -20,13 +20,16 @@ type exportedExercice struct {
|
|||||||
|
|
||||||
// exportedTheme is a structure representing a Theme, as exposed to players.
|
// exportedTheme is a structure representing a Theme, as exposed to players.
|
||||||
type exportedTheme struct {
|
type exportedTheme struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
URLId string `json:"urlid"`
|
URLId string `json:"urlid"`
|
||||||
Authors string `json:"authors"`
|
Authors string `json:"authors"`
|
||||||
Headline string `json:"headline,omitempty"`
|
Headline string `json:"headline,omitempty"`
|
||||||
Intro string `json:"intro"`
|
Intro string `json:"intro"`
|
||||||
Image string `json:"image,omitempty"`
|
Image string `json:"image,omitempty"`
|
||||||
Exercices map[string]exportedExercice `json:"exercices"`
|
PartnerImage string `json:"partner_img,omitempty"`
|
||||||
|
PartnerLink string `json:"partner_href,omitempty"`
|
||||||
|
PartnerText string `json:"partner_txt,omitempty"`
|
||||||
|
Exercices map[string]exportedExercice `json:"exercices"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exportedthemes exports themes from the database, to be displayed to players.
|
// Exportedthemes exports themes from the database, to be displayed to players.
|
||||||
@ -59,6 +62,11 @@ func ExportThemes() (interface{}, error) {
|
|||||||
imgpath = path.Join(FilesDir, theme.Image)
|
imgpath = path.Join(FilesDir, theme.Image)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partnerImgpath := ""
|
||||||
|
if len(theme.PartnerImage) > 0 {
|
||||||
|
partnerImgpath = path.Join(FilesDir, theme.PartnerImage)
|
||||||
|
}
|
||||||
|
|
||||||
ret[fmt.Sprintf("%d", theme.Id)] = exportedTheme{
|
ret[fmt.Sprintf("%d", theme.Id)] = exportedTheme{
|
||||||
theme.Name,
|
theme.Name,
|
||||||
theme.URLId,
|
theme.URLId,
|
||||||
@ -66,6 +74,9 @@ func ExportThemes() (interface{}, error) {
|
|||||||
theme.Headline,
|
theme.Headline,
|
||||||
strings.Replace(theme.Intro, "$FILES$", FilesDir, -1),
|
strings.Replace(theme.Intro, "$FILES$", FilesDir, -1),
|
||||||
imgpath,
|
imgpath,
|
||||||
|
partnerImgpath,
|
||||||
|
theme.PartnerLink,
|
||||||
|
theme.PartnerText,
|
||||||
exos,
|
exos,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user