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

Added CodeforcesProfileScrapper #555

Merged
merged 4 commits into from
Oct 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions Scripts/Web_Scrappers/CodeforcesProfileScrapper/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# CodeforcesProfileScrapper
A Simple Python Script to Scrap the details of a codeforces user and then display the details in a tkinter gui.

### How to run the script
copy this repo and cd into this directory
```
python main.py
```

###
<img src="1.png">
<img src="2.png">

## *Author*
Made With ❤️ By [Advik](https://github.com/ADV1K)
20 changes: 20 additions & 0 deletions Scripts/Web_Scrappers/CodeforcesProfileScrapper/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
rating = {
'newbie': '#808080',
'pupil': '#008000',
'specialist': '#03A89E',
'expert': 'blue',
'candidate Master': '#a0a',
'master': '#FF8C00',
'international master': '#FF8C00',
'grandmaster': 'red',
'international grandmaster': 'red',
'legendary grandmaster': 'red',
}

GRAY = '#808080'
GREEN = '#008000'
CYAN = '#03A89E'
BLUE = 'blue'
RED = 'red'

NORMAL_FONT = "Arial 14"
118 changes: 118 additions & 0 deletions Scripts/Web_Scrappers/CodeforcesProfileScrapper/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import tkinter as tk
from tkinter import ttk
from tkinter import Label
from PIL import Image, ImageTk
from urllib.request import urlopen
from datetime import datetime

from scrapper import user_info, UserNotFoundError
import constants as c


class Bunch(dict):
def __init__(self, adict):
dict.__init__(self)
self.update(adict)
self.__dict__.update(adict)


class Profile:
def __init__(self, master, handle):
self.master = master
self.master.title(f'Codeforces Profiler - {handle}')

try:
self.user = Bunch(user_info(handle)[0]) # bcz Namespace syntax is easy
self.init()
except UserNotFoundError:
w = ttk.Label(self.master, text=f"User {handle} does not exists!")
w.grid()
b = ttk.Button(self.master, text="OK", command=self.master.destroy)
b.grid()

def init(self):
PROFILE_PIC = ImageTk.PhotoImage(Image.open(urlopen(f"https:{self.user.titlePhoto}")))
RATING_COLOR = c.rating.get(self.user.rank)
MAX_RATING_COLOR = c.rating.get(self.user.maxRank)
CONTRIBUTION = '+' * (self.user.contribution > 0) + str(self.user.contribution)
CONTRIBUTION_COLOR = c.GREEN if self.user.contribution > 0 else c.GRAY
# image
img1 = Label(self.master, image=PROFILE_PIC)
img1.image = PROFILE_PIC
img1.grid(row=0, column=2, rowspan=10)
# rank
label1 = Label(self.master, fg=RATING_COLOR, font="Verdana 14 bold", text=self.user.rank.title())
label1.grid(row=0, column=0, sticky='w', columnspan=2)
# handle
label2 = Label(self.master, fg=RATING_COLOR, font="Helvetica 23 bold", text=self.user.handle)
label2.grid(row=1, column=0, sticky='w', columnspan=2)
# name, city, country
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(', '))
label3.grid(row=2, column=0, sticky='w', columnspan=2)
# From
label4 = Label(self.master, fg='#777777', text=f"From {self.user.get('organization', '')}")
label4.grid(row=3, column=0, sticky='w', columnspan=2)
# Contest Rating:
label5 = Label(self.master, font="Arial 14", text="Contest Rating: ")
label5.grid(row=4, column=0, sticky='w')
label6 = Label(self.master, fg=RATING_COLOR, font="Arial 14", text=self.user.rating)
label6.grid(row=4, column=1, sticky='w')
# Max Rating:
label7 = Label(self.master, font="Arial 14", text="Max Rating:")
label7.grid(row=5, column=0, sticky='w')
label8 = Label(self.master, fg=MAX_RATING_COLOR, font="Arial 14", text=f"{self.user.maxRank.title()}, {self.user.maxRating}")
label8.grid(row=5, column=1, sticky='w')
# Contribution:
label9 = Label(self.master, font="Arial 14", text="Contribution:")
label9.grid(row=6, column=0, sticky='w')
label10 = Label(self.master, fg=CONTRIBUTION_COLOR, font="Arial 14", text=CONTRIBUTION)
label10.grid(row=6, column=1, sticky='w')
# Friend of:
label11 = Label(self.master, font="Arial 14", text="Friend of:")
label11.grid(row=7, column=0, sticky='w')
label12 = Label(self.master, font="Arial 14", text=f"{self.user.friendOfCount} users")
label12.grid(row=7, column=1, sticky='w')
# Last visit:
label13 = Label(self.master, font="Arial 14", text="Last visit:")
label13.grid(row=8, column=0, sticky='w')
label14 = Label(self.master, font="Arial 14", text=datetime.utcfromtimestamp(int(self.user.lastOnlineTimeSeconds)))
label14.grid(row=8, column=1, sticky='w')
# Registered
label15 = Label(self.master, font="Arial 14", text="Registered:")
label15.grid(row=9, column=0, sticky='w')
label16 = Label(self.master, font="Arial 14", text=datetime.utcfromtimestamp(int(self.user.registrationTimeSeconds)))
label16.grid(row=9, column=1, sticky='w')


class App:
def __init__(self, master):
self.master = master
master.title("Codeforces Scrapper")
master.bind("<Return>", self.display_profile)

label1 = ttk.Label(master, text="Handle:")
label1.grid(row=0, column=0, padx=5, pady=5)
self.entry1 = ttk.Entry(master)
self.entry1.grid(row=0, column=1, padx=5, pady=5)
self.entry1.focus_set()
button1 = ttk.Button(master, text="Fetch Data", command=self.display_profile)
button1.grid(row=1, column=0, columnspan=2, padx=5, pady=5)

def display_profile(self, event=None):
handle = self.entry1.get()
top = tk.Toplevel()
Profile(top, handle)
self.entry1.delete(0, 999)


def main(handle=None):
root = tk.Tk()
if handle:
Profile(root, handle)
else:
App(root)
root.mainloop()


if __name__ == '__main__':
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Pillow
requests
39 changes: 39 additions & 0 deletions Scripts/Web_Scrappers/CodeforcesProfileScrapper/scrapper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from datetime import datetime
import requests
import sys


class UserNotFoundError(Exception):
pass


def user_info(handles):
if type(handles) is str:
handles = [handles]
url = "https://codeforces.com/api/user.info"
params = {
"handles": ';'.join(handles)
}
with requests.get(url=url, params=params) as r:
d = r.json()
if d['status'] == 'OK':
return d['result']
raise UserNotFoundError(d['comment'])


def main():
if len(sys.argv) > 1:
handles = sys.argv[1:]
else:
handles = input("[+] Handles (space-separated): ").split()

for user in user_info(handles):
print('-' * 50)
for key in ['handle', 'rating', 'rank', 'maxRating', 'maxRank', 'contribution', 'friendOfCount']:
print(f"[*] {key:23}: {user[key]}")
print(f"[*] lastOnlineTimeSeconds : {datetime.utcfromtimestamp(int(user['lastOnlineTimeSeconds']))}")
print(f"[*] registrationTimeSeconds: {datetime.utcfromtimestamp(int(user['registrationTimeSeconds']))}")


if __name__ == '__main__':
main()