From 6ad5df2bfc9b7da35176f2450c8ba76c05ab8a18 Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Fri, 26 Oct 2018 16:07:53 -0400 Subject: [PATCH] Implemented #30 (a given list site link can add that title to every list site) which unblocks #9 (search) --- anilist/anilist.js | 68 ++++++++++++++++++++++++++ anilist/query.js | 4 +- kitsu/kitsu.js | 88 ++++++++++++++++++++++++++------- menu.js | 119 +++++++++++++++++++++++---------------------- 4 files changed, 202 insertions(+), 77 deletions(-) diff --git a/anilist/anilist.js b/anilist/anilist.js index d9e5ec3..a4df361 100644 --- a/anilist/anilist.js +++ b/anilist/anilist.js @@ -15,6 +15,74 @@ const matchOnAniList = (url) => { return false; }; +// eslint-disable-next-line no-unused-vars +const matchOnAniListFromMAL = async (urlData) => { + const query = { + "query": ` + query matchFromMAL($type: MediaType, $id: Int) { + Media(type: $type, idMal: $id) { + id + type + } + }`, + "variables": { + "type": urlData.type.toUpperCase(), + "id": urlData.id, + }, + "operationName": "matchFromMAL", + }; + + let data = null; + let errors = null; + try { + // eslint-disable-next-line no-undef + [data, errors] = await sendAniListQuery(null, query); + } catch (e) { + console.log("Unsuccessfully made request", e); + return false; + } + + if (errors) { + return false; + } + + return { "type": data.Media.type, "id": data.Media.id }; +}; + +// eslint-disable-next-line no-unused-vars +const matchOnMALFromAniList = async (urlData) => { + const query = { + "query": ` + query matchOnMAL($type: MediaType, $id: Int) { + Media(type: $type, id: $id) { + idMal + type + } + }`, + "variables": { + "type": urlData.type.toUpperCase(), + "id": urlData.id, + }, + "operationName": "matchOnMAL", + }; + + let data = null; + let errors = null; + try { + // eslint-disable-next-line no-undef + [data, errors] = await sendAniListQuery(null, query); + } catch (e) { + console.log("Unsuccessfully made request", e); + return false; + } + + if (errors) { + return false; + } + + return { "type": data.Media.type.toLowerCase(), "id": data.Media.idMal }; +}; + // eslint-disable-next-line no-unused-vars const handleAniList = async (tab, urlData, options) => { const queryRetrieveNotes = { diff --git a/anilist/query.js b/anilist/query.js index 835baf9..e67a3f3 100644 --- a/anilist/query.js +++ b/anilist/query.js @@ -6,11 +6,13 @@ const sendAniListQuery = async (accessToken, query) => { const urlOptions = { "method": "POST", "headers": { - "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json", "Accept": "application/json", }, }; + if (accessToken) { + urlOptions.headers.Authorization = `Bearer ${accessToken}`; + } urlOptions.body = JSON.stringify(query); const retrieve = await fetch(url, urlOptions); diff --git a/kitsu/kitsu.js b/kitsu/kitsu.js index ae01678..613d5b6 100644 --- a/kitsu/kitsu.js +++ b/kitsu/kitsu.js @@ -1,30 +1,17 @@ /* eslint no-console: "off" */ -// eslint-disable-next-line no-unused-vars -const matchOnKitsu = (url) => { - const matchKitsu = url.match(/^https?:\/\/(?:www\.)?kitsu\.io\/(anime|manga)\/(.*)$/); - if (matchKitsu) { - const urlData = { - "type": matchKitsu[1], - "name": matchKitsu[2], - }; - console.log("Kitsu match success"); - console.log(`${urlData.type} ${urlData.name}`); - return urlData; - } - return false; -}; - const sendKitsuQuery = async (accessToken, method, query, body) => { - const url = `https://kitsu.io/api/edge/${query}`; + const url = query.startsWith("https") ? query : `https://kitsu.io/api/edge/${query}`; const urlOptions = { "method": method, "headers": { - "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/vnd.api+json", "Accept": "application/vnd.api+json", }, }; + if (accessToken) { + urlOptions.headers.Authorization = `Bearer ${accessToken}`; + } if (body) { urlOptions.body = JSON.stringify(body); } @@ -43,6 +30,73 @@ const sendKitsuQuery = async (accessToken, method, query, body) => { return [data, meta, errors]; }; +// eslint-disable-next-line no-unused-vars +const matchOnKitsu = (url) => { + const matchKitsu = url.match(/^https?:\/\/(?:www\.)?kitsu\.io\/(anime|manga)\/(.*)$/); + if (matchKitsu) { + const urlData = { + "type": matchKitsu[1], + "name": matchKitsu[2], + }; + console.log("Kitsu match success"); + console.log(`${urlData.type} ${urlData.name}`); + return urlData; + } + return false; +}; + +// eslint-disable-next-line no-unused-vars +const matchOnKitsuFromMAL = async (urlData) => { + let data = null; + // eslint-disable-next-line no-unused-vars + let meta = null; + let errors = null; + try { + [data, meta, errors] = await sendKitsuQuery(null, "GET", + `mappings?filter[externalSite]=myanimelist/${urlData.type.toLowerCase()}&filter[externalId]=${urlData.id}`); + if (errors) { + return false; + } + + [data, meta, errors] = await sendKitsuQuery(null, "GET", data[0].relationships.item.links.related); + if (errors) { + return false; + } + + return { "type": data.type, "name": data.attributes.slug }; + } catch (e) { + console.log("Unsuccessfully made request", e); + return false; + } +}; + +// eslint-disable-next-line no-unused-vars +const matchOnMALFromKitsu = async (urlData) => { + let data = null; + // eslint-disable-next-line no-unused-vars + let meta = null; + let errors = null; + + try { + [data, meta, errors] = await sendKitsuQuery(null, "GET", `${urlData.type}?filter[slug]=${urlData.name}`); + if (errors) { + return false; + } + + [data, meta, errors] = await sendKitsuQuery(null, "GET", data[0].relationships.mappings.links.related); + if (errors) { + return false; + } + + const mal = data.filter((mapping) => mapping.attributes.externalSite.startsWith("myanimelist"))[0]; + + return { "type": mal.attributes.externalSite.substring(12), "id": mal.attributes.externalId }; + } catch (e) { + console.log("Unsuccessfully made request", e); + return false; + } +}; + // eslint-disable-next-line no-unused-vars const handleKitsu = async (tab, urlData, options) => { if (options.accessToken === null) { diff --git a/menu.js b/menu.js index 01d2c11..37f95d0 100644 --- a/menu.js +++ b/menu.js @@ -70,29 +70,28 @@ browser.contextMenus.removeAll() } }); - const Sites = Object.freeze({ - "mal": Symbol("MyAnimeList"), - "anilist": Symbol("AniList"), - "kitsu": Symbol("Kitsu"), - }); - - const validateAndMineURL = (url, notIgnoring) => { - const matchFuncs = { - "mal": matchOnMAL, // eslint-disable-line no-undef - "anilist": matchOnAniList, // eslint-disable-line no-undef - "kitsu": matchOnKitsu, // eslint-disable-line no-undef - }; - - // eslint-disable-next-line no-restricted-syntax - for (const site of Object.keys(matchFuncs)) { - const match = matchFuncs[site](url); - if (match) { - match.source = Sites[site]; - match.notIgnoring = notIgnoring[site]; - return match; - } + const validateAndMineURL = async (url) => { + let match = matchOnMAL(url); // eslint-disable-line no-undef + if (match) { + const urlData = { "mal": match }; + urlData.anilist = await matchOnAniListFromMAL(urlData.mal); // eslint-disable-line no-undef + urlData.kitsu = await matchOnKitsuFromMAL(urlData.mal); // eslint-disable-line no-undef + return urlData; + } + match = matchOnAniList(url); // eslint-disable-line no-undef + if (match) { + const urlData = { "anilist": match }; + urlData.mal = await matchOnMALFromAniList(urlData.anilist); // eslint-disable-line no-undef + urlData.kitsu = await matchOnKitsuFromMAL(urlData.mal); // eslint-disable-line no-undef + return urlData; + } + match = matchOnKitsu(url); // eslint-disable-line no-undef + if (match) { + const urlData = { "kitsu": match }; + urlData.mal = await matchOnMALFromKitsu(urlData.kitsu); // eslint-disable-line no-undef + urlData.anilist = await matchOnAniListFromMAL(urlData.mal); // eslint-disable-line no-undef + return urlData; } - return false; }; @@ -114,43 +113,45 @@ browser.contextMenus.removeAll() } console.log(`Link URL: ${info.linkUrl}`); console.log(`Tab URL: ${tab.url}`); - const notIgnoring = { - "mal": options.checkbox.mal_mal, - "anilist": options.checkbox.anilist_anilist, - "kitsu": options.checkbox.kitsu_kitsu, - }; - const urlData = validateAndMineURL(info.linkUrl, notIgnoring); - if (urlData && !urlData.notIgnoring) { - console.log("Match ignored"); - createNotification({ - "title": "Ignoring list site", - "message": `PTW Extender is currently set to ignore ${urlData.source - .toString().slice(7, -1)}`, - }); - } else if (urlData && urlData.source === Sites.mal) { - // eslint-disable-next-line no-undef - createNotification(await handleMAL(tab, urlData, { - "prettifyCommentsBox": options.checkbox.extension_prettifyCommentsBox, - "autosubmit": options.checkbox.mal_autosubmit, - "behaviorPostAutosubmit": options.radio.mal_behaviorPostAutosubmit, - "priority": options.radio.mal_priority, - "tags": options.textarea.mal_tags, - })); - } else if (urlData && urlData.source === Sites.anilist) { - // eslint-disable-next-line no-undef - createNotification(await handleAniList(tab, urlData, { - "accessToken": optionsLocal.authentication.anilist.accessToken, - "private": options.checkbox.anilist_private, - "hiddenFromStatusLists": options.checkbox.anilist_hiddenFromStatusLists, - "customListsAnime": options.multipleCheckbox.anilist_customListsAnime, - "customListsManga": options.multipleCheckbox.anilist_customListsManga, - })); - } else if (urlData && urlData.source === Sites.kitsu) { - // eslint-disable-next-line no-undef - createNotification(await handleKitsu(tab, urlData, { - "accessToken": optionsLocal.authentication.kitsu.accessToken, - "private": options.checkbox.kitsu_private, - })); + const urlData = await validateAndMineURL(info.linkUrl); + if (urlData) { + const notIgnoring = { + "mal": options.checkbox.mal_mal, + "anilist": options.checkbox.anilist_anilist, + "kitsu": options.checkbox.kitsu_kitsu, + }; + let message = ""; + if (urlData.mal && notIgnoring.mal) { + // eslint-disable-next-line no-undef + const handled = await handleMAL(tab, urlData.mal, { + "prettifyCommentsBox": options.checkbox.extension_prettifyCommentsBox, + "autosubmit": options.checkbox.mal_autosubmit, + "behaviorPostAutosubmit": options.radio.mal_behaviorPostAutosubmit, + "priority": options.radio.mal_priority, + "tags": options.textarea.mal_tags, + }); + message = message.concat(handled.title, ": ", handled.message, "\n"); + } + if (urlData.anilist && notIgnoring.anilist) { + // eslint-disable-next-line no-undef + const handled = await handleAniList(tab, urlData.anilist, { + "accessToken": optionsLocal.authentication.anilist.accessToken, + "private": options.checkbox.anilist_private, + "hiddenFromStatusLists": options.checkbox.anilist_hiddenFromStatusLists, + "customListsAnime": options.multipleCheckbox.anilist_customListsAnime, + "customListsManga": options.multipleCheckbox.anilist_customListsManga, + }); + message = message.concat(handled.title, ": ", handled.message, "\n"); + } + if (urlData.kitsu && notIgnoring.kitsu) { + // eslint-disable-next-line no-undef + const handled = await handleKitsu(tab, urlData.kitsu, { + "accessToken": optionsLocal.authentication.kitsu.accessToken, + "private": options.checkbox.kitsu_private, + }); + message = message.concat(handled.title, ": ", handled.message, "\n"); + } + createNotification({ "title": "PTW extending results", "message": message }); } else { console.log("Match fail"); createNotification({