Skip to content

Commit

Permalink
Added support for scraping more AMD variations
Browse files Browse the repository at this point in the history
Added support for scraping more AMD launch date and graphics combinations.
  • Loading branch information
UltimateDoge5 committed Apr 18, 2023
1 parent 6a0955b commit f5d45df
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 71 deletions.
2 changes: 1 addition & 1 deletion src/pages/api/cpu/amd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {

model = model.trim().toLowerCase();
if (!model.startsWith("amd")) model = `amd ${model}`;

if(model.includes("-")) model = model.replaceAll("-", " ") // One lonely dash can cause issues
const noCache = req.query["no-cache"] !== undefined;

let error: { code: number; message: string } | undefined;
Expand Down
2 changes: 1 addition & 1 deletion src/pages/api/cpu/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
res.status(200).json({
names: names.slice(pInt * 5, pInt * 5 + 5).map((name) => ({
model: beautifyNames(name),
manufacturer: name.includes("amd") ? "amd" : "intel",
manufacturer: name.toLowerCase().includes("amd") ? "amd" : "intel",
})),
remainingItems,
});
Expand Down
130 changes: 67 additions & 63 deletions src/pages/cpu/[cpu].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,14 @@ const Cpu = ({ data }: InferGetServerSidePropsType<typeof getServerSideProps>) =

const refreshCPU = async () => {
setRefetch(true);
const result = await fetch(`/api/cpu/${data.manufacturer}?model=${data.name}&no-cache`);

const result = await fetch(`/api/cpu/${data.manufacturer}?model=${data.ref.split("/").pop()}&no-cache`);
setRefetch(false);

if (!result.ok) {
toast.error(
result.status === 504
? "The server is taking too long to respond. Try again later."
: await result.text()
? "The server is taking too long to respond. Try again later."
: await result.text(),
);
return;
}
Expand Down Expand Up @@ -94,109 +93,111 @@ const Cpu = ({ data }: InferGetServerSidePropsType<typeof getServerSideProps>) =
<div className="mx-auto mb-12 w-3/5 rounded-md bg-white/20 p-6 text-lg">
<RenderTable cpu={data} list={TableStructure} />
</div>
<ToastContainer autoClose={2500} position="bottom-left" theme="dark" draggable={false} />
</div>
<ToastContainer autoClose={2500} position="bottom-left" theme="dark" draggable={false} />
<Footer />
</>
);
};

const RenderTable = ({ cpu, list }: { cpu: CPU; list: Table }) => (
<Fragment>
{Object.keys(list).map((key, i) => (
<div key={key}>
<h2
className={`relative -left-4 ${i === 0 ? "mt-2" : "mt-4"} mb-1 border-b ${
cpu.manufacturer === "intel" ? "border-blue-500" : "border-red-500"
} px-2 pb-0.5 text-3xl font-light`}
>
{key}
</h2>
{Object.keys(list[key]).map((row) => {
const currentRow = list[key][row];

if (currentRow.type === "component") {
return (
<div key={row} className="grid grid-cols-2 pb-1 text-left">
{Object.keys(list)
// If there is no graphics, don't show the GPU specifications
.filter((key) => !(cpu.graphics === false && key === "GPU specifications"))
.map((key, i) => (
<div key={key}>
<h2
className={`relative -left-4 ${i === 0 ? "mt-2" : "mt-4"} mb-1 border-b ${
cpu.manufacturer === "intel" ? "border-blue-500" : "border-red-500"
} px-2 pb-0.5 text-3xl font-light`}
>
{key}
</h2>
{Object.keys(list[key]).map((row, j) => {
const currentRow = list[key][row];

if (currentRow.type === "component") {
return (
<div key={row} className="grid grid-cols-2 pb-1 text-left">
<span className="flex items-center gap-1">
{currentRow.title}
{currentRow.tooltip !== undefined && <Tooltip tip={currentRow.tooltip} />}
</span>
{currentRow.component({ cpu })}
{currentRow.component({ cpu })}
</div>
);
}

//Get the value from the path
const value = traversePath(currentRow.path, cpu);

//If there is no value, and we want to hide the row, return an empty fragment
if ((value === null || value === undefined) && currentRow.hideOnUndefined === true)
return <Fragment key={row} />;

switch (currentRow.type) {
case "number":
return (
<div key={row} className="grid grid-cols-2 pb-1 text-left">
);
}

//Get the value from the path
const value = traversePath(currentRow.path, cpu);

//If there is no value, and we want to hide the row, return an empty fragment the categories that are empty
if ((value === null || value === undefined) && currentRow.hideOnUndefined === true) { return <Fragment key={row} />;}
switch (currentRow.type) {
case "number":
return (
<div key={row} className="grid grid-cols-2 pb-1 text-left">
<span className="flex items-center gap-1">
{currentRow.title}
{currentRow.tooltip !== undefined && <Tooltip tip={currentRow.tooltip} />}
</span>
<span>
{currentRow.prefix !== false
? formatNumber(value, currentRow.unit)
: value + currentRow.unit}
? formatNumber(value, currentRow.unit)
: value + currentRow.unit}
</span>
</div>
);
case "string":
return (
<div key={row} className="grid grid-cols-2 text-left">
);
case "string":
return (
<div key={row} className="grid grid-cols-2 text-left">
<span className="flex items-center gap-1">
{currentRow.title}
{currentRow.tooltip !== undefined && <Tooltip tip={currentRow.tooltip} />}
</span>
<span>{currentRow.capitalize === true ? capitalize(value) : value}</span>
</div>
);
);

case "date":
return (
<div key={row} className="grid grid-cols-2 text-left">
case "date":
return (
<div key={row} className="grid grid-cols-2 text-left">
<span>
{currentRow.title}
{currentRow.tooltip !== undefined && <Tooltip tip={currentRow.tooltip} />}
</span>
<span>{DateFormat.format(new Date(value))}</span>
</div>
);
);
}
},
)
}
})}
</div>
))}
</div>
))}
</Fragment>
);

const Cores = ({ cpu }: { cpu: CPU }) => {
const cores = cpu.cores;
const cores = cpu.cores;

if (cores.performance === null && cores.efficient === null) {
return <span>{cores.total}</span>;
} else if (cores.total === null) {
return <span>Unknown</span>;
}
if (cores.performance === null && cores.efficient === null) {
return <span>{cores.total}</span>;
} else if (cores.total === null) {
return <span>Unknown</span>;
}

return (
<>
return (
<>
{cpu.cores.performance ?? 0}P / {cpu.cores.efficient ?? 0}E
</>
);
};
);
}
;

const Memory = ({ cpu }: { cpu: CPU }) => {
if (cpu.memory.types === null) {
return <>N/A</>;
}
if (cpu.memory.types === null) return <>N/A</>;

return (
<div>
Expand Down Expand Up @@ -285,18 +286,21 @@ const TableStructure: Table = {
path: "graphics.baseFrequency",
type: "number",
unit: "Hz",
hideOnUndefined: true,
},
maxClock: {
title: "Max Clock",
path: "graphics.maxFrequency",
type: "number",
unit: "Hz",
hideOnUndefined: true,
},
display: {
title: "Displays",
path: "graphics.displays",
type: "number",
unit: "",
hideOnUndefined: true,
},
},
Other: {
Expand Down Expand Up @@ -327,7 +331,7 @@ type Row = { title: string; hideOnUndefined?: true; tooltip?: string } & ( // Pr
| { type: "component"; component: ({ cpu }: { cpu: CPU }) => JSX.Element }
| { type: "string"; capitalize?: true; path: string }
| { type: "date"; path: string }
);
);

const traversePath = (path: string, obj: any) => path.split(".").reduce((prev, curr) => prev && prev[curr], obj);

Expand Down
7 changes: 6 additions & 1 deletion src/pages/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ const List = () => {
<input
type="search"
value={query}
onChange={(e) => setQuery(e.target.value)}
onChange={(e) => {
const params = new URLSearchParams(window.location.search);
params.set("q", e.target.value);
window.history.replaceState({}, "", `${window.location.pathname}?${params.toString()}`);
setQuery(e.target.value)
}}
className="h-14 w-1/2 rounded-md border border-gray-400 bg-slate-700 p-2 text-xl text-white shadow-lg"
placeholder="Search for a CPU"
/>
Expand Down
19 changes: 14 additions & 5 deletions src/util/scrapers/amd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const scrapeAMD = async (model: string, noCache: boolean) =>
if (process.env.NODE_ENV === "development") console.log("Fetching page: ", url);

if (specsPage.status !== 200) {
console.error(specsPage.statusText);
console.error("Error:", specsPage.statusText, specsPage.status);
return reject({ message: "Error while fetching the specs page", code: 500 });
}

Expand Down Expand Up @@ -75,10 +75,11 @@ const scrapeAMD = async (model: string, noCache: boolean) =>
graphics:
getParameter("Integrated Graphics") === "Yes"
? {
baseFrequency:
getFloatParameter("Graphics Base Frequency") ?? getFloatParameter("Graphics Frequency"),
maxFrequency: getFloatParameter("Graphics Max Dynamic Frequency"),
displays: getFloatParameter("Max # of Displays Supported"),
baseFrequency: getFloatParameter("GPU Base") ??
getFloatParameter("Graphics Base Frequency") ??
getFloatParameter("Graphics Frequency"),
maxFrequency: getFloatParameter("Graphics Frequency") ?? getFloatParameter("Graphics Max Dynamic Frequency"),
displays: getFloatParameter("Max Displays") ?? getFloatParameter("Max # of Displays Supported"),
}
: false,
pcie: getParameter("PCI Express Revision"),
Expand Down Expand Up @@ -122,6 +123,14 @@ const getLaunchDate = (string: string) => {
if (!string) return "Unknown";
if (/Q\d \d{4}/.test(string)) return string;

// 7/2020
// https://www.amd.com/en/product/9936
if(/\d\/\d{4}/.test(string)) {
const [month, year] = string.split("/");
const quarter = Math.floor((parseInt(month) + 1) / 3) + 1;
return `Q${quarter}'${year.substring(2)}`;
}

const date = new Date(string);

if (date.getFullYear() == 1970) return "Unknown";
Expand Down

1 comment on commit f5d45df

@vercel
Copy link

@vercel vercel bot commented on f5d45df Apr 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.