-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtoken_manager.py
More file actions
99 lines (86 loc) · 3.29 KB
/
token_manager.py
File metadata and controls
99 lines (86 loc) · 3.29 KB
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import json
import time
from typing import List, Dict, Optional, Tuple
import threading
import subprocess
import os
class TokenManager:
def __init__(self, tokens_file: str = "github_tokens.json"):
self.tokens_file = tokens_file
self.tokens: List[Dict] = []
self.token_status: Dict[str, Dict] = {}
self.lock = threading.Lock()
self.load_tokens()
def load_tokens(self):
"""Load tokens from file"""
try:
with open(self.tokens_file, 'r') as f:
data = json.load(f)
self.tokens = data.get('tokens', [])
for token in self.tokens:
token_key = token['token'][:8]
self.token_status[token_key] = {
'remaining': 5000,
'reset_time': 0,
'last_used': 0,
'errors': 0,
'active': True
}
print(f"📋 Loaded {len(self.tokens)} GitHub tokens")
except FileNotFoundError:
print("⚠ No token file found. Create github_tokens.json")
self.tokens = []
def add_token(self, token: str, name: str = None):
"""Add a new token"""
new_token = {
'token': token,
'name': name or f"token-{len(self.tokens)+1}"
}
self.tokens.append(new_token)
token_key = token[:8]
self.token_status[token_key] = {
'remaining': 5000,
'reset_time': 0,
'last_used': 0,
'errors': 0,
'active': True
}
self.save_tokens()
def save_tokens(self):
"""Save tokens to file"""
with open(self.tokens_file, 'w') as f:
json.dump({'tokens': self.tokens}, f, indent=2)
def get_best_token(self) -> Optional[Tuple[str, Dict]]:
"""Get the token with most remaining requests"""
with self.lock:
best_token = None
best_status = None
best_remaining = -1
for token in self.tokens:
token_key = token['token'][:8]
status = self.token_status.get(token_key, {})
if not status.get('active', True):
continue
remaining = status.get('remaining', 0)
if remaining > best_remaining:
best_remaining = remaining
best_token = token
best_status = status
if best_token:
token_key = best_token['token'][:8]
self.token_status[token_key]['last_used'] = time.time()
self.token_status[token_key]['remaining'] -= 1
return best_token['token'], best_status
return None, None
def get_token_stats(self) -> str:
"""Get token statistics"""
stats = []
for token in self.tokens:
token_key = token['token'][:8]
status = self.token_status.get(token_key, {})
stats.append(
f" {token.get('name', token_key)}: "
f"{status.get('remaining', 0)} remaining, "
f"errors: {status.get('errors', 0)}"
)
return "\n".join(stats)