Created
February 4, 2022 14:01
-
-
Save chelming/b8e4e58e6ad6d99f3380dda36f5de626 to your computer and use it in GitHub Desktop.
quickadd macro for interfacing with Komga
This file contains 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 log = (msg) => console.log(msg); | |
const API_URL_OPTION = "Komga URL"; | |
const API_USER_OPTION = "Username"; | |
const API_PASS_OPTION = "Password"; | |
module.exports = { | |
entry: start, | |
settings: { | |
name: "Komga Importer", | |
author: "Chris Helming", | |
options: { | |
[API_URL_OPTION]: { | |
type: "text", | |
defaultValue: "", | |
placeholder: "https://komga.example.com", | |
}, | |
[API_USER_OPTION]: { | |
type: "text", | |
defaultValue: "", | |
placeholder: "Username", | |
}, | |
[API_PASS_OPTION]: { | |
type: "text", | |
defaultValue: "", | |
placeholder: "Password", | |
secret: true, | |
}, | |
}, | |
}, | |
}; | |
let QuickAdd; | |
let Settings; | |
async function start(params, settings) { | |
QuickAdd = params; | |
Settings = settings; | |
if (!Settings[API_URL_OPTION] || !Settings[API_USER_OPTION] || !Settings[API_PASS_OPTION]) { | |
notice("Please fill out the macro API settings."); | |
throw new Error("No macro selected."); | |
} | |
Settings[API_URL_OPTION] = Settings[API_URL_OPTION].replace(/\/?$/, '/'); | |
const query = await QuickAdd.quickAddApi.inputPrompt( | |
"Comic name (blank for recent): " | |
); | |
let results; | |
if (!query) { | |
results = await getRecents(); | |
} | |
else { | |
results = await getByQuery(query); | |
} | |
const choice = await QuickAdd.quickAddApi.suggester( | |
results.map(formatTitleForSuggestion), | |
results | |
); | |
if (!choice) { | |
notice("No choice selected."); | |
throw new Error("No choice selected."); | |
} | |
const colorers = linkifyList(getAuthors(choice, 'colorist')); | |
const coverArtists = linkifyList(getAuthors(choice, 'cover')); | |
const editors = linkifyList(getAuthors(choice, 'editor')); | |
const inkers = linkifyList(getAuthors(choice, 'inker')); | |
const pencillers = linkifyList(getAuthors(choice, 'penciller')); | |
const writers = linkifyList(getAuthors(choice, 'writer')); | |
QuickAdd.variables = { | |
...choice, | |
colorersLinks: colorers || ' ', | |
coverArtistsLinks: coverArtists || ' ', | |
editorsLinks: editors || ' ', | |
fileName: replaceIllegalFileNameCharactersInString(choice.name) || ' ', | |
inkersLinks: inkers || ' ', | |
KomgaURL: `${Settings[API_URL_OPTION]}series/${choice.id}`, | |
pencillersLinks: pencillers || ' ', | |
publisherLink: `[[${choice.metadata.publisher ? choice.metadata.publisher : "Unknown Publisher"}]]`, | |
summary: choice.booksMetadata.summary || ' ', | |
title: `[[${choice.metadata.title.replace(/ \(\d{1,2}\)/,'')}]]`, | |
writersLinks: writers || ' ', | |
Year: choice.booksMetadata.releaseDate?.split('-')[0] || ' ', | |
}; | |
} | |
function getAuthors(choice, role) { | |
const roleArray = [...new Set(choice.booksMetadata.authors.filter(a => a.role == role).map(a => `@${a.name}`))] | |
return roleArray.sort((a, b) => (a.name > b.name) ? 1 : -1);; | |
} | |
function formatTitleForSuggestion(resultItem) { | |
const name = resultItem.name; | |
const issue = `${resultItem.booksCount} ${resultItem.booksCount == 1 ? "issue" : 'issues'}`; | |
const pub = resultItem.metadata.publisher ? resultItem.metadata.publisher : "Unknown"; | |
return `${name} (${issue}) (${pub})`; | |
} | |
async function getRecents() { | |
const endpoint = 'api/v1/books?read_status=READ&read_status=IN_PROGRESS&sort=readProgress.readDate%2Cdesc' | |
const searchResults = await apiGet(Settings[API_URL_OPTION] + endpoint, {}); | |
if (!searchResults.content || !searchResults.content.length) { | |
notice("No results found."); | |
throw new Error("No results found."); | |
} | |
const seriesIds = searchResults.content.map(a => a.seriesId); | |
const uniqueSeries = [...new Set(seriesIds)] | |
let seriesResults = []; | |
for (const series of uniqueSeries) { | |
seriesResults.push(await getSeries(series)); | |
} | |
return seriesResults; | |
} | |
async function getSeries(id) { | |
const endpoint = 'api/v1/series/' + id; | |
const searchResults = await apiGet(Settings[API_URL_OPTION] + endpoint, {}); | |
return searchResults; | |
} | |
async function getByQuery(query) { | |
const endpoint = 'api/v1/series'; | |
const searchResults = await apiGet(Settings[API_URL_OPTION] + endpoint, { | |
search: query, | |
unpaged: true, | |
}); | |
if (!searchResults.content || !searchResults.content.length) { | |
notice("No results found."); | |
throw new Error("No results found."); | |
} | |
return searchResults.content.sort((a, b) => (a.name > b.name) ? 1 : -1); | |
} | |
function linkifyList(list) { | |
if (list.length === 0) return ""; | |
if (list.length === 1) return `[[${list[0]}]]`; | |
return list.map((item) => `[[${item.trim()}]]`).join(", "); | |
} | |
function replaceIllegalFileNameCharactersInString(string) { | |
return string.replace(/[\\,#%&\{\}\/*<>$\'\":@]*/g, ""); | |
} | |
async function apiGet(url, data) { | |
let finalURL = new URL(url); | |
if (data) | |
Object.keys(data).forEach((key) => | |
finalURL.searchParams.append(key, data[key]) | |
); | |
const auth = "Basic " + new Buffer(Settings[API_USER_OPTION] + ":" + Settings[API_PASS_OPTION]).toString("base64"); | |
const res = await request({ | |
url: finalURL.href, | |
method: "GET", | |
cache: "no-cache", | |
headers: { | |
Authorization: auth | |
} | |
}); | |
return JSON.parse(res); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment