Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update db.py #13

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
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
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Finally, we created various functions that would enhance a user's experience on
7. **Stalk**: One user can stalk any other user on the judge using this feature, which provides the problems solved by that user and their rating
8. **Rating Change**: Provides the rating changes and results of a specific contest queried
9. **Graphs**: Provides graphs pertaining to various features such as performance, problems solved over time and ratings of problems solved over time
10. **Chat**: Enables chatting with bot using Google-Gemini AI model.

The commands for all these features and their usage can be retrieved by executing the command ```;help``` in the server.

Expand All @@ -40,6 +41,7 @@ Install the required dependencies:
7. [quickchart.io](https://pypi.org/project/quickchart-io/)
8. [nest_asyncio](https://pypi.org/project/nest-asyncio/)
9. [table2ascii](https://table2ascii.readthedocs.io/en/stable/)
10. [google-generativeai](https://pypi.org/project/google-generativeai/)

Finally, the bot can be started by running the ``main.py`` file.

Expand All @@ -52,6 +54,7 @@ The process.env file used in the bot:
**TOKEN**: Each bot, upon its creation, is given a `token` by Discord which is used by `discord.py` in running the bot. <br>
**GUILD**: It is the `id` of the `channel` one wants the bot to run on. <br>
**CLIST_TOKEN**: It is the token that is required for making a `clist api` call, it can be availed by making an account on [clist.by](https://clist.by/)
**GOOGLE_API**: It is the token that is required for making a `google-gemini api` call, it can be availed by making an account on [ai.google.dev](https://ai.google.dev/?utm_source=google&utm_medium=cpc&utm_campaign=brand_core_brand&gad_source=1)

# Working
![image](https://github.com/Sparsh752/TLE_Python/assets/21035646/69b33f10-a6cd-46a4-9ecd-5b543f158bd3)<br>
Expand All @@ -67,8 +70,17 @@ The process.env file used in the bot:


# Credits

This project was made by:
Project(2023) update and modifications were done by:
1. [Dev Shah](https://github.com/DevvvvvShah)
2. [Shreyans Garg](https://github.com/ShreyansGarg)
3. [Soumya Savarn](https://github.com/SoumyaSavarn)
4. [Mohd. Faiz]((https://github.com/FAIZMOHD1))
5. [Tanmay Mittal](https://github.com/Tanmay7404)
6. [Ashutosh Bala]((https://github.com/ArtValor))
7. [Arush Mathur]((https://github.com/arushmathur))
8. [Dhyey Patel]((https://github.com/CosmicNoise2907))

Project(2022) was started by :
1. [Sparsh Mittal](https://github.com/Sparsh752)
2. [Adittya Gupta](https://github.com/Adittya-Gupta)
3. [Yash Raj Singh](https://github.com/Yash-jar)
Expand Down
28 changes: 20 additions & 8 deletions _handle_verification_.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,25 @@ async def check_cf(username):

#Fetching firstName from codeforces for handle_verification
async def firstname(cf_handle):
cf_api = "https://codeforces.com/api/user.info?handles=" + cf_handle
response = requests.get(cf_api)
cf_list = response.json()['result'][0]
if "firstName" in cf_list.keys():
firstname_ = cf_list['firstName']
cf_url = "https://codeforces.com/profile/" + cf_handle
web_resposne = requests.get(cf_url)
html_page = BeautifulSoup(web_resposne.text, "lxml")
user_box = html_page.find('div', class_ = "userbox")
try:
name_line = user_box.find('div', style="font-size: 0.8em; color: #777;").text.split()
firstname_ = name_line[0]
return firstname_
else:
# print("first name does not exist")
except:
return ""
# cf_api = "https://codeforces.com/api/user.info?handles=" + cf_handle
# response = requests.get(cf_api)
# cf_list = response.json()["result"][0]
# if "firstName" in cf_list.keys():
# firstname_ = cf_list["firstName"]
# return firstname_
# else:
# # print("first name does not exist")
# return ""

##CodeChef
#Checking whether handle submitted exists or not
Expand Down Expand Up @@ -137,7 +147,9 @@ async def handle_verification(ctx,bot):
await rating_role(ctx.author.id,int(rating),bot,channel)
break
else:
await msg.edit(content=f"{message.author.mention} TimeOut, try again...")
await message.channel.send(content=f"{message.author.mention} TimeOut, try again...")
# await msg.edit(content=f"{message.author.mention} TimeOut, try again...")
# error throw karri thi upper wali line for some reason

else:
await msg.edit(content=f"{message.author.mention} given handle is invalid")
Expand Down
25 changes: 22 additions & 3 deletions bot.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import discord
import chat
from contest_reminder import reminder
from _handle_verification_ import handle_verification
import gitgud
Expand Down Expand Up @@ -39,17 +40,20 @@ async def on_disconnect():
async def on_connection_error(error):
print(error)
await reconnect()



@client.event
async def on_message(ctx):
if ctx.author == client.user: #will keep messaging itself without this
if ctx.author == client.user:
#will keep messaging itself without this
return
user_message=str(ctx.content)
if (user_message.startswith(';challenge')):
await challenge.challenge_question_cf(ctx,client)
if (user_message.startswith(';identify')):
await handle_verification(ctx,client)
# if user_message[0]=='?': #checking if message is private
# if user_message[0]=='?':
#checking if message is private
# user_message=user_message[1:]
# await send_message(ctx,user_message,is_private=True) #message is private
elif user_message.split()[0]==";gitlog":
Expand All @@ -60,8 +64,14 @@ async def on_message(ctx):
await msg.edit(content=f"{ctx.author.mention} You have not solved any problem yet. use ;gitgud to get a problem")
else:
await table(ctx,client,['Problem Name','Problem Rating','Points'], mydict, isEmbed=True, current_message=msg)

elif user_message.split()[0]==";next":
await clist_api.nextcontests(ctx)

#enables chat bot
elif user_message.split()[0]==";chat":
await chat.start_chat(ctx,client)

elif user_message.split()[0]==";leaderboard":
if len(user_message.split())==2:
mylist,res = await db.Leaderboard_list(ctx,user_message.split()[1])
Expand All @@ -77,6 +87,7 @@ async def on_message(ctx):
await res.edit(content=f"{ctx.author.mention} Please enter a valid platform")
else:
await ctx.channel.send(f"{ctx.author.mention} Please enter a valid platform")

elif user_message.split()[0]==";stalk":
if len(user_message.split())==2:
temp = await stalk.stalk_user(ctx,user_message.split()[1])
Expand Down Expand Up @@ -105,6 +116,7 @@ async def on_message(ctx):
return
else:
await ctx.channel.send(f"{ctx.author.mention} Please follow the message format")

elif user_message.split()[0]==";ratingchange":
if len(user_message.split())==3:
if(user_message.split()[1]=="cf"):
Expand All @@ -127,31 +139,38 @@ async def on_message(ctx):
await ctx.channel.send(f"{ctx.author.mention} Please specify a valid platform")
else:
await ctx.channel.send(f"{ctx.author.mention} Please follow the message format")

elif user_message.split()[0]==";performance":
if len(user_message.split())==2:
await performance(ctx,user_message.split()[1])
else:
await ctx.channel.send(f"{ctx.author.mention} Please follow the message format")

elif user_message.split()[0]==";graph":
if(user_message.split()[1]=="rvp"):
await rating_vs_problems(ctx)
elif(user_message.split()[1]=="pvt"):
await problem_vs_time(ctx)
else:
await ctx.channel.send(f"{ctx.author.mention} Please follow the message format")

elif user_message.split()[0]==";help":
content=await help_command()
await ctx.channel.send(embed=content)

elif user_message.split()[0]==";gitgud":
return await gitgud.gitgud(ctx)

elif user_message.split()[0]==";gotgud":
return await gitgud.gotgud(ctx)

elif user_message.split()[0]==";nogud":
if len(user_message.split())==2:
if user_message.split()[1]=="cf":
return await gitgud.nogud_cf(ctx)
elif user_message[1]=="ac":
return await gitgud.nogud_atcoder(ctx)

elif user_message.split()[0]==";gimme":
return await gitgud.gimme(ctx)
return "Sorry, I didn't understand that :smiling_face_with_tear: Try ;help for more info"
Expand Down
18 changes: 8 additions & 10 deletions challenge.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from db import get_codeforces_handle,get_last_solved_problems,find_solved_codeforces,get_atcoder_handle,find_solved_atcoder
from db import get_codeforces_handle,find_solved_codeforces,get_atcoder_handle,find_solved_atcoder
from gitgud import get_cf_user_rating,get_ac_user_rating,check_if_solved,get_ac_problem_difficulty,convertAC2CFrating,check_if_solved_ac
from random_question import cf_get_random_question_rating,ac_get_random_question
import asyncio
Expand Down Expand Up @@ -44,10 +44,9 @@ async def challenge_question_cf(ctx,bot): # function to challenge a user on code
# getting appropriate question for the challenge according to the rating of the user from codeforces
cf_rating = await get_cf_user_rating(cf_handle_2)
cf_rating = (cf_rating//100)*100
last_checked_1,last_solved_problems_1 = await get_last_solved_problems(ctx,'codeforces')
last_checked_2,last_solved_problems_2 = await get_last_solved_problems(ctx_second,'codeforces')
solved_problems_1 = await find_solved_codeforces(ctx,cf_handle_1,last_solved_problems_1,last_checked_1)
solved_problems_2 = await find_solved_codeforces(ctx_second,cf_handle_2,last_solved_problems_2,last_checked_2)

solved_problems_1 = await find_solved_codeforces(ctx,cf_handle_1)
solved_problems_2 = await find_solved_codeforces(ctx_second,cf_handle_2)
solved_problems=[]
solved_problems.extend(solved_problems_1)
solved_problems.extend(solved_problems_2)
Expand Down Expand Up @@ -118,10 +117,9 @@ async def challenge_question_cf(ctx,bot): # function to challenge a user on code
return
await msg.edit(content=f"Wait {ctx.author.mention} the bot is thinking 🤔 a problem for you....... ")
# getting random question for the challenge from atcoder
last_checked_1,last_solved_problems_1 = await get_last_solved_problems(ctx,'atcoder')
last_checked_2,last_solved_problems_2 = await get_last_solved_problems(ctx_second,'atcoder')
solved_problems_1 = await find_solved_atcoder(ctx,ac_handle_1,last_solved_problems_1,last_checked_1)
solved_problems_2 = await find_solved_atcoder(ctx_second,ac_handle_2,last_solved_problems_2,last_checked_2)

solved_problems_1 = await find_solved_atcoder(ctx,ac_handle_1)
solved_problems_2 = await find_solved_atcoder(ctx_second,ac_handle_2)
solved_problems=[]
solved_problems.extend(solved_problems_1)
solved_problems.extend(solved_problems_2)
Expand Down Expand Up @@ -196,4 +194,4 @@ async def challenge_question_cf(ctx,bot): # function to challenge a user on code
elif reaction.emoji == "❌":
# challenge rejected
await ctx.channel.send(f"{ctx.author.mention} {ctx.mentions[0].mention} has declined the challenge")
return
return
62 changes: 62 additions & 0 deletions chat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#Documentation: https://ai.google.dev/tutorials/python_quickstart
import discord
import bot
import asyncio

from dotenv import load_dotenv
load_dotenv('process.env')

import os
import pathlib
import textwrap

import google.generativeai as genai

from IPython.display import display
from IPython.display import Markdown

GOOGLE_API = os.environ.get('GOOGLE_API')

#source(for getting API): https://ai.google.dev/?utm_source=google&utm_medium=cpc&utm_campaign=brand_core_brand&gad_source=1

genai.configure(api_key=GOOGLE_API)
model = genai.GenerativeModel('gemini-pro')


async def start_chat(ctx,bot):

await ctx.channel.send("Ask me anything")
prompt="CONTEXT: Your name is 'EnEm Jr.' . You are a replica of a legendary competitve programmer named 'EnEm' trained by Competitive Programming Module, IIT Guwahati.Your name is 'EnEm Jr.' . Since EnEm left the club, now it is your responsibility to guide the young ones. Don't forget it. You are a professional coach,a guide and a responsible programmer and always help aspiring programmers . You prefer Codeforces and AtCoder more as they are best sites for practice according to you. You also prefer Leetcode for Data Structures and Algorithm. You pick random problems from https://codeforces.com/problemset if codeforces is concerned. Your answers possess humour, motivation and kindness. Also you don't repeat answers and stick around the world of Competitive Programming. Don't forget to be humble and apologize for your mistakes. You also tend to ignore mild cuss words in a funny way. Now give answers to the 'User' in a motivating way .You also can ask questions sometimes.\n"


while True:

def is_ok(m):
if ctx.author == bot.user:
return 0
else:
return 1
try:
msg = await bot.wait_for('message', check=is_ok, timeout=150.0)
except asyncio.TimeoutError:
return await ctx.channel.send(f'Sorry, you took too long to respond.')

new_prompt = str(msg.content)



if new_prompt[0]==';':
await ctx.channel.send("Thanks for chatting. Ending Chat Mode.")
break

prompt+="LATEST User: " + new_prompt
if len(new_prompt)<=3:
prompt+="Now change the topic of conversation."

response = model.generate_content(prompt+ "If the user is asking for a detailed answer then only give a detailed one else keep the conversation like a chat.")

await ctx.channel.send(response.text)
prompt+=(" Your answer: " + response.text)


return
Loading