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,
      },
    });
  }
}