diff --git a/Scripts/Web_Scrappers/CodeforcesProfileScrapper/1.png b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/1.png new file mode 100644 index 000000000..b7958d356 Binary files /dev/null and b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/1.png differ diff --git a/Scripts/Web_Scrappers/CodeforcesProfileScrapper/2.png b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/2.png new file mode 100644 index 000000000..9badb6c05 Binary files /dev/null and b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/2.png differ diff --git a/Scripts/Web_Scrappers/CodeforcesProfileScrapper/README.md b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/README.md new file mode 100644 index 000000000..b0da4092f --- /dev/null +++ b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/README.md @@ -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 +``` + +### + + + +## *Author* +Made With ❤️ By [Advik](https://github.com/ADV1K) diff --git a/Scripts/Web_Scrappers/CodeforcesProfileScrapper/constants.py b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/constants.py new file mode 100644 index 000000000..c8812f119 --- /dev/null +++ b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/constants.py @@ -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" diff --git a/Scripts/Web_Scrappers/CodeforcesProfileScrapper/main.py b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/main.py new file mode 100644 index 000000000..f99990c1e --- /dev/null +++ b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/main.py @@ -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("", 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() diff --git a/Scripts/Web_Scrappers/CodeforcesProfileScrapper/requirements.txt b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/requirements.txt new file mode 100644 index 000000000..f52ebd03e --- /dev/null +++ b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/requirements.txt @@ -0,0 +1,2 @@ +Pillow +requests diff --git a/Scripts/Web_Scrappers/CodeforcesProfileScrapper/scrapper.py b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/scrapper.py new file mode 100644 index 000000000..1e185b0a4 --- /dev/null +++ b/Scripts/Web_Scrappers/CodeforcesProfileScrapper/scrapper.py @@ -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()