Merge pull request #82 from MillenniumEarl/parse-changelog

Parse changelog
pull/83/head
Millennium Earl 2021-03-22 15:01:16 +01:00 committed by GitHub
commit 012a0b7b94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 86 additions and 35 deletions

View File

@ -6,7 +6,7 @@
"use strict"; "use strict";
// Modules from files // Modules from files
import { TAuthor, IAnimation, TRating, TCategory } from "../../interfaces"; import { TAuthor, IAnimation, TRating, TCategory, TChangelog } from "../../interfaces";
export default class Animation implements IAnimation { export default class Animation implements IAnimation {
//#region Properties //#region Properties
@ -19,7 +19,7 @@ export default class Animation implements IAnimation {
resolution: string[]; resolution: string[];
authors: TAuthor[]; authors: TAuthor[];
category: TCategory; category: TCategory;
changelog: string[]; changelog: TChangelog[];
cover: string; cover: string;
id: number; id: number;
lastThreadUpdate: Date; lastThreadUpdate: Date;

View File

@ -6,7 +6,7 @@
"use strict"; "use strict";
// Modules from files // Modules from files
import { TAuthor, IAsset, TRating, TCategory } from "../../interfaces"; import { TAuthor, IAsset, TRating, TCategory, TChangelog } from "../../interfaces";
export default class Asset implements IAsset { export default class Asset implements IAsset {
//#region Properties //#region Properties
@ -18,7 +18,7 @@ export default class Asset implements IAsset {
sku: string; sku: string;
authors: TAuthor[]; authors: TAuthor[];
category: TCategory; category: TCategory;
changelog: string[]; changelog: TChangelog[];
cover: string; cover: string;
id: number; id: number;
lastThreadUpdate: Date; lastThreadUpdate: Date;

View File

@ -6,7 +6,7 @@
"use strict"; "use strict";
// Modules from files // Modules from files
import { TAuthor, IComic, TRating, TCategory } from "../../interfaces"; import { TAuthor, IComic, TRating, TCategory, TChangelog } from "../../interfaces";
export default class Comic implements IComic { export default class Comic implements IComic {
//#region Properties //#region Properties
@ -15,7 +15,7 @@ export default class Comic implements IComic {
resolution: string[]; resolution: string[];
authors: TAuthor[]; authors: TAuthor[];
category: TCategory; category: TCategory;
changelog: string[]; changelog: TChangelog[];
cover: string; cover: string;
id: number; id: number;
lastThreadUpdate: Date; lastThreadUpdate: Date;

View File

@ -6,7 +6,7 @@
"use strict"; "use strict";
// Modules from files // Modules from files
import { TAuthor, TEngine, IGame, TRating, TStatus, TCategory } from "../../interfaces"; import { TAuthor, TEngine, IGame, TRating, TStatus, TCategory, TChangelog } from "../../interfaces";
export default class Game implements IGame { export default class Game implements IGame {
//#region Properties //#region Properties
@ -22,7 +22,7 @@ export default class Game implements IGame {
version: string; version: string;
authors: TAuthor[]; authors: TAuthor[];
category: TCategory; category: TCategory;
changelog: string[]; changelog: TChangelog[];
cover: string; cover: string;
id: number; id: number;
lastThreadUpdate: Date; lastThreadUpdate: Date;

View File

@ -6,7 +6,15 @@
"use strict"; "use strict";
// Modules from files // Modules from files
import { TAuthor, TRating, IHandiwork, TEngine, TCategory, TStatus } from "../../interfaces"; import {
TAuthor,
TRating,
IHandiwork,
TEngine,
TCategory,
TStatus,
TChangelog
} from "../../interfaces";
/** /**
* It represents a generic work, be it a game, a comic, an animation or an asset. * It represents a generic work, be it a game, a comic, an animation or an asset.
@ -25,7 +33,7 @@ export default class HandiWork implements IHandiwork {
version: string; version: string;
authors: TAuthor[]; authors: TAuthor[];
category: TCategory; category: TCategory;
changelog: string[]; changelog: TChangelog[];
cover: string; cover: string;
id: number; id: number;
lastThreadUpdate: Date; lastThreadUpdate: Date;

View File

@ -51,6 +51,20 @@ export type TRating = {
count: number; count: number;
}; };
/**
* Information about a single version of the product.
*/
export type TChangelog = {
/**
* Product version.
*/
version: string;
/**
* Version information.
*/
information: string[];
};
/** /**
* List of possible graphics engines used for game development. * List of possible graphics engines used for game development.
*/ */
@ -101,7 +115,7 @@ export interface IBasic {
/** /**
* List of changes of the work for each version. * List of changes of the work for each version.
*/ */
changelog: string[]; changelog: TChangelog[];
/** /**
* link to the cover image of the work. * link to the cover image of the work.
*/ */

View File

@ -11,7 +11,7 @@ import { DateTime } from "luxon";
// Modules from files // Modules from files
import HandiWork from "../classes/handiwork/handiwork"; import HandiWork from "../classes/handiwork/handiwork";
import Thread from "../classes/mapping/thread"; import Thread from "../classes/mapping/thread";
import { IBasic, TAuthor, TEngine, TExternalPlatform, TStatus } from "../interfaces"; import { IBasic, TAuthor, TChangelog, TEngine, TExternalPlatform, TStatus } from "../interfaces";
import shared, { TPrefixDict } from "../shared"; import shared, { TPrefixDict } from "../shared";
import { ILink, IPostElement } from "./post-parse"; import { ILink, IPostElement } from "./post-parse";
@ -223,26 +223,8 @@ function fillWithPostData(hw: HandiWork, elements: IPostElement[]) {
// Get the author // Get the author
hw.authors = parseAuthor(elements); hw.authors = parseAuthor(elements);
//#region Get the changelog // Get the changelog
hw.changelog = []; hw.changelog = parseChangelog(elements);
const changelogElement =
getPostElementByName(elements, "changelog") || getPostElementByName(elements, "change-log");
if (false && changelogElement?.content) {
const changelogSpoiler = changelogElement.content.find(
(el) => el.type === "Spoiler" && el.content.length > 0
);
// Add to the changelog the single spoilers
const spoilers = changelogSpoiler.content
.filter((e) => e.text.trim() !== "")
.map((e) => e.text);
hw.changelog.push(...spoilers);
// Add at the end also the text of the "changelog" element
hw.changelog.push(changelogSpoiler.text);
}
//#endregion Get the changelog
} }
/** /**
@ -283,4 +265,53 @@ function parseAuthor(elements: IPostElement[]): TAuthor[] {
return [author]; return [author];
} }
/**
* Parse the changelog from the post's data.
*/
function parseChangelog(elements: IPostElement[]): TChangelog[] {
// Local variables
const changelog = [];
const changelogElement =
getPostElementByName(elements, "changelog") || getPostElementByName(elements, "change-log");
if (changelogElement) {
// regex used to match version tags
const versionRegex = /^v[0-9]+\.[0-9]+.*/;
// Get the indexes of the version tags
const indexesVersion = changelogElement.content
.filter((e) => e.type === "Text" && versionRegex.test(e.text))
.map((e) => changelogElement.content.indexOf(e));
const results = indexesVersion.map((i, j) => {
// In-loop variable
const versionChangelog: TChangelog = {
version: "",
information: []
};
// Get the difference in indexes between this and the next version tag
const diff = indexesVersion[j + 1] ?? changelogElement.content.length;
// fetch the group of data of this version tag
const group = changelogElement.content.slice(i, diff);
versionChangelog.version = group.shift().text.replace("v", "").trim();
// parse the data
group.forEach((e) => {
if (e.type === "Generic" || e.type === "Spoiler") {
const textes = e.content.map((c) => c.text);
versionChangelog.information.push(...textes);
} else versionChangelog.information.push(e.text);
});
return versionChangelog;
});
changelog.push(...results);
}
return changelog;
}
//#endregion Private methods //#endregion Private methods

View File

@ -431,8 +431,6 @@ function pairUpElements(elements: IPostElement[]): IPostElement[] {
.filter((e, i) => isValidTitleElement(e, i, shallow)) .filter((e, i) => isValidTitleElement(e, i, shallow))
.map((e) => shallow.indexOf(e)); .map((e) => shallow.indexOf(e));
//if (indexes.length === 0) indexes = shallow.map((e, i) => i);
// Now we find all the elements between indexes and // Now we find all the elements between indexes and
// associate them with the previous "title" element // associate them with the previous "title" element
return indexes.map((i, j) => parseGroupData(i, j, indexes, shallow)); return indexes.map((i, j) => parseGroupData(i, j, indexes, shallow));
@ -452,7 +450,7 @@ function isValidTitleElement(element: IPostElement, index: number, array: IPostE
element.type === "Text" && (isPostfixDoublePoints || nextElementIsValue); element.type === "Text" && (isPostfixDoublePoints || nextElementIsValue);
// Special values tha must be set has "title" // Special values tha must be set has "title"
const specialValues = ["DOWNLOAD"]; const specialValues = ["DOWNLOAD", "CHANGELOG", "CHANGE-LOG", "GENRE"];
const specialTypes = ["Image"]; const specialTypes = ["Image"];
// Used to ignore already merged elements with name (ignore spoilers) // Used to ignore already merged elements with name (ignore spoilers)