Avatar

@syncretizm

5 public vals
Joined November 10, 2023
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import process from 'node:process';
import { YouTube } from 'https://deno.land/x/youtube@v0.3.0/mod.ts';
export async function fetchVideoDetails(req) {
const url = new URL(req.url);
let yturl = url.searchParams.get("yturl") || "";
let mode = url.searchParams.get("mode") || "";
let responseContent;
let publishedDate, currentDate, timeDiff, daysDiff; // Declare variables outside the switch
yturl = decodeURIComponent(yturl);
const videoIdMatch = yturl.match(/(?:https?:\/\/)?(?:www\.)?youtube\.com\/(?:watch\?v=|live\/)([a-zA-Z0-9_-]+)|youtu\.be\/([a-zA-Z0-9_-]+)/);
let videoId = videoIdMatch ? videoIdMatch[1] || videoIdMatch[2] : null;
if (videoId && videoId.includes('&')) {
videoId = videoId.split('&')[0];
}
if (!videoId) {
videoId = `0iaU9VZXKUQ`;
}
if (!mode) {
mode = `transcript`;
}
const apiKey = process.env.ytapiKey;
let apiUrl = `https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id=${videoId}&key=${apiKey}`;
try {
let response = await fetch(apiUrl);
let data = await response.json();
if (!data.items || data.items.length === 0) {
throw new Error('No video details found');
}
const item = data.items[0];
let responseContent;
switch (mode) {
case 'thumbnail':
responseContent = `![](${item.snippet.thumbnails.high.url})`;
break;
case 'channel':
const channelLink = `https://www.youtube.com/channel/${item.snippet.channelId}`;
responseContent = `[${item.snippet.channelTitle}](${channelLink})`;
break;
case 'publishDate':
responseContent = item.snippet.publishedAt;
break;
case 'viewCount':
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { PuppeteerDeno } from "https://deno.land/x/puppeteer@16.2.0/src/deno/Puppeteer.ts";
import process from "node:process";
export async function extractTwitterContent(req) {
try {
console.log("Starting to extract Twitter content...");
const url = new URL(req.url);
const twurl = decodeURIComponent(url.searchParams.get("twurl") || "");
if (twurl.length == 0) { return new Response("Error: No twitter url provided", { status: 400 }); }
console.log(`Received twitter URL: ${twurl}`);
// convert twurl to threadurl via regex
const postURLRegex = /https:\/\/twitter\.com\/(.*)\/status\/(\d+)/;
const matches = twurl.match(postURLRegex);
console.log("Matching URL against Twitter post URL regex...");
let threadurl = "";
if (matches) {
const authorHandle = matches[1];
const postID = matches[2];
threadurl = `https://twitter.com/${authorHandle}/thread/${postID}`;
console.log(`Thread URL constructed: ${threadurl}`);
} else {
threadurl = twurl;
console.log("No match found, using original URL.");
}
const puppeteer = new PuppeteerDeno({ productName: "chrome" });
console.log("Connecting to browser...");
const browser = await puppeteer.connect({
browserWSEndpoint: `wss://chrome.browserless.io?token=${process.env.browserlessKey}`,
defaultViewport: null,
args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"],
});
const page = await browser.newPage();
console.log(`Navigating to thread URL: ${threadurl}`);
await page.goto(threadurl, { waitUntil: "domcontentloaded" }).catch(e => {
console.error("Navigation to thread URL failed:", e);
browser.close();
return new Response("Error: Navigation to Twitter thread URL timed out", { status: 504 });
});
await page.screenshot({ path: "threadurl-screenshot.png" });
// Check if login required
const loginSelector = "div[data-testid=\"loginButton\"]";
console.log("Checking if login is required...");
const login = await page.$(loginSelector);
let status = "";
if (login) {
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
const functionMap = {
// Basic Arithmetic Operations, with checks for type as numbers
"add": (a, b) => typeof a === "number" && typeof b === "number" ? a + b : null,
"subtract": (a, b) => typeof a === "number" && typeof b === "number" ? a - b : null,
"multiply": (a, b) => typeof a === "number" && typeof b === "number" ? a * b : null,
"mod": (a, b) => typeof a === "number" && typeof b === "number" ? a % b : null,
"pow": (a, b) => typeof a === "number" && typeof b === "number" ? Math.pow(a, b) : null,
"divide": (a, b) => (typeof a === "number" && typeof b === "number" && b !== 0) ? a / b : null,
// Comparison Operations, with checks for type as numbers
"equal": (a, b) => typeof a === "number" && typeof b === "number" ? a === b : null,
"notequal": (a, b) => typeof a === "number" && typeof b === "number" ? a !== b : null,
"greaterthan": (a, b) => typeof a === "number" && typeof b === "number" ? a > b : null,
"lessthan": (a, b) => typeof a === "number" && typeof b === "number" ? a < b : null,
"greaterthanorequal": (a, b) => typeof a === "number" && typeof b === "number" ? a >= b : null,
"lessthanorequal": (a, b) => typeof a === "number" && typeof b === "number" ? a <= b : null,
// Logical Operations, with checks
"and": (a, b, c) => typeof a === "boolean" && typeof b === "string" && typeof c === "string" ? a ? b : c : null,
"or": (a, b) => typeof a === "boolean" && typeof b === "boolean" ? a || b : null,
"not": (a) => typeof a === "boolean" ? !a : null,
"xor": (a, b) => typeof a === "boolean" && typeof b === "boolean" ? a !== b : null,
"nand": (a, b) => typeof a === "boolean" && typeof b === "boolean" ? !(a && b) : null,
"nor": (a, b) => typeof a === "boolean" && typeof b === "boolean" ? !(a || b) : null,
"xnor": (a, b) => typeof a === "boolean" && typeof b === "boolean" ? a === b : null,
// Boolean Values
// true receives a boolean, b is if true, c is if false
"true": (a, b, c) => typeof a === "boolean" && typeof b === "string" && typeof c === "string" ? a ? b : c : null,
"false": (a, b, c) => typeof a === "boolean" && typeof b === "string" && typeof c === "string" ? a ? c : b : null,
// String and Array Operations with checks
"contains": (a, b) => typeof a === "string" || typeof a === "number" || Array.isArray(a) ? a.includes(b) : null,
"length": (a) => typeof a === "string" || typeof a === "number" || Array.isArray(a) ? a.length : null,
"empty": (a) => typeof a === "string" || typeof a === "number" || Array.isArray(a) ? a === "" : null,
"test": (a, b) => typeof a === "string" ? b.includes(a) : null,
"match": (a, b) => typeof a === "string" ? a.match(b) : null,
"replace": (a, b, c) => typeof a === "string" ? a.replace(b, c) : null,
"replaceAll": (a, b, c) => typeof a === "string" ? a.replaceAll(b, c) : null,
"lowercase": (a) => typeof a === "string" ? a.toLowerCase() : null,
"uppercase": (a) => typeof a === "string" ? a.toUpperCase() : null,
"repeat": (a, b) => typeof a === "string" ? a.repeat(b) : null,
"stripformatting": (a) => typeof a === "string" ? a.replace(/<[^>]*>/g, "") : null,
"min": (a) => Array.isArray(a) ? Math.min(...a) : null,
"max": (a) => Array.isArray(a) ? Math.max(...a) : null,
"absolute": (a) => typeof a === "number" ? Math.abs(a) : null,
"round": (a) => typeof a === "number" ? Math.round(a) : null,
"ceiling": (a) => typeof a === "number" ? Math.ceil(a) : null,
"floor": (a) => typeof a === "number" ? Math.floor(a) : null,
"squareroot": (a) => typeof a === "number" ? Math.sqrt(a) : null,
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
export async function formulaEndpoint(req) {
if (req.method !== "GET") {
return new Response("Method Not Allowed", { status: 405 });
}
// PARSE URL
const params = new URLSearchParams(req.url.split("?")[1]);
// Extract the method and remove it from the parameters
const method = params.get("method");
params.delete("method");
// Initialize an object to store the variables
const vars = {};
// Iterate through the parameters
params.forEach((value, key) => {
if (value) {
vars[key] = value;
}
});
// now params is a dictionary of all the parameters that are not 'method'
// if params is empty, then we need to respond with an error.
if (Object.keys(vars).length === 0) {
return new Response("No parameters provided", { status: 400 });
}
// the params contain either numbers or strings, depending on the method passed.
// methods/functions include: add, subtract, multiply, mod, pow, divide, equal, =/=, >, <, >=, <=, and, or, not, xor, nand, nor, xnor, true, false, if_empty, length, contains, test, match, replace, replaceAll, lowercase, uppercase, repeat(#), strip_forma
// variable types include: number, string, boolean, date, array, object, null, undefined
// the return type is always a string.
// EXECUTE REQUEST
let result = null;
// DICTIONARY OF ALL FUNCTIONS, MAX NUMBER OF PARAMETERS, AND ACCEPTED TYPE
const functions = {
"add": ["infinite", "number"],
"subtract": ["infinite", "number"],
"multiply": ["infinite", "number"],
"mod": [2, "number"],
"pow": [2, "number"],
"divide": [2, "number"],
"equal": [2, "any"],
"!=": [2, "any"],
">": [2, "number"],
"<": [2, "number"],
">=": [2, "number"],
"<=": [2, "number"],
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
const timeZone = "Asia/Singapore";
const State = {
New: 0,
Learning: 1,
Review: 2,
Relearning: 3,
};
const Rating = {
Again: 1,
Hard: 2,
Good: 3,
Easy: 4,
};
class ReviewLog {
rating;
elapsed_days;
scheduled_days;
review;
state;
constructor(rating, elapsed_days, scheduled_days, review, state) {
this.rating = rating;
this.elapsed_days = elapsed_days;
this.scheduled_days = Math.abs(scheduled_days);
this.review = review;
this.state = state;
}
}
class Card {
due;
stability;
difficulty;
elapsed_days;
scheduled_days;
reps;
lapses;
state;
last_review;
constructor() {
this.due = new Date();
this.stability = 0;
this.difficulty = 0;
this.elapsed_days = 0;
this.scheduled_days = 0;
this.reps = 0;
this.lapses = 0;
this.state = State.New;
Next