fix imports
This commit is contained in:
parent
495af0a752
commit
2e2d7baee1
|
@ -6,14 +6,13 @@ export default function LinkDate({
|
||||||
}: {
|
}: {
|
||||||
link: LinkIncludingShortenedCollectionAndTags;
|
link: LinkIncludingShortenedCollectionAndTags;
|
||||||
}) {
|
}) {
|
||||||
const formattedDate = new Date(link.createdAt as string).toLocaleString(
|
const formattedDate = new Date(
|
||||||
"en-US",
|
(link.importDate || link.createdAt) as string
|
||||||
{
|
).toLocaleString("en-US", {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "short",
|
month: "short",
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-1 text-neutral">
|
<div className="flex items-center gap-1 text-neutral">
|
||||||
|
|
|
@ -34,6 +34,8 @@ export default function ReadableView({ link }: Props) {
|
||||||
const [imageError, setImageError] = useState<boolean>(false);
|
const [imageError, setImageError] = useState<boolean>(false);
|
||||||
const [colorPalette, setColorPalette] = useState<RGBColor[]>();
|
const [colorPalette, setColorPalette] = useState<RGBColor[]>();
|
||||||
|
|
||||||
|
const [date, setDate] = useState<Date | string>();
|
||||||
|
|
||||||
const colorThief = new ColorThief();
|
const colorThief = new ColorThief();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -54,6 +56,8 @@ export default function ReadableView({ link }: Props) {
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchLinkContent();
|
fetchLinkContent();
|
||||||
|
|
||||||
|
setDate(link.importDate || link.createdAt);
|
||||||
}, [link]);
|
}, [link]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -211,8 +215,8 @@ export default function ReadableView({ link }: Props) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="min-w-fit text-sm text-neutral">
|
<p className="min-w-fit text-sm text-neutral">
|
||||||
{link?.createdAt
|
{date
|
||||||
? new Date(link?.createdAt).toLocaleString("en-US", {
|
? new Date(date).toLocaleString("en-US", {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "long",
|
month: "long",
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { prisma } from "@/lib/api/db";
|
||||||
import createFolder from "@/lib/api/storage/createFolder";
|
import createFolder from "@/lib/api/storage/createFolder";
|
||||||
import { JSDOM } from "jsdom";
|
import { JSDOM } from "jsdom";
|
||||||
import { parse, Node, Element, TextNode } from "himalaya";
|
import { parse, Node, Element, TextNode } from "himalaya";
|
||||||
|
import { writeFileSync } from "fs";
|
||||||
|
|
||||||
const MAX_LINKS_PER_USER = Number(process.env.MAX_LINKS_PER_USER) || 30000;
|
const MAX_LINKS_PER_USER = Number(process.env.MAX_LINKS_PER_USER) || 30000;
|
||||||
|
|
||||||
|
@ -36,7 +37,9 @@ export default async function importFromHTMLFile(
|
||||||
|
|
||||||
const jsonData = parse(document.documentElement.outerHTML);
|
const jsonData = parse(document.documentElement.outerHTML);
|
||||||
|
|
||||||
for (const item of jsonData) {
|
const processedArray = processNodes(jsonData);
|
||||||
|
|
||||||
|
for (const item of processedArray) {
|
||||||
console.log(item);
|
console.log(item);
|
||||||
await processBookmarks(userId, item as Element);
|
await processBookmarks(userId, item as Element);
|
||||||
}
|
}
|
||||||
|
@ -74,7 +77,9 @@ async function processBookmarks(
|
||||||
} else if (item.type === "element" && item.tagName === "a") {
|
} else if (item.type === "element" && item.tagName === "a") {
|
||||||
// process link
|
// process link
|
||||||
|
|
||||||
const linkUrl = item?.attributes.find((e) => e.key.toLowerCase() === "href")?.value;
|
const linkUrl = item?.attributes.find(
|
||||||
|
(e) => e.key.toLowerCase() === "href"
|
||||||
|
)?.value;
|
||||||
const linkName = (
|
const linkName = (
|
||||||
item?.children.find((e) => e.type === "text") as TextNode
|
item?.children.find((e) => e.type === "text") as TextNode
|
||||||
)?.content;
|
)?.content;
|
||||||
|
@ -83,30 +88,22 @@ async function processBookmarks(
|
||||||
?.value.split(",");
|
?.value.split(",");
|
||||||
|
|
||||||
// set date if available
|
// set date if available
|
||||||
const linkDateValue = item?.attributes.find((e) => e.key.toLowerCase() === "add_date")?.value;
|
const linkDateValue = item?.attributes.find(
|
||||||
let linkDate = Date.now();
|
(e) => e.key.toLowerCase() === "add_date"
|
||||||
if (linkDateValue) {
|
)?.value;
|
||||||
try {
|
|
||||||
linkDate = Number.parseInt(linkDateValue);
|
|
||||||
// use the year 2000 as an arbitrary cutoff to determine if a link is in seconds or milliseconds
|
|
||||||
const year2000ms = 946684800000;
|
|
||||||
if ((linkDate > 0) && (linkDate < year2000ms)) {
|
|
||||||
linkDate = linkDate * 1000; // turn epoch seconds into milliseconds
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// just ignore the error if it happens
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let linkDesc = "";
|
const linkDate = linkDateValue
|
||||||
const descNode = data.children.find((e) => (e as Element).tagName?.toLowerCase() === "dd") as Element;
|
? new Date(Number(linkDateValue) * 1000)
|
||||||
if (descNode && descNode.children.length > 0) {
|
: undefined;
|
||||||
try {
|
|
||||||
linkDesc = (descNode.children[0] as TextNode).content;
|
let linkDesc =
|
||||||
} catch (error) {
|
(
|
||||||
// just ignore the error if it happens
|
(
|
||||||
}
|
item?.children?.find(
|
||||||
}
|
(e) => e.type === "element" && e.tagName === "dd"
|
||||||
|
) as Element
|
||||||
|
)?.children[0] as TextNode
|
||||||
|
)?.content || "";
|
||||||
|
|
||||||
if (linkUrl && parentCollectionId) {
|
if (linkUrl && parentCollectionId) {
|
||||||
await createLink(
|
await createLink(
|
||||||
|
@ -164,10 +161,10 @@ const createCollection = async (
|
||||||
name: collectionName,
|
name: collectionName,
|
||||||
parent: parentId
|
parent: parentId
|
||||||
? {
|
? {
|
||||||
connect: {
|
connect: {
|
||||||
id: parentId,
|
id: parentId,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
owner: {
|
owner: {
|
||||||
connect: {
|
connect: {
|
||||||
|
@ -189,40 +186,81 @@ const createLink = async (
|
||||||
name?: string,
|
name?: string,
|
||||||
description?: string,
|
description?: string,
|
||||||
tags?: string[],
|
tags?: string[],
|
||||||
createdAt?: number,
|
importDate?: Date
|
||||||
) => {
|
) => {
|
||||||
await prisma.link.create({
|
await prisma.link.create({
|
||||||
data: {
|
data: {
|
||||||
name: name || "",
|
name: name || "",
|
||||||
type: url,
|
url,
|
||||||
description: description,
|
description,
|
||||||
collectionId: collectionId,
|
collectionId,
|
||||||
tags:
|
tags:
|
||||||
tags && tags[0]
|
tags && tags[0]
|
||||||
? {
|
? {
|
||||||
connectOrCreate: tags.map((tag: string) => {
|
connectOrCreate: tags.map((tag: string) => {
|
||||||
return (
|
return (
|
||||||
{
|
{
|
||||||
where: {
|
where: {
|
||||||
name_ownerId: {
|
name_ownerId: {
|
||||||
name: tag.trim(),
|
name: tag.trim(),
|
||||||
ownerId: userId,
|
ownerId: userId,
|
||||||
},
|
|
||||||
},
|
|
||||||
create: {
|
|
||||||
name: tag.trim(),
|
|
||||||
owner: {
|
|
||||||
connect: {
|
|
||||||
id: userId,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
create: {
|
||||||
} || undefined
|
name: tag.trim(),
|
||||||
);
|
owner: {
|
||||||
}),
|
connect: {
|
||||||
}
|
id: userId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} || undefined
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
createdAt: createdAt
|
importDate: importDate || undefined,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function processNodes(nodes: Node[]) {
|
||||||
|
const findAndProcessDL = (node: Node) => {
|
||||||
|
if (node.type === "element" && node.tagName === "dl") {
|
||||||
|
processDLChildren(node);
|
||||||
|
} else if (
|
||||||
|
node.type === "element" &&
|
||||||
|
node.children &&
|
||||||
|
node.children.length
|
||||||
|
) {
|
||||||
|
node.children.forEach((child) => findAndProcessDL(child));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const processDLChildren = (dlNode: Element) => {
|
||||||
|
dlNode.children.forEach((child, i) => {
|
||||||
|
if (child.type === "element" && child.tagName === "dt") {
|
||||||
|
const nextSibling = dlNode.children[i + 1];
|
||||||
|
if (
|
||||||
|
nextSibling &&
|
||||||
|
nextSibling.type === "element" &&
|
||||||
|
nextSibling.tagName === "dd"
|
||||||
|
) {
|
||||||
|
const aElement = child.children.find(
|
||||||
|
(el) => el.type === "element" && el.tagName === "a"
|
||||||
|
);
|
||||||
|
if (aElement && aElement.type === "element") {
|
||||||
|
// Add the 'dd' element as a child of the 'a' element
|
||||||
|
aElement.children.push(nextSibling);
|
||||||
|
// Remove the 'dd' from the parent 'dl' to avoid duplicate processing
|
||||||
|
dlNode.children.splice(i + 1, 1);
|
||||||
|
// Adjust the loop counter due to the removal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes.forEach(findAndProcessDL);
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Link" ADD COLUMN "importDate" TIMESTAMP(3);
|
|
@ -128,6 +128,7 @@ model Link {
|
||||||
pdf String?
|
pdf String?
|
||||||
readable String?
|
readable String?
|
||||||
lastPreserved DateTime?
|
lastPreserved DateTime?
|
||||||
|
importDate DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
}
|
}
|
||||||
|
|
Ŝarĝante…
Reference in New Issue