@rr0/cms 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/RR0Build.js +4 -2
- package/dist/people/PeopleDirectoryStep.d.ts +3 -1
- package/dist/people/PeopleDirectoryStep.js +3 -2
- package/dist/people/PeopleDirectoryStepFactory.d.ts +3 -1
- package/dist/people/PeopleDirectoryStepFactory.js +14 -13
- package/dist/people/PeopleFactory.d.ts +2 -2
- package/dist/people/PeopleFactory.js +27 -16
- package/dist/people/PeopleFactory.test.js +24 -76
- package/dist/people/PeopleHtmlRenderer.d.ts +9 -0
- package/dist/people/PeopleHtmlRenderer.js +93 -0
- package/dist/people/PeopleJson.d.ts +17 -22
- package/dist/people/PeopleJson.js +1 -19
- package/dist/people/PeopleRegexReplaceCommand.test.js +3 -1
- package/dist/people/PeopleReplacer.d.ts +3 -1
- package/dist/people/PeopleReplacer.js +3 -2
- package/dist/people/PeopleReplacer.test.js +7 -2
- package/dist/people/PeopleReplacerFactory.d.ts +3 -1
- package/dist/people/PeopleReplacerFactory.js +3 -2
- package/dist/people/PeopleService.d.ts +0 -4
- package/dist/people/PeopleService.js +2 -96
- package/dist/people/PeopleService.test.d.ts +1 -0
- package/dist/people/PeopleService.test.js +82 -0
- package/dist/place/PlaceRenderer.js +4 -0
- package/dist/search/SearchComponent.d.mts +6 -0
- package/dist/search/SearchComponent.mjs +17 -1
- package/dist/search/SearchIndexStep.js +3 -1
- package/dist/time/datasource/ChronologyReplacer.d.ts +1 -1
- package/dist/time/datasource/ChronologyReplacer.js +6 -2
- package/dist/time/datasource/baseovnifrance/{BaseOvniFranceCaseSummaryMapper.d.ts → BaseOvniFranceCaseSummaryCsvMapper.d.ts} +1 -1
- package/dist/time/datasource/baseovnifrance/{BaseOvniFranceCaseSummaryMapper.js → BaseOvniFranceCaseSummaryCsvMapper.js} +1 -1
- package/dist/time/datasource/baseovnifrance/BaseOvniFranceCsv.test.js +2 -2
- package/dist/time/datasource/baseovnifrance/BaseOvniFranceHttpDatasource.js +1 -1
- package/dist/time/datasource/baseovnifrance/index.d.ts +1 -1
- package/dist/time/datasource/baseovnifrance/index.js +1 -1
- package/dist/time/datasource/rr0/RR0HttpDatasource.js +1 -1
- package/dist/time/datasource/rr0/RR0Mapping.d.ts +1 -1
- package/dist/time/datasource/rr0/RR0Mapping.js +1 -1
- package/dist/time/datasource/rr0/RR0TestCases.js +1 -1
- package/package.json +3 -3
- package/dist/place/NamedPlace.d.ts +0 -5
- package/dist/place/NamedPlace.js +0 -7
package/dist/RR0Build.js
CHANGED
|
@@ -31,6 +31,7 @@ import { writeFile } from "@javarome/fileutil";
|
|
|
31
31
|
import { AllDataService, EventDataFactory, RR0EventFactory, TypedDataFactory } from "@rr0/data";
|
|
32
32
|
import { GooglePlaceService } from "@rr0/place";
|
|
33
33
|
import { GeipanRR0Mapping } from "./org/eu/fr/cnes/geipan/geipan/GeipanRR0Mapping";
|
|
34
|
+
import { PeopleHtmlRenderer } from "./people/PeopleHtmlRenderer";
|
|
34
35
|
const outputFunc = async (context, outFile) => {
|
|
35
36
|
try {
|
|
36
37
|
if (context.file instanceof HtmlFileContents) {
|
|
@@ -100,7 +101,8 @@ export class RR0Build {
|
|
|
100
101
|
const ufoCaseDirectoryFile = this.options.ufoCaseDirectoryFile;
|
|
101
102
|
const ufoCasesExclusions = this.options.ufoCasesExclusions;
|
|
102
103
|
const ufoCasesStep = new CaseDirectoryStep(caseService, caseService.files, ufoCasesExclusions, ufoCaseDirectoryFile, outputFunc, config);
|
|
103
|
-
const
|
|
104
|
+
const peopleRenderer = new PeopleHtmlRenderer();
|
|
105
|
+
const peopleDirectoryFactory = new PeopleDirectoryStepFactory(outputFunc, config, peopleService, peopleRenderer, this.options.directoryExcluded);
|
|
104
106
|
const directoryOptions = this.options.directoryOptions;
|
|
105
107
|
for (const directoryOption in directoryOptions) {
|
|
106
108
|
directoryOptions[directoryOption] = directoryOptions[directoryOption];
|
|
@@ -173,7 +175,7 @@ export class RR0Build {
|
|
|
173
175
|
new ClassDomReplaceCommand(sourceReplacerFactory, "source"),
|
|
174
176
|
new DomReplaceCommand("time", new TimeReplacerFactory(timeReplacer)),
|
|
175
177
|
new DomReplaceCommand("code", new CodeReplacerFactory()),
|
|
176
|
-
new ClassDomReplaceCommand(new PeopleReplacerFactory(peopleService), "people"),
|
|
178
|
+
new ClassDomReplaceCommand(new PeopleReplacerFactory(peopleService, peopleRenderer), "people"),
|
|
177
179
|
new ClassDomReplaceCommand(new PlaceReplacerFactory(), "place"),
|
|
178
180
|
new ClassDomReplaceCommand(new WitnessReplacerFactory(), "temoin", "temoin1", "temoin2", "temoin3"),
|
|
179
181
|
new ClassDomReplaceCommand(noteReplacerFactory, "note"),
|
|
@@ -4,6 +4,7 @@ import { HtmlRR0Context } from "../RR0Context.js";
|
|
|
4
4
|
import { DirectoryStep, FileWriteConfig, OutputFunc } from "ssg-api";
|
|
5
5
|
import { PeopleService } from "./PeopleService.js";
|
|
6
6
|
import { CountryCode } from "../org/country/CountryCode.js";
|
|
7
|
+
import { PeopleHtmlRenderer } from "./PeopleHtmlRenderer";
|
|
7
8
|
export type PeopleFilter = (p: People) => boolean;
|
|
8
9
|
export declare function peopleOccupationFilter(filterOccupations: Occupation[]): PeopleFilter;
|
|
9
10
|
/**
|
|
@@ -12,8 +13,9 @@ export declare function peopleOccupationFilter(filterOccupations: Occupation[]):
|
|
|
12
13
|
export declare class PeopleDirectoryStep extends DirectoryStep {
|
|
13
14
|
protected outputFunc: OutputFunc;
|
|
14
15
|
protected service: PeopleService;
|
|
16
|
+
protected renderer: PeopleHtmlRenderer;
|
|
15
17
|
protected filter: PeopleFilter;
|
|
16
|
-
constructor(name: string, rootDirs: string[], excludedDirs: string[], templateFileName: string, outputFunc: OutputFunc, config: FileWriteConfig, service: PeopleService, filter?: PeopleFilter);
|
|
18
|
+
constructor(name: string, rootDirs: string[], excludedDirs: string[], templateFileName: string, outputFunc: OutputFunc, config: FileWriteConfig, service: PeopleService, renderer: PeopleHtmlRenderer, filter?: PeopleFilter);
|
|
17
19
|
protected processDirs(context: HtmlRR0Context, dirNames: string[]): Promise<void>;
|
|
18
20
|
protected toList(context: HtmlRR0Context, peopleList: People[], pseudoPeopleList: People[], allCountries: Set<CountryCode>, occupations: Set<Occupation>): HTMLUListElement;
|
|
19
21
|
protected toListItem(context: HtmlRR0Context, people: People, pseudoPeopleList: People[], allCountries: Set<CountryCode>, occupations: Set<Occupation>): HTMLLIElement;
|
|
@@ -10,10 +10,11 @@ export function peopleOccupationFilter(filterOccupations) {
|
|
|
10
10
|
* Scan directories for people information, then populates a template with collected data.
|
|
11
11
|
*/
|
|
12
12
|
export class PeopleDirectoryStep extends DirectoryStep {
|
|
13
|
-
constructor(name, rootDirs, excludedDirs, templateFileName, outputFunc, config, service, filter = (_people) => true) {
|
|
13
|
+
constructor(name, rootDirs, excludedDirs, templateFileName, outputFunc, config, service, renderer, filter = (_people) => true) {
|
|
14
14
|
super({ rootDirs, excludedDirs, templateFileName, getOutputPath: config.getOutputPath }, name);
|
|
15
15
|
this.outputFunc = outputFunc;
|
|
16
16
|
this.service = service;
|
|
17
|
+
this.renderer = renderer;
|
|
17
18
|
this.filter = filter;
|
|
18
19
|
}
|
|
19
20
|
async processDirs(context, dirNames) {
|
|
@@ -70,7 +71,7 @@ export class PeopleDirectoryStep extends DirectoryStep {
|
|
|
70
71
|
return ul;
|
|
71
72
|
}
|
|
72
73
|
toListItem(context, people, pseudoPeopleList, allCountries, occupations) {
|
|
73
|
-
const ref = this.
|
|
74
|
+
const ref = this.renderer.renderLink(context, people, pseudoPeopleList, allCountries, occupations
|
|
74
75
|
/*this.filter*/ // TODO: Restore removal of already-known (as from people occupation subset) occupation
|
|
75
76
|
);
|
|
76
77
|
const item = context.file.document.createElement("li");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { FileWriteConfig, OutputFunc } from "ssg-api";
|
|
2
2
|
import { PeopleService } from "./PeopleService.js";
|
|
3
3
|
import { PeopleDirectoryStep } from "./PeopleDirectoryStep.js";
|
|
4
|
+
import { PeopleHtmlRenderer } from "./PeopleHtmlRenderer";
|
|
4
5
|
export type PeopleDirectoryStepOptions = {
|
|
5
6
|
root: string;
|
|
6
7
|
scientists?: string;
|
|
@@ -21,8 +22,9 @@ export declare class PeopleDirectoryStepFactory {
|
|
|
21
22
|
protected outputFunc: OutputFunc;
|
|
22
23
|
protected config: FileWriteConfig;
|
|
23
24
|
protected service: PeopleService;
|
|
25
|
+
protected renderer: PeopleHtmlRenderer;
|
|
24
26
|
protected excludedDirs: string[];
|
|
25
|
-
constructor(outputFunc: OutputFunc, config: FileWriteConfig, service: PeopleService, excludedDirs: string[]);
|
|
27
|
+
constructor(outputFunc: OutputFunc, config: FileWriteConfig, service: PeopleService, renderer: PeopleHtmlRenderer, excludedDirs: string[]);
|
|
26
28
|
create(options: PeopleDirectoryStepOptions): Promise<PeopleDirectoryStep[]>;
|
|
27
29
|
createLetters(): Promise<PeopleDirectoryStep[]>;
|
|
28
30
|
createAll(dirs: string[], templateFileName: string): PeopleDirectoryStep;
|
|
@@ -7,10 +7,11 @@ import path from "path";
|
|
|
7
7
|
* Scan directories for people information, then populates a template with collected data.
|
|
8
8
|
*/
|
|
9
9
|
export class PeopleDirectoryStepFactory {
|
|
10
|
-
constructor(outputFunc, config, service, excludedDirs) {
|
|
10
|
+
constructor(outputFunc, config, service, renderer, excludedDirs) {
|
|
11
11
|
this.outputFunc = outputFunc;
|
|
12
12
|
this.config = config;
|
|
13
13
|
this.service = service;
|
|
14
|
+
this.renderer = renderer;
|
|
14
15
|
this.excludedDirs = excludedDirs;
|
|
15
16
|
}
|
|
16
17
|
async create(options) {
|
|
@@ -66,46 +67,46 @@ export class PeopleDirectoryStepFactory {
|
|
|
66
67
|
for (const peopleLetterFile of peopleLetterFiles) {
|
|
67
68
|
const c = peopleLetterFile.charAt(peopleLetterFile.length - 1);
|
|
68
69
|
const peopleDir = `people/${c}/`;
|
|
69
|
-
const peopleDirectoryStep = new PeopleDirectoryStep(`directory of people with name starting with "${c}"`, [peopleDir], [], path.join(peopleDir, "index.html"), this.outputFunc, this.config, this.service, (p) => p.dirName.startsWith(peopleDir));
|
|
70
|
+
const peopleDirectoryStep = new PeopleDirectoryStep(`directory of people with name starting with "${c}"`, [peopleDir], [], path.join(peopleDir, "index.html"), this.outputFunc, this.config, this.service, this.renderer, (p) => p.dirName.startsWith(peopleDir));
|
|
70
71
|
letterDirectorySteps.push(peopleDirectoryStep);
|
|
71
72
|
}
|
|
72
73
|
return letterDirectorySteps;
|
|
73
74
|
}
|
|
74
75
|
createAll(dirs, templateFileName) {
|
|
75
|
-
return new PeopleDirectoryStep("all people directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service);
|
|
76
|
+
return new PeopleDirectoryStep("all people directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, this.renderer);
|
|
76
77
|
}
|
|
77
78
|
createMilitary(dirs, templateFileName) {
|
|
78
|
-
return new PeopleDirectoryStep("military people directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, peopleOccupationFilter([Occupation.military]));
|
|
79
|
+
return new PeopleDirectoryStep("military people directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, this.renderer, peopleOccupationFilter([Occupation.military]));
|
|
79
80
|
}
|
|
80
81
|
createPoliticians(dirs, templateFileName, rulersTemplateFileName) {
|
|
81
82
|
const steps = [
|
|
82
|
-
new PeopleDirectoryStep("politicians directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, peopleOccupationFilter([Occupation.politician]))
|
|
83
|
+
new PeopleDirectoryStep("politicians directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, this.renderer, peopleOccupationFilter([Occupation.politician]))
|
|
83
84
|
];
|
|
84
85
|
if (rulersTemplateFileName) {
|
|
85
|
-
steps.push(new PeopleDirectoryStep("politician leaders directories", dirs, this.excludedDirs, rulersTemplateFileName, this.outputFunc, this.config, this.service, peopleOccupationFilter([Occupation.leader])));
|
|
86
|
+
steps.push(new PeopleDirectoryStep("politician leaders directories", dirs, this.excludedDirs, rulersTemplateFileName, this.outputFunc, this.config, this.service, this.renderer, peopleOccupationFilter([Occupation.leader])));
|
|
86
87
|
}
|
|
87
88
|
return steps;
|
|
88
89
|
}
|
|
89
90
|
createSoftwareEngineers(dirs, templateFileName) {
|
|
90
|
-
return new PeopleDirectoryStep("software engineers directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, peopleOccupationFilter([Occupation.softwareEngineer]));
|
|
91
|
+
return new PeopleDirectoryStep("software engineers directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, this.renderer, peopleOccupationFilter([Occupation.softwareEngineer]));
|
|
91
92
|
}
|
|
92
93
|
createPilots(dirs, templateFileName) {
|
|
93
|
-
return new PeopleDirectoryStep("pilots directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, peopleOccupationFilter([Occupation.astronaut, Occupation.pilot]));
|
|
94
|
+
return new PeopleDirectoryStep("pilots directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, this.renderer, peopleOccupationFilter([Occupation.astronaut, Occupation.pilot]));
|
|
94
95
|
}
|
|
95
96
|
createContactees(dirs, templateFileName) {
|
|
96
|
-
return new PeopleDirectoryStep("contactees directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, peopleOccupationFilter([Occupation.contactee]));
|
|
97
|
+
return new PeopleDirectoryStep("contactees directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, this.renderer, peopleOccupationFilter([Occupation.contactee]));
|
|
97
98
|
}
|
|
98
99
|
createAstronomers(dirs, templateFileName) {
|
|
99
|
-
return new PeopleDirectoryStep("astronomers directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, peopleOccupationFilter([Occupation.astronomer]));
|
|
100
|
+
return new PeopleDirectoryStep("astronomers directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, this.renderer, peopleOccupationFilter([Occupation.astronomer]));
|
|
100
101
|
}
|
|
101
102
|
createUfoWitnesses(dirs, templateFileName) {
|
|
102
|
-
return new PeopleDirectoryStep(`UFO witnesses directories`, dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, peopleOccupationFilter([Occupation.ufoWitness, Occupation.ufoWitness2, Occupation.abductee, Occupation.contactee]));
|
|
103
|
+
return new PeopleDirectoryStep(`UFO witnesses directories`, dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, this.renderer, peopleOccupationFilter([Occupation.ufoWitness, Occupation.ufoWitness2, Occupation.abductee, Occupation.contactee]));
|
|
103
104
|
}
|
|
104
105
|
createUfologists(dirs, templateFileName) {
|
|
105
|
-
return new PeopleDirectoryStep("ufologists directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, peopleOccupationFilter([Occupation.ufologist]));
|
|
106
|
+
return new PeopleDirectoryStep("ufologists directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, this.renderer, peopleOccupationFilter([Occupation.ufologist]));
|
|
106
107
|
}
|
|
107
108
|
createScientists(dirs, templateFileName) {
|
|
108
|
-
return new PeopleDirectoryStep("scientists directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, peopleOccupationFilter([
|
|
109
|
+
return new PeopleDirectoryStep("scientists directories", dirs, this.excludedDirs, templateFileName, this.outputFunc, this.config, this.service, this.renderer, peopleOccupationFilter([
|
|
109
110
|
Occupation.anthropologist, Occupation.astronomer, Occupation.astrophysicist, Occupation.archeologist,
|
|
110
111
|
Occupation.biochemist, Occupation.biologist, Occupation.biophysicist, Occupation.botanist,
|
|
111
112
|
Occupation.chemist,
|
|
@@ -6,8 +6,8 @@ export declare class PeopleFactory extends TypedDataFactory<People, PeopleJson>
|
|
|
6
6
|
/**
|
|
7
7
|
* Determine people name from directory name.
|
|
8
8
|
*
|
|
9
|
-
* @param
|
|
9
|
+
* @param peopleJson
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
protected completeFromDirName(peopleJson: PeopleJson): PeopleJson;
|
|
12
12
|
parse(peopleJson: PeopleJson): People;
|
|
13
13
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { People } from "./People.js";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { StringUtil } from "../util/index.js";
|
|
4
2
|
import { TypedDataFactory } from "@rr0/data";
|
|
3
|
+
import { StringUtil } from "../util";
|
|
4
|
+
import path from "path";
|
|
5
5
|
export class PeopleFactory extends TypedDataFactory {
|
|
6
6
|
constructor(eventFactory) {
|
|
7
7
|
super(eventFactory, "people");
|
|
@@ -9,23 +9,35 @@ export class PeopleFactory extends TypedDataFactory {
|
|
|
9
9
|
/**
|
|
10
10
|
* Determine people name from directory name.
|
|
11
11
|
*
|
|
12
|
-
* @param
|
|
12
|
+
* @param peopleJson
|
|
13
13
|
*/
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
completeFromDirName(peopleJson) {
|
|
15
|
+
const result = { ...peopleJson };
|
|
16
|
+
const dirName = peopleJson.dirName;
|
|
17
|
+
if (dirName) {
|
|
18
|
+
const lastSlash = dirName.lastIndexOf("/");
|
|
19
|
+
const lastDir = dirName.substring(lastSlash + 1);
|
|
20
|
+
const title = StringUtil.camelToText(lastDir);
|
|
21
|
+
const firstSpace = title.indexOf(" ");
|
|
22
|
+
const lastName = title.substring(0, firstSpace);
|
|
23
|
+
result.lastName = peopleJson.lastName || lastName;
|
|
24
|
+
const firstNameStr = title.substring(firstSpace + 1);
|
|
25
|
+
const firstNames = firstNameStr.split(" ");
|
|
26
|
+
result.firstNames = peopleJson.firstNames || firstNames;
|
|
27
|
+
const id = path.basename(dirName);
|
|
28
|
+
result.id = peopleJson.id || id;
|
|
29
|
+
result.title = `${firstNames.join(" ")} ${lastName}`;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
result.dirName = "";
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
24
35
|
}
|
|
25
36
|
parse(peopleJson) {
|
|
26
|
-
|
|
37
|
+
peopleJson = this.completeFromDirName(peopleJson);
|
|
38
|
+
const peopleData = super.parse(peopleJson);
|
|
39
|
+
const people = new People(peopleData.firstNames, peopleData.lastName, peopleData.occupations, peopleData.occupations, peopleData.countries, peopleData.discredited, peopleData.birthTime, peopleData.deathTime, peopleData.gender, peopleData.id, peopleData.dirName, peopleData.image, peopleData.url, peopleData.events);
|
|
27
40
|
peopleJson.name = people.name;
|
|
28
|
-
Object.assign(people, super.parse(peopleJson));
|
|
29
41
|
let title = peopleJson.title;
|
|
30
42
|
let qualifier;
|
|
31
43
|
if (title) {
|
|
@@ -49,7 +61,6 @@ export class PeopleFactory extends TypedDataFactory {
|
|
|
49
61
|
}
|
|
50
62
|
}
|
|
51
63
|
people.title = people.firstAndLastName + (qualifier ? ` (${qualifier})` : "");
|
|
52
|
-
Object.assign(people, { events: peopleJson.events.map(this.eventFactory.parse) });
|
|
53
64
|
return people;
|
|
54
65
|
}
|
|
55
66
|
}
|
|
@@ -1,81 +1,29 @@
|
|
|
1
|
-
import { PeopleService } from "./PeopleService.js";
|
|
2
|
-
import { People } from "./People.js";
|
|
3
1
|
import { describe, expect, test } from "@javarome/testscript";
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
2
|
+
import { PeopleFactory } from "./PeopleFactory";
|
|
3
|
+
import { RR0EventFactory } from "@rr0/data";
|
|
4
|
+
import { People } from "./People";
|
|
5
|
+
import { Occupation } from "./Occupation";
|
|
6
|
+
import { CountryCode } from "../org";
|
|
6
7
|
describe("PeopleFactory", () => {
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const peopleFiles = [
|
|
10
|
-
path.join(peopleRoot, "a/Aristote"),
|
|
11
|
-
path.join(peopleRoot, "b/BeauJerome"),
|
|
12
|
-
path.join(peopleRoot, "b/BeauJeromePierre"),
|
|
13
|
-
path.join(peopleRoot, "c/CondonEdwardU"),
|
|
14
|
-
path.join(peopleRoot, "h/HynekJosefAllen"),
|
|
15
|
-
path.join(peopleRoot, "v/VonBraunWerner")
|
|
16
|
-
];
|
|
17
|
-
const factory = new PeopleService(dataService, rr0TestUtil.peopleFactory, peopleFiles, rr0TestUtil.time.getService());
|
|
18
|
-
test("build people with one first name", () => {
|
|
19
|
-
expect(factory.createFromFullName("Jérôme Beau")).toEqual(new People(["Jérôme"], "Beau", [], [], [], false, undefined, undefined, undefined, "people/b/BeauJerome"));
|
|
20
|
-
});
|
|
8
|
+
const eventFactory = new RR0EventFactory();
|
|
9
|
+
const factory = new PeopleFactory(eventFactory);
|
|
21
10
|
test("build people with two first names", () => {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
expect(
|
|
39
|
-
expect(people.hoax).toBe(false);
|
|
40
|
-
expect(people.discredited).toBe(false);
|
|
41
|
-
expect(people.dirName).toBe("people/v/VonBraunWerner");
|
|
42
|
-
expect(people.occupations).toBe([]);
|
|
43
|
-
expect(people.pseudonyms).toBe([]);
|
|
44
|
-
});
|
|
45
|
-
test("build people with one initial first names", () => {
|
|
46
|
-
const people = factory.createFromFullName("Edward U. Condon");
|
|
47
|
-
expect(people.title).toBe("Condon, Edward U.");
|
|
48
|
-
expect(people.countries).toBe([]);
|
|
49
|
-
expect(people.lastName).toBe("Condon");
|
|
50
|
-
expect(people.firstNames).toBe(["Edward", "U."]);
|
|
51
|
-
expect(people.hoax).toBe(false);
|
|
52
|
-
expect(people.discredited).toBe(false);
|
|
53
|
-
expect(people.dirName).toBe("people/c/CondonEdwardU");
|
|
54
|
-
expect(people.occupations).toBe([]);
|
|
55
|
-
expect(people.pseudonyms).toBe([]);
|
|
56
|
-
});
|
|
57
|
-
test("build people with last name first", () => {
|
|
58
|
-
const people = factory.createFromFullName("Hynek, Josef Allen");
|
|
59
|
-
expect(people.title).toBe("Hynek, Josef Allen");
|
|
60
|
-
expect(people.countries).toBe([]);
|
|
61
|
-
expect(people.lastName).toBe("Hynek");
|
|
62
|
-
expect(people.firstNames).toBe(["Josef", "Allen"]);
|
|
63
|
-
expect(people.hoax).toBe(false);
|
|
64
|
-
expect(people.discredited).toBe(false);
|
|
65
|
-
expect(people.dirName).toBe("people/h/HynekJosefAllen");
|
|
66
|
-
expect(people.occupations).toBe([]);
|
|
67
|
-
expect(people.pseudonyms).toBe([]);
|
|
68
|
-
});
|
|
69
|
-
test("Single name", () => {
|
|
70
|
-
const people = factory.createFromFullName("Aristote");
|
|
71
|
-
expect(people.title).toBe("Aristote");
|
|
72
|
-
expect(people.countries).toBe([]);
|
|
73
|
-
expect(people.lastName).toBe("Aristote");
|
|
74
|
-
expect(people.firstNames).toBe([]);
|
|
75
|
-
expect(people.hoax).toBe(false);
|
|
76
|
-
expect(people.discredited).toBe(false);
|
|
77
|
-
expect(people.dirName).toBe("people/a/Aristote");
|
|
78
|
-
expect(people.occupations).toBe([]);
|
|
79
|
-
expect(people.pseudonyms).toBe([]);
|
|
11
|
+
const villaJson = {
|
|
12
|
+
"birthTime": "1916-09-24",
|
|
13
|
+
"deathTime": "1980-11-22",
|
|
14
|
+
"occupations": [
|
|
15
|
+
"contactee",
|
|
16
|
+
"mechanic"
|
|
17
|
+
],
|
|
18
|
+
"countries": [
|
|
19
|
+
"us"
|
|
20
|
+
],
|
|
21
|
+
"pseudonyms": [
|
|
22
|
+
"Paul Villa"
|
|
23
|
+
]
|
|
24
|
+
};
|
|
25
|
+
const parsed = factory.parse(villaJson);
|
|
26
|
+
const expected = new People(undefined, undefined, ["Paul Villa"], [Occupation.contactee, Occupation.mechanic], [CountryCode.us], true);
|
|
27
|
+
expect(parsed).toEqual(expected);
|
|
80
28
|
});
|
|
81
29
|
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { People } from "./People.js";
|
|
2
|
+
import { HtmlRR0Context } from "../RR0Context.js";
|
|
3
|
+
import { CountryCode } from "../org/index.js";
|
|
4
|
+
import { Occupation } from "./Occupation.js";
|
|
5
|
+
export declare class PeopleHtmlRenderer {
|
|
6
|
+
protected defaultPreviewFileNames: string[];
|
|
7
|
+
constructor(defaultPreviewFileNames?: string[]);
|
|
8
|
+
renderLink(context: HtmlRR0Context, people: People, pseudoPeopleList: People[], allCountries: Set<CountryCode>, occupations: Set<Occupation>, filterOccupations?: Occupation[], content?: string): HTMLElement;
|
|
9
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { Gender } from "@rr0/common";
|
|
3
|
+
export class PeopleHtmlRenderer {
|
|
4
|
+
constructor(defaultPreviewFileNames = ["portrait.jpg", "portrait.gif", "portrait.png", "portrait.webp"]) {
|
|
5
|
+
this.defaultPreviewFileNames = defaultPreviewFileNames;
|
|
6
|
+
}
|
|
7
|
+
renderLink(context, people, pseudoPeopleList, allCountries, occupations, filterOccupations = [], content) {
|
|
8
|
+
var _a, _b, _c;
|
|
9
|
+
const dirName = people.dirName;
|
|
10
|
+
const events = people.events;
|
|
11
|
+
const titles = [];
|
|
12
|
+
const classList = ["data-resolved", "people-resolved"];
|
|
13
|
+
if (pseudoPeopleList.indexOf(people) >= 0 || people.pseudonyms.includes(content)) {
|
|
14
|
+
classList.push("pseudonym");
|
|
15
|
+
titles.push(`(pseudonyme de ${people.firstAndLastName})`);
|
|
16
|
+
}
|
|
17
|
+
if (people.hoax) {
|
|
18
|
+
classList.push("canular");
|
|
19
|
+
}
|
|
20
|
+
const birthTimeStr = (_a = people.birthTime) === null || _a === void 0 ? void 0 : _a.year.toString();
|
|
21
|
+
const deathTimeStr = (_b = people.deathTime) === null || _b === void 0 ? void 0 : _b.year.toString();
|
|
22
|
+
if (people.isDeceased()) {
|
|
23
|
+
classList.push("deceased");
|
|
24
|
+
}
|
|
25
|
+
if (birthTimeStr || deathTimeStr) {
|
|
26
|
+
const timeStr = birthTimeStr ? deathTimeStr ? `${birthTimeStr}-${deathTimeStr}` : `${birthTimeStr}-` : `-${deathTimeStr}`;
|
|
27
|
+
titles.push(timeStr);
|
|
28
|
+
}
|
|
29
|
+
const age = people.getAge();
|
|
30
|
+
if (age) {
|
|
31
|
+
titles.push(`${age} ans`);
|
|
32
|
+
}
|
|
33
|
+
const countries = people.countries;
|
|
34
|
+
if (countries) {
|
|
35
|
+
for (const country of countries) {
|
|
36
|
+
allCountries.add(country);
|
|
37
|
+
const countryLabel = (_c = context.messages.country[country]) === null || _c === void 0 ? void 0 : _c.title;
|
|
38
|
+
if (!countryLabel) {
|
|
39
|
+
throw new Error(`No title for country "${country}"`);
|
|
40
|
+
}
|
|
41
|
+
titles.push(countryLabel);
|
|
42
|
+
classList.push(`country-${country}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const gender = people.gender || Gender.male;
|
|
46
|
+
for (const occupation of people.occupations) {
|
|
47
|
+
if (filterOccupations.length > 1 || !filterOccupations.includes(occupation)) {
|
|
48
|
+
occupations.add(occupation);
|
|
49
|
+
const occupationMsg = context.messages.people.occupation[occupation];
|
|
50
|
+
if (!occupationMsg) {
|
|
51
|
+
throw Error(`No message to translate occupation "${occupation}" in ${context.locale}, as specified in ${people.dirName}/people*.json`);
|
|
52
|
+
}
|
|
53
|
+
classList.push(`occupation-${occupation}`);
|
|
54
|
+
titles.push(occupationMsg(gender));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const text = content || people.lastAndFirstName;
|
|
58
|
+
const doc = context.file.document;
|
|
59
|
+
const link = doc.createElement("a");
|
|
60
|
+
link.innerHTML = text;
|
|
61
|
+
link.href = `/${dirName}/`;
|
|
62
|
+
if (people.discredited) {
|
|
63
|
+
link.append(" 🤥");
|
|
64
|
+
titles.push("discrédité");
|
|
65
|
+
}
|
|
66
|
+
const elem = doc.createElement("span");
|
|
67
|
+
if (titles.length > 0) {
|
|
68
|
+
elem.title = titles.join(", ");
|
|
69
|
+
}
|
|
70
|
+
if (classList.length > 0) {
|
|
71
|
+
elem.classList.add(...classList);
|
|
72
|
+
}
|
|
73
|
+
let portraitUrl = people.image;
|
|
74
|
+
const imageEvents = events.filter(event => event.eventType === "image");
|
|
75
|
+
if (!portraitUrl) {
|
|
76
|
+
const portraitEvent = imageEvents.find(event => this.defaultPreviewFileNames.includes(event.url));
|
|
77
|
+
if (portraitEvent) {
|
|
78
|
+
portraitUrl = path.join("/", people.dirName, portraitEvent.url);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (portraitUrl) {
|
|
82
|
+
const portraitElem = doc.createElement("img");
|
|
83
|
+
portraitElem.src = path.join("/", portraitUrl);
|
|
84
|
+
portraitElem.alt = people.lastAndFirstName;
|
|
85
|
+
portraitElem.className = "portrait";
|
|
86
|
+
portraitElem.loading = "lazy";
|
|
87
|
+
portraitElem.width = 75;
|
|
88
|
+
link.append(portraitElem);
|
|
89
|
+
}
|
|
90
|
+
elem.append(link);
|
|
91
|
+
return elem;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -1,39 +1,34 @@
|
|
|
1
|
-
import { Occupation } from "./Occupation.js";
|
|
2
|
-
import { Gender } from "@rr0/common";
|
|
3
|
-
import { CountryCode } from "../org/country/CountryCode.js";
|
|
4
|
-
import { Level2Date as EdtfDate } from "@rr0/time";
|
|
5
1
|
import { RR0DataJson } from "@rr0/data/dist/RR0DataJson";
|
|
6
2
|
import { RR0EventJson } from "@rr0/data/dist/event/RR0EventJson";
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
title
|
|
10
|
-
name
|
|
3
|
+
export type PeopleJson = RR0DataJson & {
|
|
4
|
+
type?: "people";
|
|
5
|
+
title?: string;
|
|
6
|
+
name?: string;
|
|
11
7
|
/**
|
|
12
8
|
* The people actually doesn't exist.
|
|
13
9
|
*/
|
|
14
|
-
hoax
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
countries: CountryCode[];
|
|
10
|
+
hoax?: boolean;
|
|
11
|
+
firstNames?: string[];
|
|
12
|
+
lastName?: string;
|
|
13
|
+
pseudonyms?: string[];
|
|
14
|
+
occupations?: string[];
|
|
15
|
+
countries?: string[];
|
|
21
16
|
/**
|
|
22
17
|
* The people has been caught lying or has confessed a hoax.
|
|
23
18
|
*/
|
|
24
|
-
discredited
|
|
19
|
+
discredited?: boolean;
|
|
25
20
|
/**
|
|
26
21
|
* @deprecated Use a "birth"-typed event instead.
|
|
27
22
|
*/
|
|
28
|
-
birthTime?:
|
|
23
|
+
birthTime?: string;
|
|
29
24
|
/**
|
|
30
25
|
* @deprecated Use a "death"-typed event instead.
|
|
31
26
|
*/
|
|
32
|
-
deathTime?:
|
|
33
|
-
gender?:
|
|
34
|
-
id
|
|
27
|
+
deathTime?: string;
|
|
28
|
+
gender?: "male" | "female";
|
|
29
|
+
id?: string;
|
|
35
30
|
dirName?: string;
|
|
36
31
|
image?: string;
|
|
37
32
|
url?: string;
|
|
38
|
-
events
|
|
39
|
-
}
|
|
33
|
+
events?: RR0EventJson[];
|
|
34
|
+
};
|
|
@@ -1,19 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
constructor() {
|
|
3
|
-
this.type = "people";
|
|
4
|
-
/**
|
|
5
|
-
* The people actually doesn't exist.
|
|
6
|
-
*/
|
|
7
|
-
this.hoax = false;
|
|
8
|
-
this.firstNames = [];
|
|
9
|
-
this.lastName = "";
|
|
10
|
-
this.pseudonyms = [];
|
|
11
|
-
this.occupations = [];
|
|
12
|
-
this.countries = [];
|
|
13
|
-
/**
|
|
14
|
-
* The people has been caught lying or has confessed a hoax.
|
|
15
|
-
*/
|
|
16
|
-
this.discredited = false;
|
|
17
|
-
this.events = [];
|
|
18
|
-
}
|
|
19
|
-
}
|
|
1
|
+
export {};
|
|
@@ -4,12 +4,14 @@ import { ClassDomReplaceCommand } from "ssg-api";
|
|
|
4
4
|
import { describe, expect, test } from "@javarome/testscript";
|
|
5
5
|
import { PeopleService } from "./PeopleService.js";
|
|
6
6
|
import path from "path";
|
|
7
|
+
import { PeopleHtmlRenderer } from "./PeopleHtmlRenderer";
|
|
7
8
|
describe("ClassDomReplaceCommand", () => {
|
|
8
9
|
test("replaces", async () => {
|
|
9
10
|
const peopleRoot = "src/people";
|
|
10
11
|
const peopleFiles = [path.join(peopleRoot, "b/BeauJerome")];
|
|
12
|
+
const peopleRenderer = new PeopleHtmlRenderer();
|
|
11
13
|
const peopleService = new PeopleService(rr0TestUtil.dataService, rr0TestUtil.peopleFactory, peopleFiles, rr0TestUtil.time.getService());
|
|
12
|
-
const command = new ClassDomReplaceCommand(new PeopleReplacerFactory(peopleService), "people");
|
|
14
|
+
const command = new ClassDomReplaceCommand(new PeopleReplacerFactory(peopleService, peopleRenderer), "people");
|
|
13
15
|
const context = rr0TestUtil.time.newHtmlContext("1/9/9/0/08/index.html", `<span class="people">Jérôme Beau</span>`);
|
|
14
16
|
await command.execute(context);
|
|
15
17
|
expect(context.file.contents).toBe(`<html><head></head><body><span title="1972-, 50 ans, France, ufologue, Informaticien" class="country-fr occupation-ufologist occupation-softwareEngineer" translate="no"><a href="/src/people/b/BeauJerome/">Jérôme Beau</a></span></body></html>`);
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { PeopleService } from "./PeopleService.js";
|
|
2
2
|
import { DomReplacement } from "../time/DomReplacement.js";
|
|
3
3
|
import { HtmlRR0Context } from "../RR0Context.js";
|
|
4
|
+
import { PeopleHtmlRenderer } from "./PeopleHtmlRenderer";
|
|
4
5
|
export declare class PeopleReplacer implements DomReplacement<HtmlRR0Context> {
|
|
5
6
|
protected service: PeopleService;
|
|
6
|
-
|
|
7
|
+
protected renderer: PeopleHtmlRenderer;
|
|
8
|
+
constructor(service: PeopleService, renderer: PeopleHtmlRenderer);
|
|
7
9
|
replacement(context: HtmlRR0Context, element: HTMLElement): Promise<HTMLElement>;
|
|
8
10
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export class PeopleReplacer {
|
|
2
|
-
constructor(service) {
|
|
2
|
+
constructor(service, renderer) {
|
|
3
3
|
this.service = service;
|
|
4
|
+
this.renderer = renderer;
|
|
4
5
|
}
|
|
5
6
|
async replacement(context, element) {
|
|
6
7
|
const title = element.title;
|
|
@@ -29,7 +30,7 @@ export class PeopleReplacer {
|
|
|
29
30
|
const allCountries = new Set();
|
|
30
31
|
const occupations = new Set;
|
|
31
32
|
const peopl = peopleList[0] || people;
|
|
32
|
-
replacement = this.
|
|
33
|
+
replacement = this.renderer.renderLink(context, peopl, pseudoPeopleList, allCountries, occupations, [], peopleContent);
|
|
33
34
|
}
|
|
34
35
|
else {
|
|
35
36
|
const span = context.file.document.createElement("span");
|
|
@@ -5,6 +5,7 @@ import { describe, expect, test } from "@javarome/testscript";
|
|
|
5
5
|
import { PeopleFactory } from "./PeopleFactory.js";
|
|
6
6
|
import path from "path";
|
|
7
7
|
import { AllDataService, RR0EventFactory } from "@rr0/data";
|
|
8
|
+
import { PeopleHtmlRenderer } from "./PeopleHtmlRenderer";
|
|
8
9
|
describe("PeopleReplacer", () => {
|
|
9
10
|
const peopleRoot = "src/people";
|
|
10
11
|
const peopleFiles = [
|
|
@@ -22,7 +23,9 @@ describe("PeopleReplacer", () => {
|
|
|
22
23
|
}
|
|
23
24
|
test("ignore brackets", async () => {
|
|
24
25
|
const dataService = new AllDataService([peopleFactory]);
|
|
25
|
-
const
|
|
26
|
+
const peopleService = new PeopleService(dataService, peopleFactory, peopleFiles, rr0TestUtil.time.getService());
|
|
27
|
+
const peopleRenderer = new PeopleHtmlRenderer();
|
|
28
|
+
const replacer = new PeopleReplacer(peopleService, peopleRenderer);
|
|
26
29
|
const context = rr0TestUtil.time.newHtmlContext("1/9/9/0/08/index.html", "");
|
|
27
30
|
{
|
|
28
31
|
const lastnameFirstElement = createPeopleElement(context, "Hynek, Josef Allen (Northwestern University, Evanston, Illinois)");
|
|
@@ -37,7 +40,9 @@ describe("PeopleReplacer", () => {
|
|
|
37
40
|
});
|
|
38
41
|
test("replace people tags", async () => {
|
|
39
42
|
const dataService = new AllDataService([peopleFactory]);
|
|
40
|
-
const
|
|
43
|
+
const peopleService = new PeopleService(dataService, peopleFactory, peopleFiles, rr0TestUtil.time.getService());
|
|
44
|
+
const peopleRenderer = new PeopleHtmlRenderer();
|
|
45
|
+
const replacer = new PeopleReplacer(peopleService, peopleRenderer);
|
|
41
46
|
const context = rr0TestUtil.time.newHtmlContext("1/9/9/0/08/index.html", "");
|
|
42
47
|
{
|
|
43
48
|
const peopleWithTitle = createPeopleElement(context, "Ronald Reagan", "Ronald Wilson Reagan");
|
|
@@ -2,13 +2,15 @@ import { PeopleReplacer } from "./PeopleReplacer.js";
|
|
|
2
2
|
import { DomReplacer, ReplacerFactory } from "ssg-api";
|
|
3
3
|
import { PeopleService } from "./PeopleService.js";
|
|
4
4
|
import { HtmlRR0Context } from "../RR0Context.js";
|
|
5
|
+
import { PeopleHtmlRenderer } from "./PeopleHtmlRenderer";
|
|
5
6
|
/**
|
|
6
7
|
* Creates replacers for people HTML in a given context.
|
|
7
8
|
*/
|
|
8
9
|
export declare class PeopleReplacerFactory implements ReplacerFactory<DomReplacer> {
|
|
9
10
|
protected service: PeopleService;
|
|
11
|
+
protected renderer: PeopleHtmlRenderer;
|
|
10
12
|
protected singleton?: PeopleReplacer;
|
|
11
|
-
constructor(service: PeopleService);
|
|
13
|
+
constructor(service: PeopleService, renderer: PeopleHtmlRenderer);
|
|
12
14
|
create(context: HtmlRR0Context): Promise<DomReplacer>;
|
|
13
15
|
protected getInstance(): Promise<PeopleReplacer>;
|
|
14
16
|
}
|
|
@@ -3,8 +3,9 @@ import { PeopleReplacer } from "./PeopleReplacer.js";
|
|
|
3
3
|
* Creates replacers for people HTML in a given context.
|
|
4
4
|
*/
|
|
5
5
|
export class PeopleReplacerFactory {
|
|
6
|
-
constructor(service) {
|
|
6
|
+
constructor(service, renderer) {
|
|
7
7
|
this.service = service;
|
|
8
|
+
this.renderer = renderer;
|
|
8
9
|
}
|
|
9
10
|
async create(context) {
|
|
10
11
|
const instance = await this.getInstance();
|
|
@@ -16,7 +17,7 @@ export class PeopleReplacerFactory {
|
|
|
16
17
|
}
|
|
17
18
|
async getInstance() {
|
|
18
19
|
if (!this.singleton) {
|
|
19
|
-
this.singleton = new PeopleReplacer(this.service);
|
|
20
|
+
this.singleton = new PeopleReplacer(this.service, this.renderer);
|
|
20
21
|
}
|
|
21
22
|
return this.singleton;
|
|
22
23
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { People } from "./People.js";
|
|
2
|
-
import { HtmlRR0Context } from "../RR0Context.js";
|
|
3
|
-
import { CountryCode } from "../org/index.js";
|
|
4
|
-
import { Occupation } from "./Occupation.js";
|
|
5
2
|
import { PeopleFactory } from "./PeopleFactory.js";
|
|
6
3
|
import { AbstractDataService, AllDataService } from "@rr0/data";
|
|
7
4
|
import { TimeService } from "../time";
|
|
@@ -15,5 +12,4 @@ export declare class PeopleService extends AbstractDataService<People, PeopleJso
|
|
|
15
12
|
getAll(): Promise<People[]>;
|
|
16
13
|
getFromDirs(dirNames: string[]): Promise<People[]>;
|
|
17
14
|
getFromDir(dirName: string): Promise<People[]>;
|
|
18
|
-
getLink(context: HtmlRR0Context, people: People, pseudoPeopleList: People[], allCountries: Set<CountryCode>, occupations: Set<Occupation>, filterOccupations?: Occupation[], content?: string): HTMLElement;
|
|
19
15
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { People } from "./People.js";
|
|
2
|
-
import
|
|
3
|
-
import { Gender } from "@rr0/common";
|
|
4
|
-
import { AbstractDataFactory, AbstractDataService } from "@rr0/data";
|
|
2
|
+
import { AbstractDataService } from "@rr0/data";
|
|
5
3
|
export class PeopleService extends AbstractDataService {
|
|
6
4
|
constructor(dataService, peopleFactory, files, timeService) {
|
|
7
5
|
super(dataService, peopleFactory, files);
|
|
@@ -34,13 +32,7 @@ export class PeopleService extends AbstractDataService {
|
|
|
34
32
|
if (this.files.indexOf(dirName) < 0) {
|
|
35
33
|
dirName = undefined;
|
|
36
34
|
}
|
|
37
|
-
|
|
38
|
-
if (dirName && !lastName && (firstNames === null || firstNames === void 0 ? void 0 : firstNames.length) <= 0) {
|
|
39
|
-
created = this.peopleFactory.createFromDirName(dirName);
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
created = new People(firstNames, lastName, undefined, undefined, undefined, false, undefined, undefined, undefined, undefined, dirName);
|
|
43
|
-
}
|
|
35
|
+
const created = this.peopleFactory.parse({ firstNames, lastName, dirName });
|
|
44
36
|
this.cache.set(lastName, created);
|
|
45
37
|
return created;
|
|
46
38
|
}
|
|
@@ -59,90 +51,4 @@ export class PeopleService extends AbstractDataService {
|
|
|
59
51
|
const fileSpec = ["people*.json"];
|
|
60
52
|
return this.dataService.getFromDir(dirName, ["people", undefined], fileSpec);
|
|
61
53
|
}
|
|
62
|
-
getLink(context, people, pseudoPeopleList, allCountries, occupations, filterOccupations = [], content) {
|
|
63
|
-
var _a, _b, _c;
|
|
64
|
-
const dirName = people.dirName;
|
|
65
|
-
const events = people.events;
|
|
66
|
-
const titles = [];
|
|
67
|
-
const classList = ["data-resolved", "people-resolved"];
|
|
68
|
-
if (pseudoPeopleList.indexOf(people) >= 0 || people.pseudonyms.includes(content)) {
|
|
69
|
-
classList.push("pseudonym");
|
|
70
|
-
titles.push(`(pseudonyme de ${people.firstAndLastName})`);
|
|
71
|
-
}
|
|
72
|
-
if (people.hoax) {
|
|
73
|
-
classList.push("canular");
|
|
74
|
-
}
|
|
75
|
-
const birthTimeStr = (_a = people.birthTime) === null || _a === void 0 ? void 0 : _a.year.toString();
|
|
76
|
-
const deathTimeStr = (_b = people.deathTime) === null || _b === void 0 ? void 0 : _b.year.toString();
|
|
77
|
-
if (people.isDeceased()) {
|
|
78
|
-
classList.push("deceased");
|
|
79
|
-
}
|
|
80
|
-
if (birthTimeStr || deathTimeStr) {
|
|
81
|
-
const timeStr = birthTimeStr ? deathTimeStr ? `${birthTimeStr}-${deathTimeStr}` : `${birthTimeStr}-` : `-${deathTimeStr}`;
|
|
82
|
-
titles.push(timeStr);
|
|
83
|
-
}
|
|
84
|
-
const age = people.getAge();
|
|
85
|
-
if (age) {
|
|
86
|
-
titles.push(`${age} ans`);
|
|
87
|
-
}
|
|
88
|
-
const countries = people.countries;
|
|
89
|
-
if (countries) {
|
|
90
|
-
for (const country of countries) {
|
|
91
|
-
allCountries.add(country);
|
|
92
|
-
const countryLabel = (_c = context.messages.country[country]) === null || _c === void 0 ? void 0 : _c.title;
|
|
93
|
-
if (!countryLabel) {
|
|
94
|
-
throw new Error(`No title for country "${country}"`);
|
|
95
|
-
}
|
|
96
|
-
titles.push(countryLabel);
|
|
97
|
-
classList.push(`country-${country}`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
const gender = people.gender || Gender.male;
|
|
101
|
-
for (const occupation of people.occupations) {
|
|
102
|
-
if (filterOccupations.length > 1 || !filterOccupations.includes(occupation)) {
|
|
103
|
-
occupations.add(occupation);
|
|
104
|
-
const occupationMsg = context.messages.people.occupation[occupation];
|
|
105
|
-
if (!occupationMsg) {
|
|
106
|
-
throw Error(`No message to translate occupation "${occupation}" in ${context.locale}, as specified in ${people.dirName}/people*.json`);
|
|
107
|
-
}
|
|
108
|
-
classList.push(`occupation-${occupation}`);
|
|
109
|
-
titles.push(occupationMsg(gender));
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
const text = content || people.lastAndFirstName;
|
|
113
|
-
const doc = context.file.document;
|
|
114
|
-
const link = doc.createElement("a");
|
|
115
|
-
link.innerHTML = text;
|
|
116
|
-
link.href = `/${dirName}/`;
|
|
117
|
-
if (people.discredited) {
|
|
118
|
-
link.append(" 🤥");
|
|
119
|
-
titles.push("discrédité");
|
|
120
|
-
}
|
|
121
|
-
const elem = doc.createElement("span");
|
|
122
|
-
if (titles.length > 0) {
|
|
123
|
-
elem.title = titles.join(", ");
|
|
124
|
-
}
|
|
125
|
-
if (classList.length > 0) {
|
|
126
|
-
elem.classList.add(...classList);
|
|
127
|
-
}
|
|
128
|
-
let portraitUrl = people.image;
|
|
129
|
-
const imageEvents = events.filter(event => event.eventType === "image");
|
|
130
|
-
if (!portraitUrl) {
|
|
131
|
-
const portraitEvent = imageEvents.find(event => AbstractDataFactory.defaultImageFileNames.includes(event.url));
|
|
132
|
-
if (portraitEvent) {
|
|
133
|
-
portraitUrl = path.join("/", people.dirName, portraitEvent.url);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (portraitUrl) {
|
|
137
|
-
const portraitElem = doc.createElement("img");
|
|
138
|
-
portraitElem.src = path.join("/", portraitUrl);
|
|
139
|
-
portraitElem.alt = people.lastAndFirstName;
|
|
140
|
-
portraitElem.className = "portrait";
|
|
141
|
-
portraitElem.loading = "lazy";
|
|
142
|
-
portraitElem.width = 75;
|
|
143
|
-
link.append(portraitElem);
|
|
144
|
-
}
|
|
145
|
-
elem.append(link);
|
|
146
|
-
return elem;
|
|
147
|
-
}
|
|
148
54
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { PeopleService } from "./PeopleService.js";
|
|
2
|
+
import { People } from "./People.js";
|
|
3
|
+
import { describe, expect, test } from "@javarome/testscript";
|
|
4
|
+
import { rr0TestUtil } from "../test/index.js";
|
|
5
|
+
import path from "path";
|
|
6
|
+
describe("PeopleService", () => {
|
|
7
|
+
const dataService = rr0TestUtil.dataService;
|
|
8
|
+
const peopleRoot = "test/people";
|
|
9
|
+
const peopleFiles = [
|
|
10
|
+
path.join(peopleRoot, "a/Aristote"),
|
|
11
|
+
path.join(peopleRoot, "b/BeauJerome"),
|
|
12
|
+
path.join(peopleRoot, "b/BeauJeromePierre"),
|
|
13
|
+
path.join(peopleRoot, "c/CondonEdwardU"),
|
|
14
|
+
path.join(peopleRoot, "h/HynekJosefAllen"),
|
|
15
|
+
path.join(peopleRoot, "v/VonBraunWerner"),
|
|
16
|
+
path.join("test/science/crypto/ufo/enquete/dossier", "Villa")
|
|
17
|
+
];
|
|
18
|
+
const service = new PeopleService(dataService, rr0TestUtil.peopleFactory, peopleFiles, rr0TestUtil.time.getService());
|
|
19
|
+
test("build people with one first name", () => {
|
|
20
|
+
expect(service.createFromFullName("Jérôme Beau")).toEqual(new People(["Jérôme"], "Beau", [], [], [], false, undefined, undefined, undefined, "people/b/BeauJerome"));
|
|
21
|
+
});
|
|
22
|
+
test("build people with two first names", () => {
|
|
23
|
+
const people = service.createFromFullName("Jérôme Pierre Beau");
|
|
24
|
+
expect(people.title).toBe("Beau, Jérôme Pierre");
|
|
25
|
+
expect(people.countries).toBe([]);
|
|
26
|
+
expect(people.lastName).toBe("Beau");
|
|
27
|
+
expect(people.firstNames).toBe(["Jérôme", "Pierre"]);
|
|
28
|
+
expect(people.hoax).toBe(false);
|
|
29
|
+
expect(people.discredited).toBe(false);
|
|
30
|
+
expect(people.dirName).toBe("people/b/BeauJeromePierre");
|
|
31
|
+
expect(people.occupations).toBe([]);
|
|
32
|
+
expect(people.pseudonyms).toBe([]);
|
|
33
|
+
});
|
|
34
|
+
test("build people with two last names", () => {
|
|
35
|
+
const people = service.createFromFullName("Werner VonBraun");
|
|
36
|
+
expect(people.title).toBe("Von Braun, Werner");
|
|
37
|
+
expect(people.countries).toBe([]);
|
|
38
|
+
expect(people.lastName).toBe("VonBraun");
|
|
39
|
+
expect(people.firstNames).toBe(["Werner"]);
|
|
40
|
+
expect(people.hoax).toBe(false);
|
|
41
|
+
expect(people.discredited).toBe(false);
|
|
42
|
+
expect(people.dirName).toBe("people/v/VonBraunWerner");
|
|
43
|
+
expect(people.occupations).toBe([]);
|
|
44
|
+
expect(people.pseudonyms).toBe([]);
|
|
45
|
+
});
|
|
46
|
+
test("build people with one initial first names", () => {
|
|
47
|
+
const people = service.createFromFullName("Edward U. Condon");
|
|
48
|
+
expect(people.title).toBe("Condon, Edward U.");
|
|
49
|
+
expect(people.countries).toBe([]);
|
|
50
|
+
expect(people.lastName).toBe("Condon");
|
|
51
|
+
expect(people.firstNames).toBe(["Edward", "U."]);
|
|
52
|
+
expect(people.hoax).toBe(false);
|
|
53
|
+
expect(people.discredited).toBe(false);
|
|
54
|
+
expect(people.dirName).toBe("people/c/CondonEdwardU");
|
|
55
|
+
expect(people.occupations).toBe([]);
|
|
56
|
+
expect(people.pseudonyms).toBe([]);
|
|
57
|
+
});
|
|
58
|
+
test("build people with last name first", () => {
|
|
59
|
+
const people = service.createFromFullName("Hynek, Josef Allen");
|
|
60
|
+
expect(people.title).toBe("Hynek, Josef Allen");
|
|
61
|
+
expect(people.countries).toBe([]);
|
|
62
|
+
expect(people.lastName).toBe("Hynek");
|
|
63
|
+
expect(people.firstNames).toBe(["Josef", "Allen"]);
|
|
64
|
+
expect(people.hoax).toBe(false);
|
|
65
|
+
expect(people.discredited).toBe(false);
|
|
66
|
+
expect(people.dirName).toBe("people/h/HynekJosefAllen");
|
|
67
|
+
expect(people.occupations).toBe([]);
|
|
68
|
+
expect(people.pseudonyms).toBe([]);
|
|
69
|
+
});
|
|
70
|
+
test("Single name", () => {
|
|
71
|
+
const people = service.createFromFullName("Aristote");
|
|
72
|
+
expect(people.title).toBe("Aristote");
|
|
73
|
+
expect(people.countries).toBe([]);
|
|
74
|
+
expect(people.lastName).toBe("Aristote");
|
|
75
|
+
expect(people.firstNames).toBe([]);
|
|
76
|
+
expect(people.hoax).toBe(false);
|
|
77
|
+
expect(people.discredited).toBe(false);
|
|
78
|
+
expect(people.dirName).toBe("people/a/Aristote");
|
|
79
|
+
expect(people.occupations).toBe([]);
|
|
80
|
+
expect(people.pseudonyms).toBe([]);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { OrganizationPlace } from "./OrganizationPlace";
|
|
2
|
+
import { NamedPlace } from "@rr0/place";
|
|
2
3
|
/**
|
|
3
4
|
* Convert a place to a <span class="place"> tag with the place name (or location)
|
|
4
5
|
*/
|
|
@@ -9,6 +10,9 @@ export class PlaceRenderer {
|
|
|
9
10
|
const orgPlace = place;
|
|
10
11
|
placeName = orgPlace.org.getTitle(context, { parent: true });
|
|
11
12
|
}
|
|
13
|
+
else if (place instanceof NamedPlace) {
|
|
14
|
+
placeName = place.name;
|
|
15
|
+
}
|
|
12
16
|
else {
|
|
13
17
|
placeName = place.locations.map(location => location.toDMS(context.place)).join(",");
|
|
14
18
|
}
|
|
@@ -4,7 +4,13 @@ export class SearchComponent extends HTMLElement {
|
|
|
4
4
|
* @type {string}
|
|
5
5
|
*/
|
|
6
6
|
static readonly NAME: string;
|
|
7
|
+
static get observedAttributes(): string[];
|
|
7
8
|
shadow: ShadowRoot;
|
|
9
|
+
attributeChangedCallback(name: any, oldValue: any, newValue: any): void;
|
|
10
|
+
/**
|
|
11
|
+
* @param {string} value
|
|
12
|
+
*/
|
|
13
|
+
set placeholder(value: string);
|
|
8
14
|
connectedCallback(): void;
|
|
9
15
|
#private;
|
|
10
16
|
}
|
|
@@ -46,11 +46,27 @@ export class SearchComponent extends HTMLElement {
|
|
|
46
46
|
this.shadow = this.attachShadow({ mode: "closed" });
|
|
47
47
|
this.shadow.appendChild(template.content.cloneNode(true));
|
|
48
48
|
}
|
|
49
|
+
static get observedAttributes() {
|
|
50
|
+
return ["placeholder"];
|
|
51
|
+
}
|
|
52
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
53
|
+
switch (name) {
|
|
54
|
+
case "placeholder":
|
|
55
|
+
this.placeholder = newValue;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* @param {string} value
|
|
60
|
+
*/
|
|
61
|
+
set placeholder(value) {
|
|
62
|
+
const input = this.shadow.getElementById("search-input");
|
|
63
|
+
input.placeholder = value;
|
|
64
|
+
}
|
|
49
65
|
connectedCallback() {
|
|
50
66
|
this.onmouseover = __classPrivateFieldGet(this, _SearchComponent_instances, "m", _SearchComponent_siteSearchLoad).bind(this);
|
|
51
67
|
const input = this.shadow.getElementById("search-input");
|
|
52
68
|
input.oninput = __classPrivateFieldGet(this, _SearchComponent_instances, "m", _SearchComponent_siteSearchChange).bind(this);
|
|
53
|
-
|
|
69
|
+
this.placeholder = "Recherche";
|
|
54
70
|
}
|
|
55
71
|
}
|
|
56
72
|
_SearchComponent_siteIndex = new WeakMap(), _SearchComponent_loading = new WeakMap(), _SearchComponent_maxResultCount = new WeakMap(), _SearchComponent_instances = new WeakSet(), _SearchComponent_siteSearchChange = function _SearchComponent_siteSearchChange(e) {
|
|
@@ -43,7 +43,9 @@ export class SearchIndexStep {
|
|
|
43
43
|
context.warn("Could not find", this.fileName, "Will create it");
|
|
44
44
|
existingIndex = newIndex;
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
const indexSize = existingIndex.pages.length;
|
|
47
|
+
context.setVar("indexSize", indexSize);
|
|
48
|
+
context.log("Saving search index of", indexSize, "pages at", this.fileName);
|
|
47
49
|
const indexJson = JSON.stringify(existingIndex);
|
|
48
50
|
return writeFile(this.fileName, indexJson, "utf-8");
|
|
49
51
|
}
|
|
@@ -18,6 +18,6 @@ export declare class ChronologyReplacer implements DomReplacement<HtmlRR0Context
|
|
|
18
18
|
constructor(mappings: RR0CaseMapping<any>[], renderer: CaseSummaryRenderer);
|
|
19
19
|
replacement(context: HtmlRR0Context, element: HTMLUListElement): Promise<HTMLUListElement>;
|
|
20
20
|
protected aggregate(context: HtmlRR0Context, element: HTMLUListElement): Promise<void>;
|
|
21
|
-
protected aggregateDatasource(mapping: RR0CaseMapping<any>,
|
|
21
|
+
protected aggregateDatasource(context: HtmlRR0Context, mapping: RR0CaseMapping<any>, existingCases: RR0CaseSummary[], casesToAdd: RR0CaseSummary[]): Promise<void>;
|
|
22
22
|
protected merge(context: HtmlRR0Context, sourceCases: any[], fetchTime: Date, mapping: RR0CaseMapping<any>, existingCases: RR0CaseSummary[]): RR0CaseSummary[];
|
|
23
23
|
}
|
|
@@ -36,7 +36,7 @@ export class ChronologyReplacer {
|
|
|
36
36
|
}
|
|
37
37
|
const datasourceKey = context.file.name + "$" + datasource.copyright;
|
|
38
38
|
if (!this.done.has(datasourceKey)) {
|
|
39
|
-
await this.aggregateDatasource(
|
|
39
|
+
await this.aggregateDatasource(context, mapping, existingCases, casesToAdd);
|
|
40
40
|
this.done.add(datasourceKey);
|
|
41
41
|
const merge = mapping.actions.write.includes("pages");
|
|
42
42
|
if (merge) {
|
|
@@ -51,10 +51,14 @@ export class ChronologyReplacer {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
-
async aggregateDatasource(
|
|
54
|
+
async aggregateDatasource(context, mapping, existingCases, casesToAdd) {
|
|
55
55
|
let fetched;
|
|
56
56
|
const datasource = mapping.datasource;
|
|
57
57
|
const backupDatasource = mapping.backupDatasource;
|
|
58
|
+
if (!backupDatasource) {
|
|
59
|
+
context.warn(`${mapping.constructor.name} has no backupDatasource`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
58
62
|
for (const readMethod of mapping.actions.read) {
|
|
59
63
|
if (fetched) {
|
|
60
64
|
break;
|
|
@@ -5,7 +5,7 @@ import { BaseOvniFranceCase } from "./BaseOvniFranceCase.js";
|
|
|
5
5
|
/**
|
|
6
6
|
* Maps a Base OVNI France CSV case to a Base OVNI France case.
|
|
7
7
|
*/
|
|
8
|
-
export declare class
|
|
8
|
+
export declare class BaseOvniFranceCaseSummaryCsvMapper implements CaseMapper<RR0Context, BaseOvniFranceCase, BaseOvniFranceCaseSummary> {
|
|
9
9
|
readonly baseUrl: URL;
|
|
10
10
|
readonly copyright: string;
|
|
11
11
|
readonly authors: string[];
|
|
@@ -2,7 +2,7 @@ import { Level2Date as EdtfDate, Level2Timeshift } from "@rr0/time";
|
|
|
2
2
|
/**
|
|
3
3
|
* Maps a Base OVNI France CSV case to a Base OVNI France case.
|
|
4
4
|
*/
|
|
5
|
-
export class
|
|
5
|
+
export class BaseOvniFranceCaseSummaryCsvMapper {
|
|
6
6
|
constructor(baseUrl, copyright, authors) {
|
|
7
7
|
this.baseUrl = baseUrl;
|
|
8
8
|
this.copyright = copyright;
|
|
@@ -4,7 +4,7 @@ import { rr0TestUtil } from "../../../test/index.js";
|
|
|
4
4
|
import { baseOvniFranceTestCases } from "./BaseOvniFranceTestCases.js";
|
|
5
5
|
import fs from "fs";
|
|
6
6
|
import { baseOvniFranceDatasource, baseOvniFranceSortComparator } from "./BaseOvniFranceRR0Mapping.js";
|
|
7
|
-
import {
|
|
7
|
+
import { BaseOvniFranceCaseSummaryCsvMapper } from "./BaseOvniFranceCaseSummaryCsvMapper.js";
|
|
8
8
|
describe("Base OVNI France CSV mapping", () => {
|
|
9
9
|
const dataDate = new Date("2024-08-12 00:00:00 GMT+1");
|
|
10
10
|
let context;
|
|
@@ -34,7 +34,7 @@ ${case1.id},http://baseovnifrance.free.fr/listgen.php?typlist=20&page=0&numobs=2
|
|
|
34
34
|
test("read", () => {
|
|
35
35
|
const fileMapper = new CsvMapper("&");
|
|
36
36
|
const data = fs.readFileSync("time/1/9/7/7/03/05_03_24_1709676761.txt", { encoding: "latin1" });
|
|
37
|
-
const csvMapper = new
|
|
37
|
+
const csvMapper = new BaseOvniFranceCaseSummaryCsvMapper(baseOvniFranceDatasource.baseUrl, baseOvniFranceDatasource.searchPath, baseOvniFranceDatasource.authors);
|
|
38
38
|
const cases = fileMapper.parse(data)
|
|
39
39
|
.map(csvCase => csvMapper.map(context, csvCase, dataDate))
|
|
40
40
|
.sort(baseOvniFranceSortComparator);
|
|
@@ -64,7 +64,7 @@ export class BaseOvniFranceHttpDatasource extends BaseOvniFranceDatasource {
|
|
|
64
64
|
const minutes = timeFields ? parseInt(timeFields[2], 10) : undefined;
|
|
65
65
|
dateTime.hour = hour;
|
|
66
66
|
dateTime.minute = minutes;
|
|
67
|
-
dateTime.timeshift = Level2Timeshift.fromString("
|
|
67
|
+
dateTime.timeshift = Level2Timeshift.fromString("+01"); // GMT+1/UTC+1
|
|
68
68
|
}
|
|
69
69
|
getFromRow(context, row) {
|
|
70
70
|
const columns = row.querySelectorAll("td");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "./BaseOvniFranceCase.js";
|
|
2
2
|
export * from "./BaseOvniFranceCaseSummary.js";
|
|
3
|
-
export * from "./
|
|
3
|
+
export * from "./BaseOvniFranceCaseSummaryCsvMapper.js";
|
|
4
4
|
export * from "./BaseOvniFranceCaseSummaryRR0Mapper.js";
|
|
5
5
|
export * from "./BaseOvniFranceDatasource.js";
|
|
6
6
|
export * from "./BaseOvniFranceHttpDatasource.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "./BaseOvniFranceCase.js";
|
|
2
2
|
export * from "./BaseOvniFranceCaseSummary.js";
|
|
3
|
-
export * from "./
|
|
3
|
+
export * from "./BaseOvniFranceCaseSummaryCsvMapper.js";
|
|
4
4
|
export * from "./BaseOvniFranceCaseSummaryRR0Mapper.js";
|
|
5
5
|
export * from "./BaseOvniFranceDatasource.js";
|
|
6
6
|
export * from "./BaseOvniFranceHttpDatasource.js";
|
|
@@ -2,8 +2,8 @@ import { HttpSource } from "../HttpSource.js";
|
|
|
2
2
|
import { UrlUtil } from "../../../util/index.js";
|
|
3
3
|
import { RR0Datasource } from "./RR0Datasource.js";
|
|
4
4
|
import { Level2Date as EdtfDate } from "@rr0/time";
|
|
5
|
+
import { NamedPlace } from "@rr0/place";
|
|
5
6
|
import { OrganizationPlace } from "../../../place/OrganizationPlace";
|
|
6
|
-
import { NamedPlace } from "../../../place/NamedPlace";
|
|
7
7
|
export class RR0HttpDatasource extends RR0Datasource {
|
|
8
8
|
constructor(baseUrl, searchPath, cityService) {
|
|
9
9
|
super();
|
|
@@ -10,7 +10,7 @@ export declare class RR0Mapping implements RR0CaseMapping<RR0CaseSummary> {
|
|
|
10
10
|
static baseUrl: URL;
|
|
11
11
|
static searchPath: string;
|
|
12
12
|
readonly datasource: RR0Datasource;
|
|
13
|
-
readonly
|
|
13
|
+
readonly backupDatasource: RR0FileDatasource;
|
|
14
14
|
readonly mapper: RR0CaseSummaryMapper;
|
|
15
15
|
constructor(cityService: CityService, actions: ChronologyReplacerActions);
|
|
16
16
|
}
|
|
@@ -6,7 +6,7 @@ export class RR0Mapping {
|
|
|
6
6
|
this.actions = actions;
|
|
7
7
|
const rr0HttpDatasource = this.datasource = new RR0HttpDatasource(RR0Mapping.baseUrl, RR0Mapping.searchPath, cityService);
|
|
8
8
|
const csvMapper = this.mapper = new RR0CaseSummaryMapper(rr0HttpDatasource.baseUrl, rr0HttpDatasource.searchPath, rr0HttpDatasource.authors);
|
|
9
|
-
this.
|
|
9
|
+
this.backupDatasource = new RR0FileDatasource(csvMapper);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
RR0Mapping.baseUrl = new URL("https://rr0.org");
|
|
@@ -2,7 +2,7 @@ import { Level2Date as EdtfDate } from "@rr0/time";
|
|
|
2
2
|
import { UrlUtil } from "../../../util/index.js";
|
|
3
3
|
import { RR0HttpDatasource } from "./RR0HttpDatasource";
|
|
4
4
|
import { RR0Mapping } from "./RR0Mapping";
|
|
5
|
-
import { NamedPlace } from "
|
|
5
|
+
import { NamedPlace } from "@rr0/place";
|
|
6
6
|
function testCase(urlPath, time, description, sources, place) {
|
|
7
7
|
const path = UrlUtil.join(RR0Mapping.searchPath, urlPath);
|
|
8
8
|
const url = new URL(path, RR0Mapping.baseUrl).href;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@rr0/cms",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"author": "Jérôme Beau <rr0@rr0.org> (https://rr0.org)",
|
|
5
|
-
"version": "0.2.
|
|
5
|
+
"version": "0.2.3",
|
|
6
6
|
"description": "RR0 Content Management System (CMS)",
|
|
7
7
|
"exports": "./dist/index.js",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"@rr0/common": "^1.1.3",
|
|
32
32
|
"@rr0/lang": "^0.1.12",
|
|
33
33
|
"@rr0/time": "^0.9.1",
|
|
34
|
-
"@rr0/place": "^0.5.
|
|
35
|
-
"@rr0/data": "^0.2.
|
|
34
|
+
"@rr0/place": "^0.5.1",
|
|
35
|
+
"@rr0/data": "^0.2.3",
|
|
36
36
|
"@javarome/fileutil": "^0.3.6",
|
|
37
37
|
"ssg-api": "^1.16.12",
|
|
38
38
|
"canvas": "^2.11.2",
|