Skip to content
This repository was archived by the owner on Dec 22, 2023. It is now read-only.

Commit 7f1ec19

Browse files
authored
Merge pull request #555 from ADV1K/CodeforcesProfileScrapper
Added CodeforcesProfileScrapper
2 parents 9d35536 + 4035cc4 commit 7f1ec19

File tree

7 files changed

+194
-0
lines changed

7 files changed

+194
-0
lines changed
1.67 KB
Loading
173 KB
Loading
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# CodeforcesProfileScrapper
2+
A Simple Python Script to Scrap the details of a codeforces user and then display the details in a tkinter gui.
3+
4+
### How to run the script
5+
copy this repo and cd into this directory
6+
```
7+
python main.py
8+
```
9+
10+
###
11+
<img src="1.png">
12+
<img src="2.png">
13+
14+
## *Author*
15+
Made With ❤️ By [Advik](https://github.com/ADV1K)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
rating = {
2+
'newbie': '#808080',
3+
'pupil': '#008000',
4+
'specialist': '#03A89E',
5+
'expert': 'blue',
6+
'candidate Master': '#a0a',
7+
'master': '#FF8C00',
8+
'international master': '#FF8C00',
9+
'grandmaster': 'red',
10+
'international grandmaster': 'red',
11+
'legendary grandmaster': 'red',
12+
}
13+
14+
GRAY = '#808080'
15+
GREEN = '#008000'
16+
CYAN = '#03A89E'
17+
BLUE = 'blue'
18+
RED = 'red'
19+
20+
NORMAL_FONT = "Arial 14"
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import tkinter as tk
2+
from tkinter import ttk
3+
from tkinter import Label
4+
from PIL import Image, ImageTk
5+
from urllib.request import urlopen
6+
from datetime import datetime
7+
8+
from scrapper import user_info, UserNotFoundError
9+
import constants as c
10+
11+
12+
class Bunch(dict):
13+
def __init__(self, adict):
14+
dict.__init__(self)
15+
self.update(adict)
16+
self.__dict__.update(adict)
17+
18+
19+
class Profile:
20+
def __init__(self, master, handle):
21+
self.master = master
22+
self.master.title(f'Codeforces Profiler - {handle}')
23+
24+
try:
25+
self.user = Bunch(user_info(handle)[0]) # bcz Namespace syntax is easy
26+
self.init()
27+
except UserNotFoundError:
28+
w = ttk.Label(self.master, text=f"User {handle} does not exists!")
29+
w.grid()
30+
b = ttk.Button(self.master, text="OK", command=self.master.destroy)
31+
b.grid()
32+
33+
def init(self):
34+
PROFILE_PIC = ImageTk.PhotoImage(Image.open(urlopen(f"https:{self.user.titlePhoto}")))
35+
RATING_COLOR = c.rating.get(self.user.rank)
36+
MAX_RATING_COLOR = c.rating.get(self.user.maxRank)
37+
CONTRIBUTION = '+' * (self.user.contribution > 0) + str(self.user.contribution)
38+
CONTRIBUTION_COLOR = c.GREEN if self.user.contribution > 0 else c.GRAY
39+
# image
40+
img1 = Label(self.master, image=PROFILE_PIC)
41+
img1.image = PROFILE_PIC
42+
img1.grid(row=0, column=2, rowspan=10)
43+
# rank
44+
label1 = Label(self.master, fg=RATING_COLOR, font="Verdana 14 bold", text=self.user.rank.title())
45+
label1.grid(row=0, column=0, sticky='w', columnspan=2)
46+
# handle
47+
label2 = Label(self.master, fg=RATING_COLOR, font="Helvetica 23 bold", text=self.user.handle)
48+
label2.grid(row=1, column=0, sticky='w', columnspan=2)
49+
# name, city, country
50+
label3 = Label(self.master, fg='#777777', text=f"{self.user.get('firstName', '')} {self.user.get('lastName', '')}, {self.user.get('city', '')}, {self.user.get('country', '')}".strip(', '))
51+
label3.grid(row=2, column=0, sticky='w', columnspan=2)
52+
# From
53+
label4 = Label(self.master, fg='#777777', text=f"From {self.user.get('organization', '')}")
54+
label4.grid(row=3, column=0, sticky='w', columnspan=2)
55+
# Contest Rating:
56+
label5 = Label(self.master, font="Arial 14", text="Contest Rating: ")
57+
label5.grid(row=4, column=0, sticky='w')
58+
label6 = Label(self.master, fg=RATING_COLOR, font="Arial 14", text=self.user.rating)
59+
label6.grid(row=4, column=1, sticky='w')
60+
# Max Rating:
61+
label7 = Label(self.master, font="Arial 14", text="Max Rating:")
62+
label7.grid(row=5, column=0, sticky='w')
63+
label8 = Label(self.master, fg=MAX_RATING_COLOR, font="Arial 14", text=f"{self.user.maxRank.title()}, {self.user.maxRating}")
64+
label8.grid(row=5, column=1, sticky='w')
65+
# Contribution:
66+
label9 = Label(self.master, font="Arial 14", text="Contribution:")
67+
label9.grid(row=6, column=0, sticky='w')
68+
label10 = Label(self.master, fg=CONTRIBUTION_COLOR, font="Arial 14", text=CONTRIBUTION)
69+
label10.grid(row=6, column=1, sticky='w')
70+
# Friend of:
71+
label11 = Label(self.master, font="Arial 14", text="Friend of:")
72+
label11.grid(row=7, column=0, sticky='w')
73+
label12 = Label(self.master, font="Arial 14", text=f"{self.user.friendOfCount} users")
74+
label12.grid(row=7, column=1, sticky='w')
75+
# Last visit:
76+
label13 = Label(self.master, font="Arial 14", text="Last visit:")
77+
label13.grid(row=8, column=0, sticky='w')
78+
label14 = Label(self.master, font="Arial 14", text=datetime.utcfromtimestamp(int(self.user.lastOnlineTimeSeconds)))
79+
label14.grid(row=8, column=1, sticky='w')
80+
# Registered
81+
label15 = Label(self.master, font="Arial 14", text="Registered:")
82+
label15.grid(row=9, column=0, sticky='w')
83+
label16 = Label(self.master, font="Arial 14", text=datetime.utcfromtimestamp(int(self.user.registrationTimeSeconds)))
84+
label16.grid(row=9, column=1, sticky='w')
85+
86+
87+
class App:
88+
def __init__(self, master):
89+
self.master = master
90+
master.title("Codeforces Scrapper")
91+
master.bind("<Return>", self.display_profile)
92+
93+
label1 = ttk.Label(master, text="Handle:")
94+
label1.grid(row=0, column=0, padx=5, pady=5)
95+
self.entry1 = ttk.Entry(master)
96+
self.entry1.grid(row=0, column=1, padx=5, pady=5)
97+
self.entry1.focus_set()
98+
button1 = ttk.Button(master, text="Fetch Data", command=self.display_profile)
99+
button1.grid(row=1, column=0, columnspan=2, padx=5, pady=5)
100+
101+
def display_profile(self, event=None):
102+
handle = self.entry1.get()
103+
top = tk.Toplevel()
104+
Profile(top, handle)
105+
self.entry1.delete(0, 999)
106+
107+
108+
def main(handle=None):
109+
root = tk.Tk()
110+
if handle:
111+
Profile(root, handle)
112+
else:
113+
App(root)
114+
root.mainloop()
115+
116+
117+
if __name__ == '__main__':
118+
main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Pillow
2+
requests
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from datetime import datetime
2+
import requests
3+
import sys
4+
5+
6+
class UserNotFoundError(Exception):
7+
pass
8+
9+
10+
def user_info(handles):
11+
if type(handles) is str:
12+
handles = [handles]
13+
url = "https://codeforces.com/api/user.info"
14+
params = {
15+
"handles": ';'.join(handles)
16+
}
17+
with requests.get(url=url, params=params) as r:
18+
d = r.json()
19+
if d['status'] == 'OK':
20+
return d['result']
21+
raise UserNotFoundError(d['comment'])
22+
23+
24+
def main():
25+
if len(sys.argv) > 1:
26+
handles = sys.argv[1:]
27+
else:
28+
handles = input("[+] Handles (space-separated): ").split()
29+
30+
for user in user_info(handles):
31+
print('-' * 50)
32+
for key in ['handle', 'rating', 'rank', 'maxRating', 'maxRank', 'contribution', 'friendOfCount']:
33+
print(f"[*] {key:23}: {user[key]}")
34+
print(f"[*] lastOnlineTimeSeconds : {datetime.utcfromtimestamp(int(user['lastOnlineTimeSeconds']))}")
35+
print(f"[*] registrationTimeSeconds: {datetime.utcfromtimestamp(int(user['registrationTimeSeconds']))}")
36+
37+
38+
if __name__ == '__main__':
39+
main()

0 commit comments

Comments
 (0)