#120 [sources][nouns] sources for dictionary entries

This commit is contained in:
Avris 2021-01-05 20:11:41 +01:00
parent 6ce8d34415
commit b1b65bd789
10 changed files with 63 additions and 7 deletions

View File

@ -74,6 +74,15 @@
</li> </li>
</ul> </ul>
</small> </small>
<div v-if="s.el.sourcesData.length" class="div-three-columns">
<p><strong><T>sources.referenced</T>:</strong></p>
<ul class="list-unstyled">
<li v-for="source in s.el.sourcesData">
<Source :source="source"/>
</li>
</ul>
</div>
</td> </td>
<td> <td>
<ul class="list-singular"> <ul class="list-singular">
@ -375,4 +384,8 @@
} }
} }
} }
.div-three-columns {
width: 300%;
}
</style> </style>

View File

@ -68,6 +68,10 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<div v-if="$isGranted('sources')" class="form-group">
<label><strong><T>sources.referenced</T>:</strong></label>
<ListInput v-model="form.sources"/>
</div>
<div class="alert alert-info" v-if="form.base"> <div class="alert alert-info" v-if="form.base">
<Icon v="info-circle"/> <Icon v="info-circle"/>
<T>nouns.editing</T> <T>nouns.editing</T>
@ -128,6 +132,7 @@
mascPl: this.config.nouns.pluralsRequired ? [''] : [], mascPl: this.config.nouns.pluralsRequired ? [''] : [],
femPl: this.config.nouns.pluralsRequired ? [''] : [], femPl: this.config.nouns.pluralsRequired ? [''] : [],
neutrPl: this.config.nouns.pluralsRequired ? [''] : [], neutrPl: this.config.nouns.pluralsRequired ? [''] : [],
sources: [],
base: null, base: null,
}, },
submitting: false, submitting: false,
@ -151,6 +156,7 @@
mascPl: this.config.nouns.pluralsRequired ? [''] : [], mascPl: this.config.nouns.pluralsRequired ? [''] : [],
femPl: this.config.nouns.pluralsRequired ? [''] : [], femPl: this.config.nouns.pluralsRequired ? [''] : [],
neutrPl: this.config.nouns.pluralsRequired ? [''] : [], neutrPl: this.config.nouns.pluralsRequired ? [''] : [],
sources: [],
base: null, base: null,
}; };
this.templateVisible = false; this.templateVisible = false;
@ -164,6 +170,7 @@
mascPl: word.mascPl, mascPl: word.mascPl,
femPl: word.femPl, femPl: word.femPl,
neutrPl: word.neutrPl, neutrPl: word.neutrPl,
sources: word.sources,
base: word.id, base: word.id,
} }
this.afterSubmit = false; this.afterSubmit = false;

View File

@ -97,6 +97,7 @@ sources:
key: 'Key' # TODO key: 'Key' # TODO
keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary' # TODO keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary' # TODO
otherVersions: 'In other languages' # TODO otherVersions: 'In other languages' # TODO
referenced: 'Examples of use' # TODO
nouns: nouns:
header: 'Wörterbuch' header: 'Wörterbuch'

View File

@ -97,6 +97,7 @@ sources:
key: 'Key' key: 'Key'
keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary' keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary'
otherVersions: 'In other languages' otherVersions: 'In other languages'
referenced: 'Examples of use'
nouns: nouns:

View File

@ -97,6 +97,7 @@ sources:
key: 'Key' # TODO key: 'Key' # TODO
keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary' # TODO keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary' # TODO
otherVersions: 'In other languages' # TODO otherVersions: 'In other languages' # TODO
referenced: 'Examples of use' # TODO
nouns: nouns:
header: 'Diccionario' header: 'Diccionario'

View File

@ -196,6 +196,7 @@ sources:
key: 'Klucz' key: 'Klucz'
keyInfo: 'Identyfikator do łączenia tekstów między wersjami językowymi i łączenia ze słownikiem' keyInfo: 'Identyfikator do łączenia tekstów między wersjami językowymi i łączenia ze słownikiem'
otherVersions: 'W innych językach' otherVersions: 'W innych językach'
referenced: 'Przykłady użycia'
nouns: nouns:
header: 'Słowniki' header: 'Słowniki'

View File

@ -95,6 +95,7 @@ sources:
key: 'Key' # TODO key: 'Key' # TODO
keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary' # TODO keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary' # TODO
otherVersions: 'In other languages' # TODO otherVersions: 'In other languages' # TODO
referenced: 'Examples of use' # TODO
nouns: nouns:
header: '字典' header: '字典'

View File

@ -0,0 +1,5 @@
-- Up
ALTER TABLE nouns ADD COLUMN sources TEXT NULL DEFAULT NULL;
-- Down

View File

@ -3,7 +3,7 @@ import SQL from 'sql-template-strings';
import {ulid} from "ulid"; import {ulid} from "ulid";
import {createCanvas, loadImage, registerFont} from "canvas"; import {createCanvas, loadImage, registerFont} from "canvas";
import {loadSuml} from "../loader"; import {loadSuml} from "../loader";
import {isTroll} from "../../src/helpers"; import {buildDict, isTroll} from "../../src/helpers";
const translations = loadSuml('translations'); const translations = loadSuml('translations');
@ -23,22 +23,45 @@ const approve = async (db, id) => {
`); `);
} }
const addVersions = async (req, nouns) => {
const keys = new Set();
nouns.filter(s => !!s && s.sources)
.forEach(s => s.sources.split(',').forEach(k => keys.add(`'` + k + `'`)));
const sources = await req.db.all(SQL`
SELECT s.*, u.username AS submitter FROM sources s
LEFT JOIN users u ON s.submitter_id = u.id
WHERE s.locale == ${req.config.locale}
AND s.deleted = 0
AND s.approved >= ${req.isGranted('sources') ? 0 : 1}
AND s.key IN (`.append([...keys].join(',')).append(SQL`)
`));
const sourcesMap = {};
sources.forEach(s => sourcesMap[s.key] = s)
return nouns.map(n => {
n.sourcesData = (n.sources ? n.sources.split(',') : []).map(s => sourcesMap[s]);
return n;
});
};
const router = Router(); const router = Router();
router.get('/nouns', async (req, res) => { router.get('/nouns', async (req, res) => {
return res.json(await req.db.all(SQL` return res.json(await addVersions(req, await req.db.all(SQL`
SELECT n.*, u.username AS author FROM nouns n SELECT n.*, u.username AS author FROM nouns n
LEFT JOIN users u ON n.author_id = u.id LEFT JOIN users u ON n.author_id = u.id
WHERE n.locale = ${req.config.locale} WHERE n.locale = ${req.config.locale}
AND n.deleted = 0 AND n.deleted = 0
AND n.approved >= ${req.isGranted('nouns') ? 0 : 1} AND n.approved >= ${req.isGranted('nouns') ? 0 : 1}
ORDER BY n.approved, n.masc ORDER BY n.approved, n.masc
`)); `)));
}); });
router.get('/nouns/search/:term', async (req, res) => { router.get('/nouns/search/:term', async (req, res) => {
const term = '%' + req.params.term + '%'; const term = '%' + req.params.term + '%';
return res.json(await req.db.all(SQL` return res.json(await addVersions(req, await req.db.all(SQL`
SELECT n.*, u.username AS author FROM nouns n SELECT n.*, u.username AS author FROM nouns n
LEFT JOIN users u ON n.author_id = u.id LEFT JOIN users u ON n.author_id = u.id
WHERE n.locale = ${req.config.locale} WHERE n.locale = ${req.config.locale}
@ -46,7 +69,7 @@ router.get('/nouns/search/:term', async (req, res) => {
AND n.deleted = 0 AND n.deleted = 0
AND (n.masc like ${term} OR n.fem like ${term} OR n.neutr like ${term} OR n.mascPl like ${term} OR n.femPl like ${term} OR n.neutrPl like ${term}) AND (n.masc like ${term} OR n.fem like ${term} OR n.neutr like ${term} OR n.mascPl like ${term} OR n.femPl like ${term} OR n.neutrPl like ${term})
ORDER BY n.approved, n.masc ORDER BY n.approved, n.masc
`)); `)));
}); });
router.post('/nouns/submit', async (req, res) => { router.post('/nouns/submit', async (req, res) => {
@ -56,11 +79,12 @@ router.post('/nouns/submit', async (req, res) => {
const id = ulid(); const id = ulid();
await req.db.get(SQL` await req.db.get(SQL`
INSERT INTO nouns (id, masc, fem, neutr, mascPl, femPl, neutrPl, approved, base_id, locale, author_id) INSERT INTO nouns (id, masc, fem, neutr, mascPl, femPl, neutrPl, sources, approved, base_id, locale, author_id)
VALUES ( VALUES (
${id}, ${id},
${req.body.masc.join('|')}, ${req.body.fem.join('|')}, ${req.body.neutr.join('|')}, ${req.body.masc.join('|')}, ${req.body.fem.join('|')}, ${req.body.neutr.join('|')},
${req.body.mascPl.join('|')}, ${req.body.femPl.join('|')}, ${req.body.neutrPl.join('|')}, ${req.body.mascPl.join('|')}, ${req.body.femPl.join('|')}, ${req.body.neutrPl.join('|')},
${req.body.sources || null},
0, ${req.body.base}, ${req.config.locale}, ${req.user ? req.user.id : null} 0, ${req.body.base}, ${req.config.locale}, ${req.user ? req.user.id : null}
) )
`); `);

View File

@ -554,7 +554,7 @@ export class PronounLibrary {
} }
export class Noun { export class Noun {
constructor({id, masc, fem, neutr, mascPl, femPl, neutrPl, approved = true, base_id = null, author = null}) { constructor({id, masc, fem, neutr, mascPl, femPl, neutrPl, sources = null, sourcesData = [], approved = true, base_id = null, author = null}) {
this.id = id; this.id = id;
this.masc = masc.split('|'); this.masc = masc.split('|');
this.fem = fem.split('|'); this.fem = fem.split('|');
@ -562,6 +562,8 @@ export class Noun {
this.mascPl = mascPl ? mascPl.split('|') : []; this.mascPl = mascPl ? mascPl.split('|') : [];
this.femPl = femPl ? femPl.split('|') : []; this.femPl = femPl ? femPl.split('|') : [];
this.neutrPl = neutrPl ? neutrPl.split('|') : []; this.neutrPl = neutrPl ? neutrPl.split('|') : [];
this.sources = sources ? sources.split(',') : [];
this.sourcesData = sourcesData.map(s => new Source(s));
this.approved = !!approved; this.approved = !!approved;
this.base = base_id; this.base = base_id;
this.author = author; this.author = author;