mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-22 01:29:22 +00:00
103 lines
2.5 KiB
TypeScript
103 lines
2.5 KiB
TypeScript
//import fs from "fs";
|
|
import { getTwitterClient } from "../twitter";
|
|
import * as Skins from "../data/skins";
|
|
import { MD5_REGEX } from "../utils";
|
|
|
|
export const knownManualTweets = new Set([
|
|
"1333662209436631043",
|
|
"1307861036431679494",
|
|
"1315066935353065472",
|
|
"1315453111943614465",
|
|
"1197689761269350400",
|
|
]);
|
|
|
|
const MAX_CALL_COUNT = 800;
|
|
|
|
type TweetPayload = {
|
|
entities: {
|
|
urls: {
|
|
expanded_url: string;
|
|
}[];
|
|
};
|
|
text: string;
|
|
id_str: string;
|
|
favorite_count: number;
|
|
retweet_count: number;
|
|
};
|
|
|
|
async function getTweets(twitterClient): Promise<TweetPayload[]> {
|
|
let max_id: string | undefined = undefined;
|
|
let tweets: TweetPayload[] = [];
|
|
let callCount = 0;
|
|
|
|
while (callCount < MAX_CALL_COUNT * 6) {
|
|
callCount++;
|
|
const response = await twitterClient.get("statuses/user_timeline", {
|
|
max_id,
|
|
screen_name: "winampskins",
|
|
exclude_replies: true,
|
|
include_rts: false,
|
|
});
|
|
console.log(JSON.stringify(response.data, null, 2));
|
|
tweets = tweets.concat(response.data);
|
|
const newMaxId = tweets.map((tweet) => tweet.id_str).sort()[0];
|
|
if (newMaxId === max_id) {
|
|
console.warn(`Got the same max id ${max_id}`);
|
|
return tweets;
|
|
}
|
|
|
|
max_id = newMaxId;
|
|
if (response.data.length <= 1) {
|
|
console.warn("Page was short");
|
|
return tweets;
|
|
}
|
|
if (callCount === MAX_CALL_COUNT) {
|
|
console.warn("Hit MAX (but gonna keep going)");
|
|
}
|
|
}
|
|
|
|
console.warn("Hit MAX (but gonna keep going)");
|
|
return tweets;
|
|
}
|
|
|
|
function getMd5(tweet: TweetPayload): string | null {
|
|
return (
|
|
tweet.entities.urls
|
|
.map(({ expanded_url }) => {
|
|
const match = expanded_url.match(MD5_REGEX);
|
|
return match != null ? match[0] : null;
|
|
})
|
|
.find(Boolean) ?? null
|
|
);
|
|
}
|
|
|
|
export async function scrapeLikeData() {
|
|
const twitterClient = getTwitterClient();
|
|
const rawTweets = await getTweets(twitterClient);
|
|
|
|
const tweets = rawTweets.filter((tweet) => {
|
|
// Ignore tweets that don't have links, or are known manual tweets.
|
|
return !(
|
|
tweet.entities.urls.length === 0 || knownManualTweets.has(tweet.id_str)
|
|
);
|
|
});
|
|
|
|
const todo: TweetPayload[] = [];
|
|
|
|
for (const tweet of tweets) {
|
|
const success = await Skins.setTweetInfo(
|
|
getMd5(tweet),
|
|
tweet.favorite_count,
|
|
tweet.retweet_count,
|
|
tweet.id_str
|
|
);
|
|
if (!success) {
|
|
console.warn(
|
|
`Cannot insert skin without an md5 for tweet ${tweet.id_str}`
|
|
);
|
|
todo.push(tweet);
|
|
}
|
|
}
|
|
|
|
// fs.writeFileSync("todo.json", JSON.stringify(todo));
|
|
}
|