diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6a8620e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "activestate.promptRuntimeCreation": false +} \ No newline at end of file diff --git a/README.md b/README.md index 4dcf895..d69ebb0 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,12 @@ # API Digest 2021 -This repository contains the rules and code of conduct for __API Digest 2021__. +The idea is to create a Telegram Bot for running the code inside Telegram, written in messages. The code has to be written in the message and the bot will return the output. The user can add its username in the bot to receive its details in messages like rating, number of stars etc. -## Contents -- __[Contents](#contents)__ -- __[Requirements](#requirements)__ -- __[Few pointers](#few-pointers)__ -- __[How to submit?](#how-to-submit)__ -- __[Rules](HackIIITV_rules_and_timeline.pdf)__ -- __[Code of Conduct](CODE_OF_CONDUCT.md)__ -- __[Our Community](#our-community)__ -- __[Contact / Support](#contact--support)__ +We will be using APIs from Codechef, Codeforces or Hackerrank to fetch a random question from any category/difficulty level. -### Requirements +Further, we will try to introduce more features like fetching a random question daily according to user's rating, alert about the upcoming contests and solving language specific ladders. -- __[GitHub account](https://github.com/login)__ -- Install __[git](https://git-scm.com/)__ for your repsective OS. -- Make sure you are part of IIITV organisation on GitHub, else join __[here](http://getmein.glitch.me/)__ - -### Few pointers - -- You can make at max one commit per hour. -- Don't close your PR. -- No commits after Hackathon ends will be entertained. -- It is required from the teams to keep committing within __three__ hours of the previous commit to keep your hack backed up. -- Make sure your whole project is inside the folder of your team. -- If you have time left, make sure you make a README.md 📄 😉(it will help others to understand your code) - -### How to submit? - -One member from each team have to follow this instructions: -Follow the instructions in order: - -1. Fork this repository. - -2. Clone your fork, using - `git clone https://github.com//api-digest-2021.git` - -3. Change Directory to `api-digest-2021`, using - `cd api-digest-2021` - -4. Set remote to original repository using - `git remote add ups https://github.com/iiitv/api-digest-2021.git` - -5. Create a branch named `team#x`, where __"x"__ is your team number, using - `git checkout -b team#x` - -6. Add a folder with name `team#x - {Chosen_Theme_number}` in root directory. Make sure your whole hack is in folder `team#x - {Chosen_Theme_number}`. - -7. Now add this folder to your staging area, using - `git add "team#x - {Chosen_Theme_number}"` - -8. Now commit the changes using, - `git commit -m "Add team#x"` - -9. Push the changes using, - `git push` - -10. Open a pull request: As soon as the changes will be pushed, GUI of repository's main page will show a yellow banner saying you too open a Pull request, just click on it and you are done. - -For making changes to PR, just keep on repeating Step 6-9. - -### Rules - -- Keep your content as original as possible. -- It is allowed to use available softwares/packages as a module, but they can't be your project. - -### Contact / Support - -- Write to us at: __[technical.committee@iiitvadodara.ac.in](mailto:technical.committee@iiitvadodara.ac.in)__ -- Join the discord server: __[Technical Committee](https://discord.gg/Rw4X9rYZgR)__ - -### Our Community - -- Open source projects created by students at IIITV : [IIITV Open Source Org](https://github.com/iiitv) -- Discord channel where we discuss topics related to DSA and Competitive Programming: [IIITVCC Discord Server Invite](https://discord.gg/pUPbVHF) -- Join the Open Source Org and our Slack Channel to ask your doubts and discussion: [Get Me In](https://getmein.glitch.me/), [Slack](https://join.slack.com/t/iiitvadodara/shared_invite/zt-gx92qvc2-X_NREKMxP6f7DlyZuxzM_g) - -### Happy Hacking! 🖖 - - *** - -

Made With ❤️ By Team API Digest

+### Steps to Run +1. Clone the repository using `git clone https://github.com/anaghamittal/api-digest-2021/`. +2. Go to the folder `team#17-education`. +3. Run `server.py` using `python server.py`. +4. Use the Bot :) diff --git a/__pycache__/admins.cpython-39.pyc b/__pycache__/admins.cpython-39.pyc new file mode 100644 index 0000000..283f7db Binary files /dev/null and b/__pycache__/admins.cpython-39.pyc differ diff --git a/team#17-education/README.md b/team#17-education/README.md new file mode 100644 index 0000000..928f7f4 --- /dev/null +++ b/team#17-education/README.md @@ -0,0 +1,9 @@ +# Team#17 - Telegram Bot + +The idea is to create a Telegram Bot for running the code inside Telegram, written in messages. The code has to be written in the message and the bot will return the output. The user can add its username in the bot to receive its details in messages like rating, number of stars etc. + +We will be using APIs from Codechef, Codeforces or Hackerrank to fetch a random question from any category/difficulty level. + +### To start using the chatbot: [CS_toolkit_bot](http://t.me/CS_toolkit_bot) + +Further, we will try to introduce more features like fetching a random question daily according to user's rating, alert about the upcoming contests and solving language specific ladders. \ No newline at end of file diff --git a/team#17-education/__pycache__/admins.cpython-38.pyc b/team#17-education/__pycache__/admins.cpython-38.pyc new file mode 100644 index 0000000..fe93a90 Binary files /dev/null and b/team#17-education/__pycache__/admins.cpython-38.pyc differ diff --git a/team#17-education/__pycache__/admins.cpython-39.pyc b/team#17-education/__pycache__/admins.cpython-39.pyc new file mode 100644 index 0000000..52133a7 Binary files /dev/null and b/team#17-education/__pycache__/admins.cpython-39.pyc differ diff --git a/team#17-education/__pycache__/codeforces.cpython-38.pyc b/team#17-education/__pycache__/codeforces.cpython-38.pyc new file mode 100644 index 0000000..1bcd3bf Binary files /dev/null and b/team#17-education/__pycache__/codeforces.cpython-38.pyc differ diff --git a/team#17-education/__pycache__/codeforces.cpython-39.pyc b/team#17-education/__pycache__/codeforces.cpython-39.pyc new file mode 100644 index 0000000..9c0139e Binary files /dev/null and b/team#17-education/__pycache__/codeforces.cpython-39.pyc differ diff --git a/team#17-education/__pycache__/gfg.cpython-38.pyc b/team#17-education/__pycache__/gfg.cpython-38.pyc new file mode 100644 index 0000000..5243c3c Binary files /dev/null and b/team#17-education/__pycache__/gfg.cpython-38.pyc differ diff --git a/team#17-education/__pycache__/gfg.cpython-39.pyc b/team#17-education/__pycache__/gfg.cpython-39.pyc new file mode 100644 index 0000000..c68e92c Binary files /dev/null and b/team#17-education/__pycache__/gfg.cpython-39.pyc differ diff --git a/team#17-education/__pycache__/github.cpython-38.pyc b/team#17-education/__pycache__/github.cpython-38.pyc new file mode 100644 index 0000000..e8ff628 Binary files /dev/null and b/team#17-education/__pycache__/github.cpython-38.pyc differ diff --git a/team#17-education/__pycache__/github.cpython-39.pyc b/team#17-education/__pycache__/github.cpython-39.pyc new file mode 100644 index 0000000..a00e6e3 Binary files /dev/null and b/team#17-education/__pycache__/github.cpython-39.pyc differ diff --git a/team#17-education/__pycache__/image.cpython-38.pyc b/team#17-education/__pycache__/image.cpython-38.pyc new file mode 100644 index 0000000..7ca3b28 Binary files /dev/null and b/team#17-education/__pycache__/image.cpython-38.pyc differ diff --git a/team#17-education/__pycache__/image.cpython-39.pyc b/team#17-education/__pycache__/image.cpython-39.pyc new file mode 100644 index 0000000..032e28b Binary files /dev/null and b/team#17-education/__pycache__/image.cpython-39.pyc differ diff --git a/team#17-education/__pycache__/ocr.cpython-38.pyc b/team#17-education/__pycache__/ocr.cpython-38.pyc new file mode 100644 index 0000000..900b204 Binary files /dev/null and b/team#17-education/__pycache__/ocr.cpython-38.pyc differ diff --git a/team#17-education/__pycache__/ocr.cpython-39.pyc b/team#17-education/__pycache__/ocr.cpython-39.pyc new file mode 100644 index 0000000..08cff4d Binary files /dev/null and b/team#17-education/__pycache__/ocr.cpython-39.pyc differ diff --git a/team#17-education/__pycache__/register.cpython-38.pyc b/team#17-education/__pycache__/register.cpython-38.pyc new file mode 100644 index 0000000..f535cf0 Binary files /dev/null and b/team#17-education/__pycache__/register.cpython-38.pyc differ diff --git a/team#17-education/__pycache__/register.cpython-39.pyc b/team#17-education/__pycache__/register.cpython-39.pyc new file mode 100644 index 0000000..9f4c6b9 Binary files /dev/null and b/team#17-education/__pycache__/register.cpython-39.pyc differ diff --git a/team#17-education/__pycache__/stackoverflow.cpython-38.pyc b/team#17-education/__pycache__/stackoverflow.cpython-38.pyc new file mode 100644 index 0000000..fc0fe92 Binary files /dev/null and b/team#17-education/__pycache__/stackoverflow.cpython-38.pyc differ diff --git a/team#17-education/__pycache__/stackoverflow.cpython-39.pyc b/team#17-education/__pycache__/stackoverflow.cpython-39.pyc new file mode 100644 index 0000000..bf10933 Binary files /dev/null and b/team#17-education/__pycache__/stackoverflow.cpython-39.pyc differ diff --git a/team#17-education/admins.py b/team#17-education/admins.py new file mode 100644 index 0000000..6c0603d --- /dev/null +++ b/team#17-education/admins.py @@ -0,0 +1,30 @@ +import requests +import json +import configparser as cfg + + +class CS_toolkit(): + + def __init__(self, config): + self.token = self.read_token_from_config_file(config) + self.base = "https://api.telegram.org/bot{}/".format(self.token) + + def getUpdates(self, offset=None): + url = self.base + "getUpdates?timeout=100" #Timeout = 100 to avoid requesting endpoint again and again + if offset: + url += "&offset={}".format(offset + 1) + + r = requests.get(url) + return json.loads(r.content) + + def sendMessage(self, msg, chat_id, reply_markup): + url = self.base + "sendMessage?chat_id={}&text={}".format(chat_id, msg) + if reply_markup is not None: + url += "&reply_markup={}".format(reply_markup) + if msg is not None: + requests.get(url) + + def read_token_from_config_file(self, config): + parser = cfg.ConfigParser() + parser.read(config) + return parser.get('creds', 'token') diff --git a/team#17-education/codeforces.py b/team#17-education/codeforces.py new file mode 100644 index 0000000..751da41 --- /dev/null +++ b/team#17-education/codeforces.py @@ -0,0 +1,55 @@ +import requests +import json +from admins import CS_toolkit +from telegram import ForceReply +import random + +bot = CS_toolkit("config.cfg") + +class Codeforces(): + def __init__(self): + self.base = "https://codeforces.com/api/" + + def get_user_info(self, handle): + url = self.base + "user.info?handles={}".format(handle) + r = requests.get(url) + return json.loads(r.content) + + def get_problem_by_tag(self, tag): + url = self.base + "problemset.problems?tags={}".format(tag) + r = requests.get(url) + return json.loads(r.content) + + def chosen_option(self, chat_id, update_id): + callback = bot.getUpdates(offset=update_id) + update_id+=1 + callback = callback["result"][0]["callback_query"]["data"] + if(callback == "profile"): + bot.sendMessage("Enter your handle: ", chat_id, None) + reply = bot.getUpdates(offset=update_id) + update_id+=1 + reply = reply["result"][0]["message"]["text"] + profile = self.get_user_info(reply) + profile_str = "Profile Name: {}\nRating: {}\nRank: {}\nMax Rating: {}\nMax Rank: {}".format(profile["result"][0]["handle"], profile["result"][0]["rating"], profile["result"][0]["rank"], profile["result"][0]["maxRating"], profile["result"][0]["maxRank"]) + bot.sendMessage(profile_str, chat_id, None) + elif(callback == "problem"): + bot.sendMessage("Enter a tag for problem", chat_id, None) + reply = bot.getUpdates(offset=update_id) + update_id+=1 + reply = reply["result"][0]["message"]["text"] + problems = self.get_problem_by_tag(reply) + problems = problems["result"]["problems"] + problem = random.choice(problems) + url = "https://codeforces.com/problemset/problem/{}/{}".format(problem["contestId"],problem["index"]) + bot.sendMessage(url, chat_id, None) + + def show_options(self, chat_id, update_id): + keyBoard = { "inline_keyboard": [ + [ + {"text": "Profile", "callback_data": "profile"}, + {"text": "Problem", "callback_data": "problem"} + ], + ] + } + bot.sendMessage("Please select one of the following:", chat_id, reply_markup=json.dumps(keyBoard)) + self.chosen_option(chat_id, update_id) \ No newline at end of file diff --git a/team#17-education/config.cfg b/team#17-education/config.cfg new file mode 100644 index 0000000..3e6c45f --- /dev/null +++ b/team#17-education/config.cfg @@ -0,0 +1,9 @@ +[creds] +token = 1651920399:AAHrId7JydTx9O4boUEx__MdWt8ZcVbmKNs + +[codeforces] +key = fbeb5fb261d83d3bb455a1b087fe44b85fac90d3 +secret = 753015ee556d87425f43b5eed951e447a90ae04d + +[github] +key = 9c55329fa6a4aabcb6ca775963f261c943e7c56a \ No newline at end of file diff --git a/team#17-education/gfg.py b/team#17-education/gfg.py new file mode 100644 index 0000000..fa902ca --- /dev/null +++ b/team#17-education/gfg.py @@ -0,0 +1,24 @@ +import requests +import json +from admins import CS_toolkit +from telegram import InlineKeyboardButton, InlineKeyboardMarkup, ForceReply +import telegram + +bot = CS_toolkit("config.cfg") + +class GFG(): + def __init__(self): + self.platforms = ["GeeksforGeeks"] + def options(self, chat_id): + keyBoard = { "inline_keyboard": [ + [ + {"text": "Algorithms", "url": "https://www.geeksforgeeks.org/fundamentals-of-algorithms/"}, + {"text": "Data Structures", "url": "https://www.geeksforgeeks.org/data-structures/"}, + ], + [ + {"text": "Interview Prep", "url": "https://www.geeksforgeeks.org/company-interview-corner/"}, + {"text": "GATE Prep", "url": "https://www.geeksforgeeks.org/gate-cs-notes-gq/"} + ] + ] + } + bot.sendMessage("Please select one of the following:", chat_id, reply_markup=json.dumps(keyBoard)) diff --git a/team#17-education/github.py b/team#17-education/github.py new file mode 100644 index 0000000..728081c --- /dev/null +++ b/team#17-education/github.py @@ -0,0 +1,54 @@ +import requests +import json +from admins import CS_toolkit +from telegram import ForceReply +import random + + +bot = CS_toolkit("config.cfg") + +class Github(): + def __init__(self): + self.base = "https://api.github.com/" + + def show_options(self, chat_id, update_id): + keyBoard = { "inline_keyboard": [ + [ + {"text": "Profile", "callback_data": "users"}, + {"text": "Search by Username", "callback_data": "search"} + ], + ] + } + bot.sendMessage("Please select one of the following:", chat_id, reply_markup=json.dumps(keyBoard)) + self.chosen_option(chat_id, update_id) + + def get_user_info(self, username): + url = self.base + "users/{}".format(username) + r = requests.get(url) + return json.loads(r.content) + + def search_users(self, username): + url = self.base + "search/users/{}".format(username) + r = requests.get(url) + return json.loads(r.content) + + def chosen_option(self, chat_id, update_id): + callback = bot.getUpdates(offset=update_id) + update_id += 1 + callback = callback["result"][0]["callback_query"]["data"] + if(callback == "users"): + bot.sendMessage("Enter your username: ", chat_id, None) + reply = bot.getUpdates(offset = update_id) + update_id += 1 + reply = reply["result"][0]["message"]["text"] + profile = self.get_user_info(reply) + profile_str = "Profile Name: {}\nCompany: {}\nFollowers: {}\nFollowing: {}\nRepos URL: {}".format(profile["name"], profile["company"], profile["followers"], profile["following"], profile["repos_url"]) + bot.sendMessage(profile_str, chat_id, None) + if(callback == "search"): + bot.sendMessage("Enter username: ", chat_id, None) + reply = bot.getUpdates(offset = update_id) + update_id += 1 + reply = reply["result"][0]["message"]["text"] + profile = self.get_user_info(reply) + profile_str = "Profile URL: {}\nRepos URL: {}".format(profile["html_url"], profile["repos_url"]) + bot.sendMessage(profile_str, chat_id, None) \ No newline at end of file diff --git a/team#17-education/image.py b/team#17-education/image.py new file mode 100644 index 0000000..8b6f6c1 --- /dev/null +++ b/team#17-education/image.py @@ -0,0 +1,26 @@ +import requests +import json +from admins import CS_toolkit +from ocr import OCR + + +bot = CS_toolkit("config.cfg") +ocr_ = OCR() + +class Image(): + + def take_image(self, sender, update_id): + bot.sendMessage("Please send your image: ", sender, None) + image = bot.getUpdates(offset=update_id) + update_id += 1 + try: + image_id = image["result"][0]["message"]["document"][0]["file_id"] + except: + image_id = image["result"][0]["message"]["photo"][0]["file_id"] + url = bot.base + "getFile?file_id={}".format(image_id) + r = requests.get(url) + content = json.loads(r.content) + image_file_path = content["result"]["file_path"] + url = "https://api.telegram.org/file/bot{}/{}".format(bot.token, image_file_path) + # print(url) + return bot.sendMessage(ocr_.ocr_space_url(url), sender, None) \ No newline at end of file diff --git a/team#17-education/ocr.py b/team#17-education/ocr.py new file mode 100644 index 0000000..64cdea0 --- /dev/null +++ b/team#17-education/ocr.py @@ -0,0 +1,15 @@ +import requests +import json +from admins import CS_toolkit +from stackoverflow import StackOverflow + +bot = CS_toolkit("config.cfg") +stackoverflow_ = StackOverflow() + +class OCR(): + def ocr_space_url(self, url, api_key="helloworld"): + # print(str(url)) + r = requests.get("https://api.ocr.space/parse/imageurl?apikey=helloworld&url={}&filetype=jpg".format(str(url))) + text = json.loads(r.content.decode()) + text = text["ParsedResults"][0]["ParsedText"] + return stackoverflow_.get_question_by_tag(text) \ No newline at end of file diff --git a/team#17-education/register.py b/team#17-education/register.py new file mode 100644 index 0000000..01a1a92 --- /dev/null +++ b/team#17-education/register.py @@ -0,0 +1,35 @@ +import requests +import json +from admins import CS_toolkit +from telegram import InlineKeyboardButton, InlineKeyboardMarkup, ForceReply +from codeforces import Codeforces +from github import Github + +bot = CS_toolkit("config.cfg") +codeforces = Codeforces() +github = Github() +class Register(): + def __init__(self): + self.platforms = ["Codeforces", "Codechef", "Github"] + + def chosen_platform(self, chat_id, update_id): + callback = bot.getUpdates(offset=update_id) + callback = callback["result"][0]["callback_query"]["data"] + if(callback == "cf"): + codeforces.show_options(chat_id, update_id+1) + if(callback == "gh"): + github.show_options(chat_id, update_id+1) + + def show_options(self, chat_id, update_id): + keyBoard = { "inline_keyboard": [ + [ + {"text": self.platforms[0], "callback_data": "cf"}, + {"text": self.platforms[1], "callback_data": "chef"} + ], + [ + {"text": self.platforms[2], "callback_data": "gh"} + ] + ] + } + bot.sendMessage("Please select one of the following:", chat_id, reply_markup=json.dumps(keyBoard)) + self.chosen_platform(chat_id, update_id) diff --git a/team#17-education/server.py b/team#17-education/server.py new file mode 100644 index 0000000..e7eef63 --- /dev/null +++ b/team#17-education/server.py @@ -0,0 +1,79 @@ +from admins import CS_toolkit +from telegram import InlineKeyboardButton, InlineKeyboardMarkup +from register import Register +import json +from gfg import GFG +from image import Image + + +gfg_links = """{ + "Search": "https://www.geeksforgeeks.org/searching-algorithms/", + "Sort": "https://www.geeksforgeeks.org/sorting-algorithms/", + "DP": "https://www.geeksforgeeks.org/dynamic-programming/", + "DnC": "https://www.geeksforgeeks.org/divide-and-conquer/" + }""" +bot = CS_toolkit("config.cfg") +register_ = Register() +gfg_ = GFG() +image_ = Image() + +def displayLink(key): + links = json.loads(gfg_links) + if key in links: + return bot.sendMessage(links[key], sender, None) + else: + return bot.sendMessage("Ehh.. maybe a wrong spelling or command, check again.", sender, None) + +def reply(msg, sender, update_id): + if msg is None: + return + elif msg == "/start": + return bot.sendMessage("Hey There!\nThis is your one-stop bot for all CS related things.\nType /help to see all commands.", sender, None) + elif msg == "/help": + return bot.sendMessage("""You can use the following commands: + /start : to start the bot. + /help : to get a list of commands. + /gfg : to fetch categories of articles from GeeksforGeeks. + /search_algos : to fetch the link to learn about searching algorithms. + /sort_algos : to fetch the link to learn about sorting algorithms. + /dp : to fetch the link to learn about dynamic programming. + /dnc : to fetch the link to learn about divide and conquer. + /platform : to access different online platforms through this bot. + /error : to take an image of your error and search it on stackoverflow. + """, + sender, None) + elif msg == "/gfg": + return gfg_.options(sender) + elif msg == "/search_algos": + key = "Search" + return displayLink(key) + elif msg == "/sort_algos": + key = "Sort" + return displayLink(key) + elif msg == "/dp": + key = "DP" + return displayLink(key) + elif msg == "/dnc": + key = "DnC" + return displayLink(key) + elif msg == "/platform": + return register_.show_options(sender, update_id) + elif msg == "/error": + return image_.take_image(sender, update_id) + elif msg is not None: + return bot.sendMessage("Okay!", sender, None) + +update_id = None +while True: + updates = bot.getUpdates(offset=update_id) + updates = updates["result"] + if updates: + for item in updates: + update_id = item["update_id"] + try: + msg = item["message"]["text"] + sender = item["message"]["from"]["id"] + except: + msg = None + sender = None + reply(msg, sender, update_id) \ No newline at end of file diff --git a/team#17-education/stackoverflow.py b/team#17-education/stackoverflow.py new file mode 100644 index 0000000..cdc27e7 --- /dev/null +++ b/team#17-education/stackoverflow.py @@ -0,0 +1,18 @@ +import requests +import json +from admins import CS_toolkit + + +bot = CS_toolkit("config.cfg") + +class StackOverflow(): + + def __init__(self): + self.base = "https://api.stackexchange.com/2.2/" + + def get_question_by_tag(self, tag): + url = self.base + "questions?site=stackoverflow&tagged={}&sort=votes&order=desc".format(tag) + r = requests.get(url) + content = json.loads(r.content) + content = content["items"][0]["link"] + return content