File size: 2,158 Bytes
df9b14f |
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
import { delay } from '@std/async/delay';
import { shuffle } from '@std/random';
type User = {
user: string;
fullname: string;
type: string;
isFollowing?: true;
_id: string;
isPro: boolean;
avatarUrl: string;
};
export class HuggingFace {
constructor(public cookie: string) {
}
async getOrganizationFollowers(organization: string, cursor?: string) {
const url = new URL(`https://huggingface.co/api/organizations/${organization}/followers`);
cursor && url.searchParams.append('cursor', cursor);
const response = await fetch(url, {
headers: {
'Cookie': this.cookie,
},
});
if (!response.ok) throw Error(`${response.status} ${response.statusText}`);
return await response.json() as User[];
}
async getNonFollowingUsers(organization: string) {
let cursor: string | undefined = undefined;
while (true) {
const users = await this.getOrganizationFollowers(organization, cursor);
if (!users.length) throw Error('No users found');
const nonFollowing = users.filter((user) => !user.isFollowing);
if (nonFollowing.length) return nonFollowing;
cursor = users[users.length - 1]._id;
}
}
async followRandomUsers(organization: string) {
const users = await this.getNonFollowingUsers(organization);
const shuffled = shuffle(users);
for (let i = 0; i < shuffled.length; i++) {
await delay(1000);
const user = shuffled[i];
const res = await this.follow(user.user);
if (res.status === 429) {
console.error((await res.json()).error);
return i;
}
const body = await res.text();
if (body.trim().toLowerCase() === 'ok') {
console.log(`Followed ${user.user}`);
} else {
console.warn(`Failed to follow ${user.user}`);
continue;
}
}
}
async follow(user: string) {
return await fetch(`https://huggingface.co/api/users/${user}/follow`, {
method: 'post',
headers: {
'content-type': 'application/json',
'Cookie': this.cookie,
},
});
}
}
|