From f7661a839d2b6c2091819089aea7ee3dcca20d80 Mon Sep 17 00:00:00 2001 From: Lauchmelder Date: Sun, 20 Mar 2022 01:04:30 +0100 Subject: [PATCH] auto sync, wanikani subscription check --- background.js | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++ content.js | 7 ++- 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 background.js diff --git a/background.js b/background.js new file mode 100644 index 0000000..caa3d3e --- /dev/null +++ b/background.js @@ -0,0 +1,119 @@ +const query = (token, url) => + new Promise(async (resolve, reject) => { + const requestHeaders = new Headers() + requestHeaders.append("Authorization", "Bearer " + token) + + const endpoint = new Request( + url, + { + method: "GET", + headers: requestHeaders + } + ) + + var result = await fetch(endpoint) + if(!result.ok) + { + var message = await result.json() + return reject(message.error + " (" + message.code + ")") + } + + return resolve(result.json()) + }) + +const updateCache = async (token, oldLevel, newLevel) => { + if(oldLevel === undefined) + oldLevel = 1 + + var levelArray = [] + for(var i = oldLevel; i < newLevel; i++) + levelArray.push(i) + + var levelURLString = levelArray.join(",") + + var url = "https://api.wanikani.com/v2/subjects?types=vocabulary&levels=" + levelURLString + var vocabulary = [] + + do + { + var response = await query(token, url).catch(reason => console.error("WaniKani API request failed: " + reason)) + if(response === undefined) + break + + for(let i in response.data) + vocabulary.push(response.data[i].data.characters) + + url = response.pages.next_url + } while(url !== null) + + var url = "https://api.wanikani.com/v2/subjects?types=kanji&levels=" + levelURLString + var kanji = [] + + do + { + var response = await query(token, url).catch(reason => console.error("WaniKani API request failed: " + reason)) + if(response === undefined) + break + + for(let i in response.data) + kanji.push(response.data[i].data.characters) + + url = response.pages.next_url + } while(url !== null) + + if(oldLevel < newLevel) + { + await chrome.storage.local.get(["vocabulary", "kanji"], (data) => { + vocabulary.concat(data.vocabulary) + kanji.concat(data.kanji) + }) + } + + chrome.storage.local.set({ + "vocabulary": vocabulary, + "kanji": kanji + }) + + chrome.storage.local.set({"level": newLevel}); +} + +const sync = () => + new Promise((resolve, reject) => { + chrome.storage.local.get(["level", "token"], async (data) => { + const apiTokenPattern = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/ + if(!apiTokenPattern.test(data.token)) + return reject("Please set a valid WaniKani API Token") + + var user = await query(data.token, "https://api.wanikani.com/v2/user").catch(reason => reject("WaniKani API request failed: " + reason)) + + if(user === undefined) + return + + level = user.data.level + + chrome.storage.local.set({"validUserLevel": level <= user.data.subscription.max_level_granted}) + + if(level > user.data.subscription.max_level_granted) + return reject("User account level exceeds account level limit") + + if(level !== data.level) + updateCache(data.token, data.level, level) + + resolve("Successfully synchronized data!") + }) + }) + +chrome.runtime.onMessage.addListener((data, sender, sendResponse) => { + if(data.type === "sync") + sync() + .then(value => { + sendResponse({success: true}) + }) + .catch(reason => { + sendResponse({success: false, error: reason}) + }) + + return true; +}) + +sync().then(value => console.log(value)).catch(reason => console.error(reason)) \ No newline at end of file diff --git a/content.js b/content.js index 74ba59e..26fd3af 100644 --- a/content.js +++ b/content.js @@ -1,5 +1,10 @@ + + // Get stored word list from chrome storage -chrome.storage.local.get(["vocabulary", "kanji"], (data) => { +chrome.storage.local.get(["vocabulary", "kanji", "validUserLevel"], (data) => { + if(!data.validUserLevel) + return + const vocabulary = data.vocabulary const kanji = data.kanji