Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/works/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
getChapterName,
getChapterSummary,
getWorkAdditionalTags,
getWorkAdult,
getWorkAuthors,
getWorkBookmarkCount,
getWorkCategory,
Expand Down Expand Up @@ -85,8 +86,7 @@ export const getWork = async ({
language: getWorkLanguage(workPage),
rating: getWorkRating(workPage),
category: getWorkCategory(workPage),
// TODO: figure out how to get this
adult: false,
adult: getWorkAdult(workPage),
fandoms: getWorkFandoms(workPage),
tags: {
warnings: getWorkWarnings(workPage),
Expand Down
31 changes: 24 additions & 7 deletions src/works/work-getters.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import type { Author, BasicSeries, WorkSummary } from "types/entities";
import { WorkRatings, WorkCategory, WorkWarnings } from "types/entities";
import { WorkPage } from "src/page-loaders";
import {
Author,
BasicSeries,
WorkCategory,
WorkRatings,
WorkSummary,
WorkWarnings,
} from "types/entities";
import { isValidArchiveId, parseArchiveId } from "src/utils";

import { WorkPage } from "src/page-loaders";

export const getWorkAuthors = ($workPage: WorkPage): Author[] => {
const authorLinks = $workPage("h3.byline a[rel='author']");
const authors: Author[] = [];
Expand Down Expand Up @@ -194,6 +201,15 @@ export const getWorkLocked = ($workPage: WorkPage) => {
return !!$workPage("#signin > .heading").text();
};

const ADULT_CATEGORIES = [
WorkRatings.EXPLICIT,
WorkRatings.MATURE,
WorkRatings.NOT_RATED
] as const satisfies ReadonlyArray<WorkRatings>;
export const getWorkAdult = ($workPage: WorkPage): boolean => {
return (ADULT_CATEGORIES as readonly WorkRatings[]).includes(getWorkRating($workPage));
};

export const getWorkContentHtml = ($workPage: WorkPage): string => {
let content = $workPage('.userstuff.module[role="article"]').html();
// Works with multiple chapters have a different structure for the content
Expand All @@ -208,14 +224,14 @@ export const getWorkContentHtml = ($workPage: WorkPage): string => {

export const getWorkStartNotes = ($workPage: WorkPage): string | null => {
const startNotes = $workPage(
".chapter.preface #notes.notes.module .userstuff"
".chapter.preface #notes.notes.module .userstuff",
).html();
return startNotes ? startNotes.trim() : null;
};

export const getWorkEndNotes = ($workPage: WorkPage): string | null => {
const endNotes = $workPage(
".chapter.preface .end.notes.module .userstuff"
".chapter.preface .end.notes.module .userstuff",
).html();
return endNotes ? endNotes.trim() : null;
};
Expand All @@ -225,15 +241,16 @@ export const getWorkContentSummary = ($workPage: WorkPage): string | null => {
return summary ? summary.trim() : null;
};

// Chapter-specific (must be multi-chapter fic)
export const getChapterIndex = (
$workPage: WorkPage
$workPage: WorkPage,
): NonNullable<WorkSummary["chapterInfo"]>["index"] => {
const index = $workPage("#chapters h3.title a").text();
return index ? parseInt(index.trim().replace("Chapter ", "")) : -1;
};

export const getChapterName = (
$workPage: WorkPage
$workPage: WorkPage,
): NonNullable<WorkSummary["chapterInfo"]>["name"] => {
const title = $workPage("#chapters h3.title").text().trim();
// 2 characters is the length of query string
Expand Down
13 changes: 7 additions & 6 deletions tests/work-chapter.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { describe, expect, it } from "vitest";

import type { WorkSummary } from "types/entities";
import { getWork } from "src/index";
import { describe, it, expect } from "vitest";

describe("Work Chapter/chapter", () => {
it("should use null for single-chapter work", async () => {
const work = await getWork({ workId: 168768 });

expect(work.locked).toBeFalsy();
expect(!work.locked).toBeTruthy();

expect(work).toMatchObject({
id: 168768,
Expand Down Expand Up @@ -39,7 +40,7 @@ describe("Work Chapter/chapter", () => {
chapters: { published: 1, total: 1 },
complete: true,
series: [],
stats: { bookmarks: 2, comments: 1, hits: expect.any(Number), kudos: 45 },
stats: { bookmarks: 2, comments: 1, hits: expect.any(Number), kudos: 46 },
locked: false,
});
});
Expand All @@ -53,10 +54,10 @@ describe("Work Chapter/chapter", () => {
expect(!work.locked).toBeTruthy();

expect(work.summary).toMatchInlineSnapshot(
`"<p><b>A Modern Thedas AU</b>, in which Fen&apos;Harel and the Second Inquisitor tore down the Veil a thousand years ago, reshaping Thedas into something entirely new. Thedas now has modern technology powered by magic, and a society still plagued with problems that are all too familiar - issues of race, classism, and power.</p><p>Fenina Lavellan, a student at the College of Enchanters: New Haven, often escapes her reality by playing the MMORPG Dragon Age (set in the ancient past during the time of the Second Inquisition) and is part of the most powerful guild aptly named &quot;TheInquisition&quot; - a guild which has been running since the game was released. But when the guild discovers that they all live in the same city and decide to meet up, they unknowingly stumble into a plot to destroy their world as they know it. Can they navigate the difficulties of actually being social in the real world? Will their in-game skills translate into abilities that will actually help them in stopping a madman? Or is this the end of the world as they know it?</p>"`
`"<p><b>A Modern Thedas AU</b>, in which Fen&apos;Harel and the Second Inquisitor tore down the Veil a thousand years ago, reshaping Thedas into something entirely new. Thedas now has modern technology powered by magic, and a society still plagued with problems that are all too familiar - issues of race, classism, and power.</p><p>Fenina Lavellan, a student at the College of Enchanters: New Haven, often escapes her reality by playing the MMORPG Dragon Age (set in the ancient past during the time of the Second Inquisition) and is part of the most powerful guild aptly named &quot;TheInquisition&quot; - a guild which has been running since the game was released. But when the guild discovers that they all live in the same city and decide to meet up, they unknowingly stumble into a plot to destroy their world as they know it. Can they navigate the difficulties of actually being social in the real world? Will their in-game skills translate into abilities that will actually help them in stopping a madman? Or is this the end of the world as they know it?</p>"`,
);
expect(work.chapterInfo?.summary).toMatchInlineSnapshot(
`"<p>Fenina Lavellan&apos;s MMO guild discovers they all live closer than they thought and decides to meet up.</p>"`
`"<p>Fenina Lavellan&apos;s MMO guild discovers they all live closer than they thought and decides to meet up.</p>"`,
);
});
});
Expand All @@ -79,7 +80,7 @@ describe("Work Chapter/work", () => {
language: "English",
rating: "Not Rated",
category: null,
adult: false,
adult: true,
fandoms: ["Batman - All Media Types"],
tags: {
warnings: ["Creator Chose Not To Use Archive Warnings"],
Expand Down
Loading