Last active
February 10, 2025 13:23
-
-
Save anpigon/546325e2c44ce978a925e9bb0077e3fa to your computer and use it in GitHub Desktop.
옵시디언 quickAdd 플러그인: yes24 도서 검색 매크로
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const notice = (msg) => new Notice(msg, 5000); | |
const parseDOMFormString = (html) => { | |
return new DOMParser().parseFromString(html, "text/html"); | |
}; | |
const requestHtmlDoc = async (url) => { | |
const response = await request({ url }); | |
return parseDOMFormString(response); | |
}; | |
const searchBooks = async (keyword) => { | |
try { | |
const html = await requestHtmlDoc( | |
"https://m.yes24.com/Search?domain=ALL&query=" + encodeURI(keyword) | |
); | |
const findBookList = html.querySelectorAll("ul#yesSchGList > li.item"); | |
return Array.from(findBookList) | |
.map((item) => { | |
const type = item.querySelector(".gd_res").innerText; | |
if (!/도서|eBook|외서/i.test(type)) { | |
return null; | |
} | |
const linkItem = item.querySelector("a.lnk_item") | |
const title = linkItem.innerText.replace(/(\s이동)$/gi, ""); | |
const link = linkItem.getAttribute("href"); | |
return { | |
type, | |
title, | |
link, | |
author: item.querySelector(".info_auth")?.innerText?.trim(), | |
publisher: item.querySelector(".info_pub")?.innerText?.trim(), | |
}; | |
}) | |
.filter(Boolean); | |
} catch (err) { | |
console.log(err); | |
} | |
return ""; | |
}; | |
const getBookInfo = async (bookUrl) => { | |
try { | |
const infoLink = "https://m.yes24.com" + bookUrl; | |
const doc = await requestHtmlDoc(infoLink); | |
const title = doc | |
.querySelector(".gName > .name") | |
.innerText.replace(":", ":") | |
.replace("?", "?") | |
.trim(); | |
const subtitle = doc | |
.querySelector(".etc > .nameE") | |
.innerText.replace(":", ":") | |
.replace("?", "?") | |
.trim(); | |
const authors = Array.from(doc.querySelectorAll(".authPub > .auth")).map((val) => | |
val.innerText.trim().replace(/\s(저|역)$/g, '') | |
); | |
const publisher = doc.querySelector(".authPub > .pub").innerText.trim(); | |
const publishedDate = moment(doc.querySelector(".authPub > .date").innerText.trim(), "yyyy.MM.DD.").format("yyyy-MM-DD"); | |
const thumbnail = doc.querySelector(".img_bdr > img").getAttribute("src"); | |
const smallThumbnail = thumbnail.replace("/XL", "/S"); | |
const mediumThumbnail = thumbnail.replace("/XL", "/M"); | |
const largeThumbnail = thumbnail.replace("/XL", "/L"); | |
const categories = [ | |
...new Set( | |
Array.from(doc.querySelectorAll("#RelatedCategory ul > li > a")) | |
.map((val) => val.innerText.trim()) | |
.filter((val) => !/선물|위로|응원/.test(val)) | |
), | |
]; | |
const rating = doc.querySelector("#dBotRevw em.rating_num:first-of-type").innerText.trim(); | |
const totalPage = | |
parseInt( | |
Array.from(doc.querySelectorAll("#GoodsBasicInfo dl > dd")) | |
.map((dd) => /\d+쪽/.exec(dd.innerText)?.[0]) | |
.find((e) => e) || '0', | |
10 | |
) || 0; | |
const isbn = doc | |
.querySelector("#GoodsBasicInfo dl:last-of-type > dd") | |
?.innerText.match(/(?<isbn13>\w{13})?[^]*(?<isbn10>\w{10})?/)?.groups || { | |
isbn10: "", | |
isbn13: "", | |
}; | |
const results = { | |
title, | |
subtitle, | |
authors, | |
categories, | |
totalPage, | |
publisher, | |
publishedDate, | |
thumbnail, | |
smallThumbnail, | |
mediumThumbnail, | |
largeThumbnail, | |
infoLink, | |
rating, | |
...isbn, | |
}; | |
console.log(results) | |
return results; | |
} catch (err) { | |
console.log(err); | |
} | |
return {}; | |
}; | |
const replaceIllegalFileNameCharactersInString = (str) => { | |
return str | |
.replace(/[\\,#%&\{\}\/*<>?$\'\":@\[\]\|]*/g, "") | |
.replace(/\s{2,}/g, " "); | |
}; | |
module.exports = async (plugin) => { | |
console.log("Starting..."); | |
const query = await plugin.quickAddApi.inputPrompt( | |
"제목, 저자, 출판사, ISBN 검색" | |
); | |
if (query) { | |
const books = await searchBooks(query); | |
if (!books) { | |
return notice(`"${query}" was not found`); | |
} | |
const pickedBook = await plugin.quickAddApi.suggester( | |
({ type, title, author, publisher }) => | |
`${type} ${title}\n${author}, ${publisher}`, | |
books | |
); | |
const book = await getBookInfo(pickedBook.link); | |
console.log(book); | |
plugin.variables = { | |
...book, | |
fileName: replaceIllegalFileNameCharactersInString(book.title), | |
author: book.authors[0], | |
category: book.categories[1], | |
}; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
안녕하세요! 스크립트 너무 감사합니다...!! 덕분에 옵시디언을 더 만족스럽게 사용하게됐어요🥰🥰🥰
작성주신 스크립트 사용 중 아래와 같은 현상을 발견해서 제보 + 살짝 수정해서 사용중인 코드도 남겨놓고 갑니다!