Add subscribe to RSS button to Ao3 works
This commit is contained in:
130
ao3-subscribe.user.js
Normal file
130
ao3-subscribe.user.js
Normal file
@@ -0,0 +1,130 @@
|
||||
// ==UserScript==
|
||||
// @name ao3 subscribe to feed
|
||||
// @version 1
|
||||
// @require http://crypto.stanford.edu/sjcl/sjcl.js
|
||||
// @grant GM.getValue
|
||||
// @grant GM.setValue
|
||||
// @include https://archiveofourown.org/works/*
|
||||
// ==/UserScript==
|
||||
// User script for Firefox
|
||||
|
||||
// Password management
|
||||
|
||||
async function decodeOrPrompt(targVar, userPrompt, setValVarName, encKey) {
|
||||
if (targVar) {
|
||||
targVar = unStoreAndDecrypt(targVar, encKey);
|
||||
}
|
||||
else {
|
||||
targVar = prompt(
|
||||
userPrompt + ' not set for ' + location.hostname + '. Please enter it now:',
|
||||
''
|
||||
);
|
||||
await GM.setValue(setValVarName, encryptAndStore(targVar, encKey));
|
||||
}
|
||||
return targVar;
|
||||
}
|
||||
|
||||
function encryptAndStore(clearText, encKey) {
|
||||
return JSON.stringify(sjcl.encrypt(encKey, clearText));
|
||||
}
|
||||
|
||||
function unStoreAndDecrypt(jsonObj, encKey) {
|
||||
return sjcl.decrypt(encKey, JSON.parse(jsonObj));
|
||||
}
|
||||
|
||||
async function getCredentials() {
|
||||
var encKey = await GM.getValue("encKey", "");
|
||||
var usr = await GM.getValue("ttrssUser", "");
|
||||
var pword = await GM.getValue("ttrssPass", "");
|
||||
|
||||
if (!encKey) {
|
||||
encKey = prompt(
|
||||
'Script key not set for ' + location.hostname + '. Please enter a random string:',
|
||||
''
|
||||
);
|
||||
await GM.setValue("encKey", encKey);
|
||||
|
||||
usr = pword = ""; // New key makes prev stored values (if any) unable to decode.
|
||||
}
|
||||
usr = await decodeOrPrompt(usr, "TTRSS user", "ttrssUser", encKey);
|
||||
pword = await decodeOrPrompt(pword, "TTRSS password", "ttrssPass", encKey);
|
||||
return { usr: usr, pword: pword };
|
||||
}
|
||||
|
||||
// Function to add a button to the <ul> element
|
||||
function addSubscriptionButton() {
|
||||
const ulElement = document.querySelector("ul.work");
|
||||
if (ulElement) {
|
||||
const newLi = document.createElement("li");
|
||||
const button = document.createElement("button");
|
||||
button.textContent = "Subscribe to RSS";
|
||||
button.onclick = async function () {
|
||||
// Extract work_id from the URL
|
||||
const workIdMatch = window.location.href.match(/works\/(\d+)/);
|
||||
if (workIdMatch) {
|
||||
const workId = workIdMatch[1];
|
||||
const rssURL = `https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=${workId}&format=atom`;
|
||||
|
||||
// Call the login method to get a session ID
|
||||
try {
|
||||
const sessionID = await loginToTinyTinyRSS();
|
||||
|
||||
// Subscribe to the RSS feed using the session ID
|
||||
try {
|
||||
await subscribeToFeed(rssURL, sessionID);
|
||||
alert("Subscribed successfully!");
|
||||
} catch (error) {
|
||||
alert("Error subscribing to feed: " + error);
|
||||
}
|
||||
} catch (error) {
|
||||
alert("Error logging in: " + error);
|
||||
}
|
||||
} else {
|
||||
alert("Unable to extract work_id from the URL.");
|
||||
}
|
||||
};
|
||||
|
||||
newLi.appendChild(button);
|
||||
ulElement.appendChild(newLi);
|
||||
}
|
||||
}
|
||||
|
||||
// Function to simulate a login to Tiny Tiny RSS
|
||||
async function loginToTinyTinyRSS() {
|
||||
const creds = await getCredentials();
|
||||
const loginResponse = await fetch("https://news.nas.franpenedo.com/api/", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: JSON.stringify({ op: "login", user: creds.usr, password: creds.pword }),
|
||||
});
|
||||
|
||||
const data = await loginResponse.json();
|
||||
if (data.content.hasOwnProperty("session_id")) {
|
||||
return data.content.session_id;
|
||||
} else {
|
||||
console.log(data);
|
||||
throw new Error("Login failed");
|
||||
}
|
||||
}
|
||||
|
||||
// Function to subscribe to an RSS feed in Tiny Tiny RSS
|
||||
async function subscribeToFeed(feedURL, sessionID) {
|
||||
const subscribeResponse = await fetch("https://news.nas.franpenedo.com/api/", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: JSON.stringify({ op: "subscribeToFeed", feed_url: feedURL, category_id: 11, sid: sessionID }),
|
||||
});
|
||||
|
||||
const subscribeData = await subscribeResponse.json();
|
||||
if (subscribeData.content.status.code !== 1) {
|
||||
console.log(subscribeData);
|
||||
throw new Error("Subscription failed");
|
||||
}
|
||||
}
|
||||
|
||||
// Call the function to add the button
|
||||
addSubscriptionButton();
|
||||
Reference in New Issue
Block a user