Skip to content

Commit

Permalink
Add flavorProfile to smws scraping
Browse files Browse the repository at this point in the history
  • Loading branch information
dcramer committed Apr 12, 2024
1 parent 34afffa commit 0642714
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 33 deletions.
33 changes: 18 additions & 15 deletions apps/server/src/jobs/scrapeSMWS.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,23 @@ test("bottle list", async ({ axiosMock }) => {
await fn;

expect(items.length).toBe(128);
expect(items[0]).toEqual({
name: "RW3.6 Truly a flavour bomb",
brand: {
name: "The Scotch Malt Whisky Society",
},
bottler: {
name: "The Scotch Malt Whisky Society",
},
category: "rye",
distillers: [
{
name: "New York Distilling Co.",
expect(items[0]).toMatchInlineSnapshot(`
{
"bottler": {
"name": "The Scotch Malt Whisky Society",
},
],
statedAge: 5,
});
"brand": {
"name": "The Scotch Malt Whisky Society",
},
"category": "rye",
"distillers": [
{
"name": "New York Distilling Co.",
},
],
"flavorProfile": null,
"name": "RW3.6 Truly a flavour bomb",
"statedAge": 5,
}
`);
});
16 changes: 15 additions & 1 deletion apps/server/src/jobs/scrapeSMWS.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { getUrl } from "@peated/server/lib/scraper";
import { parseDetailsFromName } from "@peated/server/lib/smws";
import {
parseDetailsFromName,
parseFlavorProfile,
} from "@peated/server/lib/smws";
import { trpcClient } from "@peated/server/lib/trpc/server";
import { type BottleInputSchema } from "@peated/server/schemas";
import { type z } from "zod";
Expand Down Expand Up @@ -38,6 +41,7 @@ type SMWSPayload = {
name: string;
age: number | null;
cask_no: string;
categories: string[];
}[];
};

Expand Down Expand Up @@ -67,6 +71,15 @@ export async function scrapeBottles(
return;
}

const flavorProfileRaw = item.categories.find((c) => {
return c.startsWith("All Whisky/Flavour Profiles/");
});
const flavorProfile = flavorProfileRaw
? parseFlavorProfile(
flavorProfileRaw.split("All Whisky/Flavour Profiles/")[1],
)
: null;

await cb({
name: details.name,
category: details.category,
Expand All @@ -82,6 +95,7 @@ export async function scrapeBottles(
name: details.distiller,
},
],
flavorProfile,
});
});
}
33 changes: 18 additions & 15 deletions apps/server/src/jobs/scrapeSMWSA.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,23 @@ test("bottle list", async ({ axiosMock }) => {
await fn;

expect(items.length).toBe(35);
expect(items[0]).toEqual({
name: "41.176 Baristaliscious",
brand: {
name: "The Scotch Malt Whisky Society",
},
bottler: {
name: "The Scotch Malt Whisky Society",
},
category: "single_malt",
distillers: [
{
name: "Dailuaine",
expect(items[0]).toMatchInlineSnapshot(`
{
"bottler": {
"name": "The Scotch Malt Whisky Society",
},
],
statedAge: 17,
});
"brand": {
"name": "The Scotch Malt Whisky Society",
},
"category": "single_malt",
"distillers": [
{
"name": "Dailuaine",
},
],
"flavorProfile": "juicy_oak_vanilla",
"name": "41.176 Baristaliscious",
"statedAge": 17,
}
`);
});
9 changes: 8 additions & 1 deletion apps/server/src/jobs/scrapeSMWSA.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { getUrl } from "@peated/server/lib/scraper";
import { parseDetailsFromName } from "@peated/server/lib/smws";
import {
parseDetailsFromName,
parseFlavorProfile,
} from "@peated/server/lib/smws";
import { trpcClient } from "@peated/server/lib/trpc/server";
import { type BottleInputSchema } from "@peated/server/schemas";
import { load as cheerio } from "cheerio";
Expand Down Expand Up @@ -77,6 +80,9 @@ export async function scrapeBottles(
const ageSpec = specList.find(([name]) => name === "Age:");
const statedAge = ageSpec ? Number(ageSpec[1].split(" ")[0]) : null;

const flavorSpec = specList.find(([name]) => name === "Flavour:");
const flavorProfile = flavorSpec ? parseFlavorProfile(flavorSpec[1]) : null;

const details = parseDetailsFromName(`${itemType} ${caskName}`);
if (!details?.distiller) {
console.error(`Cannot find distiller: ${itemType}`);
Expand All @@ -98,6 +104,7 @@ export async function scrapeBottles(
name: "The Scotch Malt Whisky Society",
},
distillers: [{ name: details.distiller }],
flavorProfile,
});
}
}
38 changes: 37 additions & 1 deletion apps/server/src/lib/smws.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CATEGORY_LIST } from "@peated/server/constants";
import { type Category } from "@peated/server/types";
import type { Category, FlavorProfile } from "@peated/server/types";

// This needs moved into the database and needs to be editable by the community/mods
// https://www.whiskysaga.com/smws-codes
Expand Down Expand Up @@ -312,3 +312,39 @@ export function parseDetailsFromName(name: string): SMWSCaskDetails | null {
distiller: SMWS_DISTILLERY_CODES[distillerNo],
};
}

export function parseFlavorProfile(name: string): FlavorProfile | null {
name = name.replace("&", "&").replace(",", "");

switch (name) {
case "Young & Spritely":
return "young_spritely";
case "Sweet Fruit & Mellow":
case "Sweet Fruity & Mellow":
return "sweet_fruit_mellow";
case "Spicy & Sweet":
return "spicy_sweet";
case "Spicy & Dry":
return "spicy_dry";
case "Deep Rich & Dried Fruit":
case "Deep Rich & Dried Fruits":
return "deep_rich_dried_fruit";
case "Old & Dignified":
return "old_dignified";
case "Light & Delicate":
return "light_delicate";
case "Juicy Oak & Vanilla":
return "juicy_oak_vanilla";
case "Oily & Coastal":
return "oily_coastal";
case "Lightly Peated":
return "lightly_peated";
case "Peated":
return "peated";
case "Heavily Peated":
return "heavily_peated";
default:
console.error(`Unknown flavor profile: ${name}`);
return null;
}
}
3 changes: 3 additions & 0 deletions apps/server/src/trpc/routes/bottleCreate.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { FLAVOR_PROFILES } from "@peated/server/constants";
import { db } from "@peated/server/db";
import {
bottles,
Expand Down Expand Up @@ -63,6 +64,7 @@ test("creates a new bottle with all params", async ({ defaults, fixtures }) => {
bottler: distiller.id,
distillers: [distiller.id],
statedAge: 12,
flavorProfile: FLAVOR_PROFILES[0],
});

expect(data.id).toBeDefined();
Expand All @@ -74,6 +76,7 @@ test("creates a new bottle with all params", async ({ defaults, fixtures }) => {
expect(bottle.name).toEqual("Delicious Wood 12-year-old");
expect(bottle.brandId).toEqual(brand.id);
expect(bottle.statedAge).toEqual(12);
expect(bottle.flavorProfile).toEqual(FLAVOR_PROFILES[0]);
expect(bottle.createdById).toBe(defaults.user.id);
const distillers = await db
.select({ distillerId: bottlesToDistillers.distillerId })
Expand Down
1 change: 1 addition & 0 deletions apps/server/src/trpc/routes/bottleCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export async function bottleCreate({
.values({
name,
fullName,
flavorProfile: input.flavorProfile,
statedAge: statedAge,
category: input.category || null,
brandId: brand.id,
Expand Down

0 comments on commit 0642714

Please sign in to comment.