Spaces:
Paused
Paused
| 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): Promise<User[]> { | |
| 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(); | |
| } | |
| async getNonFollowingUsers(organization: string): Promise<User[]> { | |
| 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): Promise<number | undefined> { | |
| 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, | |
| }, | |
| }); | |
| } | |
| } | |