From e3d9912378d39bf44071f735567c274dc9ee5dd4 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sat, 10 Feb 2024 02:47:58 -0500 Subject: [PATCH 1/5] fixed the imports --- .../migration/importFromHTMLFile.ts | 182 +++++++++++++----- 1 file changed, 139 insertions(+), 43 deletions(-) diff --git a/lib/api/controllers/migration/importFromHTMLFile.ts b/lib/api/controllers/migration/importFromHTMLFile.ts index a2fae27..d47af91 100644 --- a/lib/api/controllers/migration/importFromHTMLFile.ts +++ b/lib/api/controllers/migration/importFromHTMLFile.ts @@ -11,6 +11,8 @@ export default async function importFromHTMLFile( const dom = new JSDOM(rawData); const document = dom.window.document; + // console.log(document.querySelectorAll("A").length); + const bookmarks = document.querySelectorAll("A"); const totalImports = bookmarks.length; @@ -29,49 +31,54 @@ export default async function importFromHTMLFile( }; const folders = document.querySelectorAll("H3"); + let unorganizedCollectionId: number | null = null; + + if (folders.length === 0) { + const unorganizedCollection = await prisma.collection.findFirst({ + where: { + name: "Imported", + ownerId: userId, + }, + }); + + if (!unorganizedCollection) { + const newUnorganizedCollection = await prisma.collection.create({ + data: { + name: "Imported", + description: + "Automatically created collection for imported bookmarks.", + ownerId: userId, + }, + }); + unorganizedCollectionId = newUnorganizedCollection.id; + } else { + unorganizedCollectionId = unorganizedCollection.id; + } + + createFolder({ filePath: `archives/${unorganizedCollectionId}` }); + } await prisma .$transaction( async () => { - // @ts-ignore - for (const folder of folders) { - const findCollection = await prisma.user.findUnique({ - where: { - id: userId, - }, - select: { - collections: { - where: { - name: folder.textContent.trim(), - }, - }, - }, - }); - - const checkIfCollectionExists = findCollection?.collections[0]; - - let collectionId = findCollection?.collections[0]?.id; - - if (!checkIfCollectionExists || !collectionId) { - const newCollection = await prisma.collection.create({ - data: { - name: folder.textContent.trim(), - description: "", - color: "#0ea5e9", - isPublic: false, - ownerId: userId, - }, - }); - - createFolder({ filePath: `archives/${newCollection.id}` }); - - collectionId = newCollection.id; - } - - createFolder({ filePath: `archives/${collectionId}` }); - - const bookmarks = folder.nextElementSibling.querySelectorAll("A"); + if (unorganizedCollectionId) { + // @ts-ignore for (const bookmark of bookmarks) { + // Move up to the parent node (
) and then find the next sibling + let parentDT = bookmark.parentNode; + let nextSibling = parentDT ? parentDT.nextSibling : null; + let description = ""; + + // Loop through siblings to skip any potential text nodes or whitespace + while (nextSibling && nextSibling.nodeType !== 1) { + nextSibling = nextSibling.nextSibling; + } + + // Check if the next sibling element is a
tag and use its content as the description + if (nextSibling && nextSibling.tagName === "DD") { + description = nextSibling.textContent.trim(); + } + await prisma.link.create({ data: { name: bookmark.textContent.trim(), @@ -103,14 +110,103 @@ export default async function importFromHTMLFile( ), } : undefined, - description: bookmark.getAttribute("DESCRIPTION") - ? bookmark.getAttribute("DESCRIPTION") - : "", - collectionId: collectionId, - createdAt: new Date(), + description: description, + collectionId: unorganizedCollectionId, }, }); } + } else { + // @ts-ignore + for (const folder of folders) { + const findCollection = await prisma.user.findUnique({ + where: { + id: userId, + }, + select: { + collections: { + where: { + name: folder.textContent.trim(), + }, + }, + }, + }); + + const checkIfCollectionExists = findCollection?.collections[0]; + + let collectionId = findCollection?.collections[0]?.id; + + if (!checkIfCollectionExists || !collectionId) { + const newCollection = await prisma.collection.create({ + data: { + name: folder.textContent.trim(), + description: "", + color: "#0ea5e9", + isPublic: false, + ownerId: userId, + }, + }); + + createFolder({ filePath: `archives/${newCollection.id}` }); + + collectionId = newCollection.id; + } + + createFolder({ filePath: `archives/${collectionId}` }); + + const bookmarks = folder.nextElementSibling.querySelectorAll("A"); + for (const bookmark of bookmarks) { + // Move up to the parent node (
) and then find the next sibling + let parentDT = bookmark.parentNode; + let nextSibling = parentDT ? parentDT.nextSibling : null; + let description = ""; + + // Loop through siblings to skip any potential text nodes or whitespace + while (nextSibling && nextSibling.nodeType !== 1) { + nextSibling = nextSibling.nextSibling; + } + + // Check if the next sibling element is a
tag and use its content as the description + if (nextSibling && nextSibling.tagName === "DD") { + description = nextSibling.textContent.trim(); + } + + await prisma.link.create({ + data: { + name: bookmark.textContent.trim(), + url: bookmark.getAttribute("HREF"), + tags: bookmark.getAttribute("TAGS") + ? { + connectOrCreate: bookmark + .getAttribute("TAGS") + .split(",") + .map((tag: string) => + tag + ? { + where: { + name_ownerId: { + name: tag.trim(), + ownerId: userId, + }, + }, + create: { + name: tag.trim(), + owner: { + connect: { + id: userId, + }, + }, + }, + } + : undefined + ), + } + : undefined, + description: description, + collectionId: collectionId, + }, + }); + } + } } }, { timeout: 30000 } From c3f72c4be896bf8de3881fc36393182d4421350f Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Wed, 14 Feb 2024 10:35:59 -0500 Subject: [PATCH 2/5] minor cleanup --- .../migration/importFromHTMLFile.ts | 161 +++++++----------- 1 file changed, 59 insertions(+), 102 deletions(-) diff --git a/lib/api/controllers/migration/importFromHTMLFile.ts b/lib/api/controllers/migration/importFromHTMLFile.ts index d47af91..6a8b298 100644 --- a/lib/api/controllers/migration/importFromHTMLFile.ts +++ b/lib/api/controllers/migration/importFromHTMLFile.ts @@ -11,8 +11,6 @@ export default async function importFromHTMLFile( const dom = new JSDOM(rawData); const document = dom.window.document; - // console.log(document.querySelectorAll("A").length); - const bookmarks = document.querySelectorAll("A"); const totalImports = bookmarks.length; @@ -64,56 +62,7 @@ export default async function importFromHTMLFile( if (unorganizedCollectionId) { // @ts-ignore for (const bookmark of bookmarks) { - // Move up to the parent node (
) and then find the next sibling - let parentDT = bookmark.parentNode; - let nextSibling = parentDT ? parentDT.nextSibling : null; - let description = ""; - - // Loop through siblings to skip any potential text nodes or whitespace - while (nextSibling && nextSibling.nodeType !== 1) { - nextSibling = nextSibling.nextSibling; - } - - // Check if the next sibling element is a
tag and use its content as the description - if (nextSibling && nextSibling.tagName === "DD") { - description = nextSibling.textContent.trim(); - } - - await prisma.link.create({ - data: { - name: bookmark.textContent.trim(), - url: bookmark.getAttribute("HREF"), - tags: bookmark.getAttribute("TAGS") - ? { - connectOrCreate: bookmark - .getAttribute("TAGS") - .split(",") - .map((tag: string) => - tag - ? { - where: { - name_ownerId: { - name: tag.trim(), - ownerId: userId, - }, - }, - create: { - name: tag.trim(), - owner: { - connect: { - id: userId, - }, - }, - }, - } - : undefined - ), - } - : undefined, - description: description, - collectionId: unorganizedCollectionId, - }, - }); + createBookmark(userId, bookmark, unorganizedCollectionId); } } else { // @ts-ignore @@ -155,56 +104,7 @@ export default async function importFromHTMLFile( const bookmarks = folder.nextElementSibling.querySelectorAll("A"); for (const bookmark of bookmarks) { - // Move up to the parent node (
) and then find the next sibling - let parentDT = bookmark.parentNode; - let nextSibling = parentDT ? parentDT.nextSibling : null; - let description = ""; - - // Loop through siblings to skip any potential text nodes or whitespace - while (nextSibling && nextSibling.nodeType !== 1) { - nextSibling = nextSibling.nextSibling; - } - - // Check if the next sibling element is a
tag and use its content as the description - if (nextSibling && nextSibling.tagName === "DD") { - description = nextSibling.textContent.trim(); - } - - await prisma.link.create({ - data: { - name: bookmark.textContent.trim(), - url: bookmark.getAttribute("HREF"), - tags: bookmark.getAttribute("TAGS") - ? { - connectOrCreate: bookmark - .getAttribute("TAGS") - .split(",") - .map((tag: string) => - tag - ? { - where: { - name_ownerId: { - name: tag.trim(), - ownerId: userId, - }, - }, - create: { - name: tag.trim(), - owner: { - connect: { - id: userId, - }, - }, - }, - } - : undefined - ), - } - : undefined, - description: description, - collectionId: collectionId, - }, - }); + createBookmark(userId, bookmark, collectionId); } } } @@ -215,3 +115,60 @@ export default async function importFromHTMLFile( return { response: "Success.", status: 200 }; } + +const createBookmark = async ( + userId: number, + bookmark: any, + collectionId: number +) => { + // Move up to the parent node (
) and then find the next sibling + let parentDT = bookmark.parentNode; + let nextSibling = parentDT ? parentDT.nextSibling : null; + let description = ""; + + // Loop through siblings to skip any potential text nodes or whitespace + while (nextSibling && nextSibling.nodeType !== 1) { + nextSibling = nextSibling.nextSibling; + } + + // Check if the next sibling element is a
tag and use its content as the description + if (nextSibling && nextSibling.tagName === "DD") { + description = nextSibling.textContent.trim(); + } + + await prisma.link.create({ + data: { + name: bookmark.textContent.trim(), + url: bookmark.getAttribute("HREF"), + tags: bookmark.getAttribute("TAGS") + ? { + connectOrCreate: bookmark + .getAttribute("TAGS") + .split(",") + .map((tag: string) => + tag + ? { + where: { + name_ownerId: { + name: tag.trim(), + ownerId: userId, + }, + }, + create: { + name: tag.trim(), + owner: { + connect: { + id: userId, + }, + }, + }, + } + : undefined + ), + } + : undefined, + description, + collectionId, + }, + }); +}; From 0e60dee47d4c995fbe9c9a6d3e34c485b10fee39 Mon Sep 17 00:00:00 2001 From: Isaac Wise Date: Thu, 15 Feb 2024 11:26:42 -0600 Subject: [PATCH 3/5] Subcollections when importing --- .../migration/importFromHTMLFile.ts | 152 ++++++++++-------- 1 file changed, 89 insertions(+), 63 deletions(-) diff --git a/lib/api/controllers/migration/importFromHTMLFile.ts b/lib/api/controllers/migration/importFromHTMLFile.ts index 6a8b298..55bbf57 100644 --- a/lib/api/controllers/migration/importFromHTMLFile.ts +++ b/lib/api/controllers/migration/importFromHTMLFile.ts @@ -67,45 +67,12 @@ export default async function importFromHTMLFile( } else { // @ts-ignore for (const folder of folders) { - const findCollection = await prisma.user.findUnique({ - where: { - id: userId, - }, - select: { - collections: { - where: { - name: folder.textContent.trim(), - }, - }, - }, - }); - - const checkIfCollectionExists = findCollection?.collections[0]; - - let collectionId = findCollection?.collections[0]?.id; - - if (!checkIfCollectionExists || !collectionId) { - const newCollection = await prisma.collection.create({ - data: { - name: folder.textContent.trim(), - description: "", - color: "#0ea5e9", - isPublic: false, - ownerId: userId, - }, - }); - - createFolder({ filePath: `archives/${newCollection.id}` }); - - collectionId = newCollection.id; - } - - createFolder({ filePath: `archives/${collectionId}` }); - - const bookmarks = folder.nextElementSibling.querySelectorAll("A"); - for (const bookmark of bookmarks) { - createBookmark(userId, bookmark, collectionId); - } + await createCollectionAndBookmarks( + userId, + folder, + folder.nextElementSibling, + null + ); } } }, @@ -116,6 +83,52 @@ export default async function importFromHTMLFile( return { response: "Success.", status: 200 }; } +const createCollectionAndBookmarks = async ( + userId: number, + folder: any, + folderContent: any, + parentId: number | null +) => { + const findCollection = await prisma.collection.findFirst({ + where: { + name: folder.textContent.trim(), + ownerId: userId, + }, + }); + + const checkIfCollectionExists = findCollection; + let collectionId = findCollection?.id; + + if (!checkIfCollectionExists || !collectionId) { + const newCollection = await prisma.collection.create({ + data: { + name: folder.textContent.trim(), + description: "", + color: "#0ea5e9", + isPublic: false, + ownerId: userId, + parentId + }, + }); + + createFolder({ filePath: `archives/${newCollection.id}` }); + + collectionId = newCollection.id; + } + + createFolder({ filePath: `archives/${collectionId}` }); + + const bookmarks = folderContent.querySelectorAll("A"); + for (const bookmark of bookmarks) { + createBookmark(userId, bookmark, collectionId); + } + + const subfolders = folderContent.querySelectorAll("H3"); + for (const subfolder of subfolders) { + await createCollectionAndBookmarks(userId, subfolder, subfolder.nextElementSibling, collectionId); + } +}; + const createBookmark = async ( userId: number, bookmark: any, @@ -136,39 +149,52 @@ const createBookmark = async ( description = nextSibling.textContent.trim(); } - await prisma.link.create({ - data: { - name: bookmark.textContent.trim(), - url: bookmark.getAttribute("HREF"), - tags: bookmark.getAttribute("TAGS") - ? { + const linkName = bookmark.textContent.trim(); + const linkURL = bookmark.getAttribute("HREF"); + + const existingLink = await prisma.link.findFirst({ + where: { + url: linkURL, + collectionId + }, + }); + + // Create the link only if it doesn't already exist + if (!existingLink) { + await prisma.link.create({ + data: { + name: linkName, + url: linkURL, + tags: bookmark.getAttribute("TAGS") + ? { connectOrCreate: bookmark .getAttribute("TAGS") .split(",") .map((tag: string) => tag ? { - where: { - name_ownerId: { - name: tag.trim(), - ownerId: userId, - }, - }, - create: { + where: { + data: { name: tag.trim(), - owner: { - connect: { - id: userId, - }, + ownerId: userId, + }, + }, + create: { + name: tag.trim(), + owner: { + connect: { + id: userId, }, }, - } + }, + } : undefined ), } - : undefined, - description, - collectionId, - }, - }); -}; + : undefined, + description, + collectionId, + }, + }); + } +}; \ No newline at end of file From 7b7b979b209bfc776e978d5b8b4404072c26c327 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sat, 17 Feb 2024 20:08:34 -0500 Subject: [PATCH 4/5] refactored import and add support for subcollections --- .../migration/importFromHTMLFile.ts | 281 +++++++++--------- package.json | 1 + prisma/schema.prisma | 1 - types/himalaya.d.ts | 22 ++ yarn.lock | 5 + 5 files changed, 174 insertions(+), 136 deletions(-) create mode 100644 types/himalaya.d.ts diff --git a/lib/api/controllers/migration/importFromHTMLFile.ts b/lib/api/controllers/migration/importFromHTMLFile.ts index 55bbf57..c557133 100644 --- a/lib/api/controllers/migration/importFromHTMLFile.ts +++ b/lib/api/controllers/migration/importFromHTMLFile.ts @@ -1,6 +1,7 @@ import { prisma } from "@/lib/api/db"; import createFolder from "@/lib/api/storage/createFolder"; import { JSDOM } from "jsdom"; +import { parse, Node, Element, TextNode } from "himalaya"; const MAX_LINKS_PER_USER = Number(process.env.MAX_LINKS_PER_USER) || 30000; @@ -11,6 +12,11 @@ export default async function importFromHTMLFile( const dom = new JSDOM(rawData); const document = dom.window.document; + // remove bad tags + document.querySelectorAll("meta").forEach((e) => (e.outerHTML = e.innerHTML)); + document.querySelectorAll("META").forEach((e) => (e.outerHTML = e.innerHTML)); + document.querySelectorAll("P").forEach((e) => (e.outerHTML = e.innerHTML)); + const bookmarks = document.querySelectorAll("A"); const totalImports = bookmarks.length; @@ -28,153 +34,161 @@ export default async function importFromHTMLFile( status: 400, }; - const folders = document.querySelectorAll("H3"); - let unorganizedCollectionId: number | null = null; + const jsonData = parse(document.documentElement.outerHTML); - if (folders.length === 0) { - const unorganizedCollection = await prisma.collection.findFirst({ - where: { - name: "Imported", - ownerId: userId, - }, - }); + // console.log(jsonData); - if (!unorganizedCollection) { - const newUnorganizedCollection = await prisma.collection.create({ - data: { - name: "Imported", - description: - "Automatically created collection for imported bookmarks.", - ownerId: userId, - }, - }); - unorganizedCollectionId = newUnorganizedCollection.id; - } else { - unorganizedCollectionId = unorganizedCollection.id; - } - - createFolder({ filePath: `archives/${unorganizedCollectionId}` }); + for (const item of jsonData) { + console.log(item); + await processBookmarks(userId, item as Element); } - await prisma - .$transaction( - async () => { - if (unorganizedCollectionId) { - // @ts-ignore - for (const bookmark of bookmarks) { - createBookmark(userId, bookmark, unorganizedCollectionId); - } - } else { - // @ts-ignore - for (const folder of folders) { - await createCollectionAndBookmarks( - userId, - folder, - folder.nextElementSibling, - null - ); - } - } - }, - { timeout: 30000 } - ) - .catch((err) => console.log(err)); - return { response: "Success.", status: 200 }; } -const createCollectionAndBookmarks = async ( +async function processBookmarks( userId: number, - folder: any, - folderContent: any, - parentId: number | null + data: Node, + parentCollectionId?: number +) { + if (data.type === "element") { + for (const item of data.children) { + if (item.type === "element" && item.tagName === "dt") { + let collectionId; + const collectionName = item.children.find( + (e) => e.type === "element" && e.tagName === "h3" + ) as Element; + + console.log("collection:", item); + console.log("collectionName:", collectionName); + + // This is a collection or sub-collection + if (collectionName) { + collectionId = await createCollection( + userId, + (collectionName.children[0] as TextNode).content, + parentCollectionId + ); + } + await processBookmarks( + userId, + item, + collectionId || parentCollectionId + ); + } else if (item.type === "element" && item.tagName === "a") { + // This is a link + + // get link href + const linkUrl = item?.attributes.find((e) => e.key === "href")?.value; + + // get link name + const linkName = ( + item?.children.find((e) => e.type === "text") as TextNode + )?.content; + + // get link tags + const linkTags = item?.attributes + .find((e) => e.key === "tags") + ?.value.split(","); + + console.log("link:", item); + + if (linkUrl && parentCollectionId) { + await createLink( + userId, + linkUrl, + parentCollectionId, + linkName, + "", + linkTags + ); + } else if (linkUrl) { + // create a collection named "Imported Bookmarks" and add the link to it + const collectionId = await createCollection(userId, "Imports"); + + await createLink( + userId, + linkUrl, + collectionId, + linkName, + "", + linkTags + ); + } + + await processBookmarks(userId, item, parentCollectionId); + } else { + // This could be anything else + await processBookmarks(userId, item, parentCollectionId); + } + + // Add more conditions as necessary based on your JSON structure + } + } +} + +const createCollection = async ( + userId: number, + collectionName: string, + parentId?: number ) => { const findCollection = await prisma.collection.findFirst({ where: { - name: folder.textContent.trim(), + parentId, + name: collectionName, ownerId: userId, }, }); - const checkIfCollectionExists = findCollection; - let collectionId = findCollection?.id; + if (findCollection) { + return findCollection.id; + } - if (!checkIfCollectionExists || !collectionId) { - const newCollection = await prisma.collection.create({ - data: { - name: folder.textContent.trim(), - description: "", - color: "#0ea5e9", - isPublic: false, - ownerId: userId, - parentId + const collectionId = await prisma.collection.create({ + data: { + name: collectionName, + parent: parentId + ? { + connect: { + id: parentId, + }, + } + : undefined, + owner: { + connect: { + id: userId, + }, }, - }); - - createFolder({ filePath: `archives/${newCollection.id}` }); - - collectionId = newCollection.id; - } - - createFolder({ filePath: `archives/${collectionId}` }); - - const bookmarks = folderContent.querySelectorAll("A"); - for (const bookmark of bookmarks) { - createBookmark(userId, bookmark, collectionId); - } - - const subfolders = folderContent.querySelectorAll("H3"); - for (const subfolder of subfolders) { - await createCollectionAndBookmarks(userId, subfolder, subfolder.nextElementSibling, collectionId); - } -}; - -const createBookmark = async ( - userId: number, - bookmark: any, - collectionId: number -) => { - // Move up to the parent node (
) and then find the next sibling - let parentDT = bookmark.parentNode; - let nextSibling = parentDT ? parentDT.nextSibling : null; - let description = ""; - - // Loop through siblings to skip any potential text nodes or whitespace - while (nextSibling && nextSibling.nodeType !== 1) { - nextSibling = nextSibling.nextSibling; - } - - // Check if the next sibling element is a
tag and use its content as the description - if (nextSibling && nextSibling.tagName === "DD") { - description = nextSibling.textContent.trim(); - } - - const linkName = bookmark.textContent.trim(); - const linkURL = bookmark.getAttribute("HREF"); - - const existingLink = await prisma.link.findFirst({ - where: { - url: linkURL, - collectionId }, }); - // Create the link only if it doesn't already exist - if (!existingLink) { - await prisma.link.create({ - data: { - name: linkName, - url: linkURL, - tags: bookmark.getAttribute("TAGS") + createFolder({ filePath: `archives/${collectionId.id}` }); + + return collectionId.id; +}; + +const createLink = async ( + userId: number, + url: string, + collectionId: number, + name?: string, + description?: string, + tags?: string[] +) => { + await prisma.link.create({ + data: { + name: name || "", + url, + description, + collectionId, + tags: + tags && tags[0] ? { - connectOrCreate: bookmark - .getAttribute("TAGS") - .split(",") - .map((tag: string) => - tag - ? { + connectOrCreate: tags.map((tag: string) => { + return ( + { where: { - data: { + name_ownerId: { name: tag.trim(), ownerId: userId, }, @@ -187,14 +201,11 @@ const createBookmark = async ( }, }, }, - } - : undefined - ), - } + } || undefined + ); + }), + } : undefined, - description, - collectionId, - }, - }); - } -}; \ No newline at end of file + }, + }); +}; diff --git a/package.json b/package.json index 8e741fc..7199f79 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "eslint-config-next": "13.4.9", "formidable": "^3.5.1", "framer-motion": "^10.16.4", + "himalaya": "^1.1.0", "jimp": "^0.22.10", "jsdom": "^22.1.0", "lottie-web": "^5.12.2", diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 8cfa7b3..036f658 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -165,4 +165,3 @@ model AccessToken { createdAt DateTime @default(now()) updatedAt DateTime @default(now()) @updatedAt } - diff --git a/types/himalaya.d.ts b/types/himalaya.d.ts new file mode 100644 index 0000000..e2bd5e0 --- /dev/null +++ b/types/himalaya.d.ts @@ -0,0 +1,22 @@ +declare module "himalaya" { + export interface Attribute { + key: string; + value: string; + } + + export interface TextNode { + type: "text"; + content: string; + } + + export type Node = TextNode | Element; + + export interface Element { + type: "element"; + tagName: string; + attributes: Attribute[]; + children: Node[]; + } + + export function parse(html: string): Node[]; +} diff --git a/yarn.lock b/yarn.lock index 4ef5d2e..7f3b8b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3713,6 +3713,11 @@ hexoid@^1.0.0: resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-1.0.0.tgz#ad10c6573fb907de23d9ec63a711267d9dc9bc18" integrity sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g== +himalaya@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/himalaya/-/himalaya-1.1.0.tgz#31724ae9d35714cd7c6f4be94888953f3604606a" + integrity sha512-LLase1dHCRMel68/HZTFft0N0wti0epHr3nNY7ynpLbyZpmrKMQ8YIpiOV77TM97cNpC8Wb2n6f66IRggwdWPw== + hoist-non-react-statics@^3.3.1: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" From 72266d1cd509983b80f8b282bf7ea388c3afa54f Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sun, 18 Feb 2024 11:07:50 -0500 Subject: [PATCH 5/5] final touch --- .../migration/importFromHTMLFile.ts | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/lib/api/controllers/migration/importFromHTMLFile.ts b/lib/api/controllers/migration/importFromHTMLFile.ts index c557133..4398600 100644 --- a/lib/api/controllers/migration/importFromHTMLFile.ts +++ b/lib/api/controllers/migration/importFromHTMLFile.ts @@ -36,8 +36,6 @@ export default async function importFromHTMLFile( const jsonData = parse(document.documentElement.outerHTML); - // console.log(jsonData); - for (const item of jsonData) { console.log(item); await processBookmarks(userId, item as Element); @@ -54,15 +52,13 @@ async function processBookmarks( if (data.type === "element") { for (const item of data.children) { if (item.type === "element" && item.tagName === "dt") { + // process collection or sub-collection + let collectionId; const collectionName = item.children.find( (e) => e.type === "element" && e.tagName === "h3" ) as Element; - console.log("collection:", item); - console.log("collectionName:", collectionName); - - // This is a collection or sub-collection if (collectionName) { collectionId = await createCollection( userId, @@ -76,23 +72,16 @@ async function processBookmarks( collectionId || parentCollectionId ); } else if (item.type === "element" && item.tagName === "a") { - // This is a link + // process link - // get link href const linkUrl = item?.attributes.find((e) => e.key === "href")?.value; - - // get link name const linkName = ( item?.children.find((e) => e.type === "text") as TextNode )?.content; - - // get link tags const linkTags = item?.attributes .find((e) => e.key === "tags") ?.value.split(","); - console.log("link:", item); - if (linkUrl && parentCollectionId) { await createLink( userId, @@ -118,11 +107,9 @@ async function processBookmarks( await processBookmarks(userId, item, parentCollectionId); } else { - // This could be anything else + // process anything else await processBookmarks(userId, item, parentCollectionId); } - - // Add more conditions as necessary based on your JSON structure } } }