From 102103b8fb2d8a09b596a500dcee05120ce33dba Mon Sep 17 00:00:00 2001 From: sasi Date: Wed, 31 Jul 2024 12:38:45 +0530 Subject: [PATCH 01/21] addind print --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index f7f1142..64ba1aa 100644 --- a/main.py +++ b/main.py @@ -147,6 +147,7 @@ async def on_submit(self, interaction: discord.Interaction): view=AuthenticationView(user.id), ephemeral=True, ) + print(self,"self") await self.post_data( { "name": self.name.value, From 0c23308c51ee73dd3fa44cf9efe33464ef132aaa Mon Sep 17 00:00:00 2001 From: sasi Date: Mon, 19 Aug 2024 19:04:46 +0530 Subject: [PATCH 02/21] query converted to ORM --- cogs/badges.py | 12 +- cogs/discordDataScraper.py | 28 +- cogs/listeners/member_events_cog.py | 6 +- cogs/listeners/message_events_cog.py | 6 +- cogs/listeners/role_events_cog.py | 12 +- cogs/serverManagement.py | 16 +- cogs/userInteractions.py | 30 +- cogs/vcCog.py | 12 +- helpers/supabaseClient.py | 257 ++++- main.py | 6 +- models.py | 1526 ++++++++++++++++++++++++++ requirements.txt | 2 + 12 files changed, 1848 insertions(+), 65 deletions(-) create mode 100644 models.py diff --git a/cogs/badges.py b/cogs/badges.py index 665d53c..7d728be 100644 --- a/cogs/badges.py +++ b/cogs/badges.py @@ -3,7 +3,7 @@ import discord from discord.ext import commands -from helpers.supabaseClient import SupabaseClient +from helpers.supabaseClient import PostgresClient class BadgeModal(discord.ui.Modal, title="Your Badges"): @@ -133,7 +133,7 @@ def get_user_badges(self, discord_id): userBadges = {"points": [], "achievements": []} if ( len( - SupabaseClient().read( + PostgresClient().read( "contributors_registration", query_key="discord_id", query_value=discord_id, @@ -143,7 +143,7 @@ def get_user_badges(self, discord_id): ): userBadges["achievements"].append(self.discordXGithubBadge) - discordMemberData = SupabaseClient().read( + discordMemberData = PostgresClient().read( "discord_engagement", "contributor", discord_id ) if discordMemberData: @@ -153,16 +153,16 @@ def get_user_badges(self, discord_id): userBadges["achievements"].append(self.rockstarBadge) if discordMemberData[0]["has_introduced"]: userBadges["achievements"].append(self.apprenticeBadge) - contributorData = SupabaseClient().read( + contributorData = PostgresClient().read( "contributors_registration", query_key="discord_id", query_value=discord_id ) if contributorData: github_id = contributorData[0]["github_id"] prData = { - "raised": SupabaseClient().read( + "raised": PostgresClient().read( table="connected_prs", query_key="raised_by", query_value=github_id ), - "merged": SupabaseClient(table="connected_prs").read( + "merged": PostgresClient(table="connected_prs").read( table="connected_prs", query_key="merged_by", query_value=github_id ), } diff --git a/cogs/discordDataScraper.py b/cogs/discordDataScraper.py index 5097c99..b78565a 100644 --- a/cogs/discordDataScraper.py +++ b/cogs/discordDataScraper.py @@ -9,7 +9,7 @@ from discord.channel import TextChannel from discord.ext import commands, tasks -from helpers.supabaseClient import SupabaseClient +from helpers.supabaseClient import PostgresClient with open("config.json") as config_file: config_data = json.load(config_file) @@ -28,12 +28,12 @@ def __init__(self, bot) -> None: @commands.Cog.listener() async def on_message(self, message): pass - # contributor = SupabaseClient().read( + # contributor = PostgresClient().read( # "discord_engagement", "contributor", message.author.id # ) # print("message", len(message.content)) # if not contributor: - # SupabaseClient().insert( + # PostgresClient().insert( # "discord_engagement", # { # "contributor": message.author.id, @@ -46,13 +46,13 @@ async def on_message(self, message): # if len(message.content) > 20: # if message.channel.id == INTRODUCTIONS_CHANNEL_ID: # print("intro") - # SupabaseClient().update( + # PostgresClient().update( # "discord_engagement", # {"has_introduced": True}, # "contributor", # message.author.id, # ) - # SupabaseClient("discord_engagement").update( + # PostgresClient("discord_engagement").update( # "discord_engagement", # {"total_message_count": contributor[0]["total_message_count"] + 1}, # "contributor", @@ -62,11 +62,11 @@ async def on_message(self, message): @commands.Cog.listener() async def on_reaction_add(self, reaction, user): message = reaction.message - contributor = SupabaseClient().read( + contributor = PostgresClient().read( "discord_engagement", "contributor", message.author.id )[0] if not contributor: - SupabaseClient().insert( + PostgresClient().insert( "discord_engagement", { "contributor": message.author.id, @@ -77,7 +77,7 @@ async def on_reaction_add(self, reaction, user): ) return print("reaction") - SupabaseClient().update( + PostgresClient().update( "discord_engagement", {"total_reaction_count": contributor["total_reaction_count"] + 1}, "contributor", @@ -89,7 +89,7 @@ async def add_engagement(self, ctx): await ctx.channel.send("started") def addEngagmentData(data): - client = SupabaseClient() + client = PostgresClient() client.insert("discord_engagement", data) return @@ -145,7 +145,7 @@ async def enable_webhook(self, ctx): channels = await guild.fetch_channels() enabled = [ channel["channel_id"] - for channel in SupabaseClient().read_all("discord_channels") + for channel in PostgresClient().read_all("discord_channels") ] for channel in channels: try: @@ -156,7 +156,7 @@ async def enable_webhook(self, ctx): webhook = await channel.create_webhook(name="New Ticket Alert") feedback = f"""URL: {webhook.url}\n Token:{"Yes" if webhook.token else "No"}""" await ctx.send(feedback) - SupabaseClient().insert( + PostgresClient().insert( "discord_channels", { "channel_id": channel.id, @@ -177,7 +177,7 @@ async def update_applicants(self, ctx): await ctx.send("Member List Count: " + str(len(members))) for member in members: try: - SupabaseClient().insert( + PostgresClient().insert( "applicant", {"sheet_username": member.name, "discord_id": member.id}, ) @@ -216,12 +216,12 @@ async def collect_all_messages(self): async def add_messages(self): def addMessageData(data): - client = SupabaseClient() + client = PostgresClient() client.insert("unstructured discord data", data) return def getLastMessageObject(channelId): - last_message = SupabaseClient().read_by_order_limit( + last_message = PostgresClient().read_by_order_limit( table="unstructured discord data", query_key="channel", query_value=channelId, diff --git a/cogs/listeners/member_events_cog.py b/cogs/listeners/member_events_cog.py index b743de2..3a353e2 100644 --- a/cogs/listeners/member_events_cog.py +++ b/cogs/listeners/member_events_cog.py @@ -1,7 +1,7 @@ import discord from discord.ext import commands -from helpers.supabaseClient import SupabaseClient +from helpers.supabaseClient import PostgresClient class MemberEventsListener(commands.Cog): @@ -11,7 +11,7 @@ def __init__(self, bot) -> None: @commands.Cog.listener("on_member_join") async def on_member_join(self, member: discord.Member): - SupabaseClient().updateContributor(member) + PostgresClient().updateContributor(member) @commands.Cog.listener("on_member_remove") async def on_member_remove(self, member: discord.Member): @@ -20,7 +20,7 @@ async def on_member_remove(self, member: discord.Member): @commands.Cog.listener("on_member_update") async def on_member_update(self, before: discord.Member, after: discord.Member): - SupabaseClient().updateContributor(after) + PostgresClient().updateContributor(after) async def setup(bot: commands.Bot): diff --git a/cogs/listeners/message_events_cog.py b/cogs/listeners/message_events_cog.py index 0fb4462..5c8047d 100644 --- a/cogs/listeners/message_events_cog.py +++ b/cogs/listeners/message_events_cog.py @@ -2,10 +2,10 @@ from discord.ext import commands from config.server import ServerConfig -from helpers.supabaseClient import SupabaseClient +from helpers.supabaseClient import PostgresClient serverConfig = ServerConfig() -supabaseClient = SupabaseClient() +postgresClient = PostgresClient() async def grantVerifiedRole(member: discord.Member): @@ -32,7 +32,7 @@ def __init__(self, bot) -> None: async def on_message(self, message: discord.Message): # Listen for Introduction if message.channel.id == serverConfig.Channels.INTRODUCTION_CHANNEL: - if await supabaseClient.memberIsAuthenticated(message.author): + if await postgresClient.memberIsAuthenticated(message.author): await grantVerifiedRole(message.author) else: return diff --git a/cogs/listeners/role_events_cog.py b/cogs/listeners/role_events_cog.py index 482672e..68a2855 100644 --- a/cogs/listeners/role_events_cog.py +++ b/cogs/listeners/role_events_cog.py @@ -1,7 +1,7 @@ import discord from discord.ext import commands -from helpers.supabaseClient import SupabaseClient +from helpers.supabaseClient import PostgresClient class RoleEventsListener(commands.Cog): @@ -13,27 +13,27 @@ def __init__(self, bot) -> None: async def on_guild_role_create(self, role: discord.Role): if role.name.startswith("College:"): orgName = role.name[len("College: ") :] - SupabaseClient().addChapter(roleId=role.id, orgName=orgName, type="COLLEGE") + PostgresClient().addChapter(roleId=role.id, orgName=orgName, type="COLLEGE") elif role.name.startswith("Corporate:"): orgName = role.name[len("Corporate: ") :] - SupabaseClient().addChapter( + PostgresClient().addChapter( roleId=role.id, orgName=orgName, type="CORPORATE" ) @commands.Cog.listener() async def on_guild_role_delete(self, role: discord.Role): - SupabaseClient().deleteChapter(roleID=role.id) + PostgresClient().deleteChapter(roleID=role.id) @commands.Cog.listener() async def on_guild_role_update(self, before: discord.Role, after: discord.Role): if after.name.startswith("College:"): orgName = after.name[len("College: ") :] - SupabaseClient().addChapter( + PostgresClient().addChapter( roleId=after.id, orgName=orgName, type="COLLEGE" ) elif after.name.startswith("Corporate:"): orgName = after.name[len("Corporate: ") :] - SupabaseClient().addChapter( + PostgresClient().addChapter( roleId=after.id, orgName=orgName, type="CORPORATE" ) diff --git a/cogs/serverManagement.py b/cogs/serverManagement.py index f096c0c..8c861e9 100644 --- a/cogs/serverManagement.py +++ b/cogs/serverManagement.py @@ -3,7 +3,7 @@ from discord.ext import commands, tasks from config.server import ServerConfig -from helpers.supabaseClient import SupabaseClient +from helpers.supabaseClient import PostgresClient serverConfig = ServerConfig() @@ -42,20 +42,20 @@ async def getServerData(self, ctx): if role.name.startswith("College:"): orgName = role.name[len("College: ") :] chapterRoles.append(role) - SupabaseClient().addChapter( + PostgresClient().addChapter( roleId=role.id, orgName=orgName, type="COLLEGE" ) elif role.name.startswith("Corporate:"): orgName = role.name[len("Corporate: ") :] chapterRoles.append(role) - SupabaseClient().addChapter( + PostgresClient().addChapter( roleId=role.id, orgName=orgName, type="CORPORATE" ) print("added chapters") - contributorsGithub = SupabaseClient().read_all("contributors_registration") - contributorsDiscord = SupabaseClient().read_all("contributors_discord") + contributorsGithub = PostgresClient().read_all("contributors_registration") + contributorsDiscord = PostgresClient().read_all("contributors_discord") ## Give contributor role contributorIds = [ @@ -73,7 +73,7 @@ async def getServerData(self, ctx): print(count) - SupabaseClient().updateContributors(guild.members) + PostgresClient().updateContributors(guild.members) recordedMembers = [ contributor["discord_id"] for contributor in contributorsDiscord ] @@ -81,14 +81,14 @@ async def getServerData(self, ctx): currentMembers = [member.id for member in guild.members] membersWhoLeft = list(set(recordedMembers) - set(currentMembers)) print(f"{len(membersWhoLeft)} members left") - SupabaseClient().deleteContributorDiscord(membersWhoLeft) + PostgresClient().deleteContributorDiscord(membersWhoLeft) print("Updated Contributors") @tasks.loop(minutes=30) async def assign_contributor_role(self): guild = self.bot.get_guild(serverConfig.SERVER) contributorRole = guild.get_role(serverConfig.Roles.CONTRIBUTOR_ROLE) - contributorsGithub = SupabaseClient().read_all("contributors_registration") + contributorsGithub = PostgresClient().read_all("contributors_registration") contributorIds = [ contributor["discord_id"] for contributor in contributorsGithub diff --git a/cogs/userInteractions.py b/cogs/userInteractions.py index 9b11024..a70cee5 100644 --- a/cogs/userInteractions.py +++ b/cogs/userInteractions.py @@ -4,7 +4,7 @@ import discord from discord.ext import commands, tasks -from helpers.supabaseClient import SupabaseClient +from helpers.supabaseClient import PostgresClient VERIFIED_CONTRIBUTOR_ROLE_ID = 1123967402175119482 NON_CONTRIBUTOR_ROLES = [973852321870118914, 976345770477387788, 973852439054782464] @@ -226,7 +226,7 @@ async def list_badges(self, ctx): @tasks.loop(minutes=10) async def update_contributors(self): - contributors = SupabaseClient().read_all("contributors_registration") + contributors = PostgresClient().read_all("contributors_registration") guild = await self.bot.fetch_guild(os.getenv("SERVER_ID")) contributor_role = guild.get_role(VERIFIED_CONTRIBUTOR_ROLE_ID) count = 1 @@ -240,31 +240,31 @@ async def update_contributors(self): await member.add_roles(contributor_role) print(f"Given Roles to {member.name if member else 'None'}") # add to discord engagement - # SupabaseClient("discord_engagement").insert({"contributor": member.id}) + # PostgresClient("discord_engagement").insert({"contributor": member.id}) # update engagement # for contributor in contributors: - # contributorData = SupabaseClient("discord_engagement").read("contributor", contributor["discord_id"])[0] + # contributorData = PostgresClient("discord_engagement").read("contributor", contributor["discord_id"])[0] # member = await guild.fetch_member(contributorData["contributor"]) # print(f"-----Contributor-----{member.name}-------") # badges = Badges(member.name) # if contributorData: # if contributorData["total_message_count"]>10 and not contributorData["converserBadge"]: - # SupabaseClient("discord_engagement").update({"converserBadge":True},"contributor", contributorData["contributor"]) + # PostgresClient("discord_engagement").update({"converserBadge":True},"contributor", contributorData["contributor"]) # dmchannel = member.dm_channel if member.dm_channel else await member.create_dm() # await dmchannel.send(embed=badges.converseBadge) # if contributorData["total_reaction_count"]>5 and not contributorData["rockstarBadge"]: - # SupabaseClient("discord_engagement").update({"rockstarBadge":True},"contributor", contributorData["contributor"]) + # PostgresClient("discord_engagement").update({"rockstarBadge":True},"contributor", contributorData["contributor"]) # dmchannel = member.dm_channel if member.dm_channel else await member.create_dm() # await dmchannel.send(embed=badges.rockstarBadge) # if contributorData["has_introduced"] and not contributorData["apprenticeBadge"]: - # SupabaseClient("discord_engagement").update({"apprenticeBadge":True},"contributor", contributorData["contributor"]) + # PostgresClient("discord_engagement").update({"apprenticeBadge":True},"contributor", contributorData["contributor"]) # dmchannel = member.dm_channel if member.dm_channel else await member.create_dm() # await dmchannel.send(embed=badges.apprenticeBadge) # github_id = contributor["github_id"] # prData = { - # "raised": SupabaseClient(table="pull_requests").read(query_key="raised_by", query_value=github_id), - # "merged":SupabaseClient(table="pull_requests").read(query_key="merged_by", query_value=github_id) + # "raised": PostgresClient(table="pull_requests").read(query_key="raised_by", query_value=github_id), + # "merged":PostgresClient(table="pull_requests").read(query_key="merged_by", query_value=github_id) # } # points = 0 # for action in prData.keys(): @@ -272,10 +272,10 @@ async def update_contributors(self): # for pr in prs: # points+=pr["points"] # if len(prData["raised"])+len(prData["merged"])>0and not contributorData["enthusiastBadge"]: - # SupabaseClient("discord_engagement").update({"enthusiastBadge":True},"contributor", contributorData["contributor"]) + # PostgresClient("discord_engagement").update({"enthusiastBadge":True},"contributor", contributorData["contributor"]) # await dmchannel.send(embed=Badges(member.name, points=points).enthusiastBadge) # if points>=30 and not contributorData["risingStarBadge"]: - # SupabaseClient("discord_engagement").update({"risingStarBadge":True},"contributor", contributorData["contributor"]) + # PostgresClient("discord_engagement").update({"risingStarBadge":True},"contributor", contributorData["contributor"]) # await dmchannel.send(embed=badges.risingStarBadge) return @@ -316,7 +316,7 @@ async def github_profile(self, ctx): **Know more about [badges & points](https://github.com/Code4GovTech/C4GT/wiki/Point-System-for-Contributors)**🧗""" noPointsGithubProfileEmbed = discord.Embed(title="", description=desc) - user = SupabaseClient().read( + user = PostgresClient().read( "github_profile_data", "discord_id", ctx.author.id ) if len(user) == 0: @@ -386,17 +386,17 @@ async def point_breakdown(self, ctx): async def get_points(self, ctx): if isinstance(ctx.channel, discord.DMChannel): discord_id = ctx.author.id - contributor = SupabaseClient().read( + contributor = PostgresClient().read( table="contributors_registration", query_key="discord_id", query_value=discord_id, ) print(contributor) github_id = contributor[0]["github_id"] - prs_raised = SupabaseClient().read( + prs_raised = PostgresClient().read( table="connected_prs", query_key="raised_by", query_value=github_id ) - prs_merged = SupabaseClient().read( + prs_merged = PostgresClient().read( table="connected_prs", query_key="merged_by", query_value=github_id ) raise_points = 0 diff --git a/cogs/vcCog.py b/cogs/vcCog.py index 941e3b7..dc6427e 100644 --- a/cogs/vcCog.py +++ b/cogs/vcCog.py @@ -6,7 +6,7 @@ from discord.ext import commands from config.server import ServerConfig -from helpers.supabaseClient import SupabaseClient +from helpers.supabaseClient import PostgresClient """ with io.BytesIO(image_bytes) as image_file: @@ -29,7 +29,7 @@ def isCommunityContributor(self, roles: list[Role]): return False def getCommunityMember(self, memberId: Member): - data = SupabaseClient().getLeaderboard(memberId) + data = PostgresClient().getLeaderboard(memberId) if data: contributor = data[0] return contributor @@ -59,7 +59,7 @@ def getCertificateLink(self, contributor): def getStatsShowcaseImage(self, discordId=None, type=None): print(f"{discordId}-c4gt-contributions.jpeg") - imageBytes = SupabaseClient().getStatsStorage( + imageBytes = PostgresClient().getStatsStorage( f"{discordId}-c4gt-contributions.jpeg" ) with BytesIO(imageBytes) as imageFile: @@ -72,7 +72,7 @@ def getStatsShowcaseImage(self, discordId=None, type=None): custom_id=f"vc_view_button:my_cert:blurple", ) async def serveCertificateLink(self, interaction: Interaction, button: ui.Button): - SupabaseClient().logVCAction(interaction.user, "My Certificate Button") + PostgresClient().logVCAction(interaction.user, "My Certificate Button") contributor = self.getCommunityMember(interaction.user.id) if contributor["points"] < 10: await interaction.response.send_message( @@ -99,7 +99,7 @@ async def serveCertificateLink(self, interaction: Interaction, button: ui.Button custom_id=f"vc_view:my_profile:blurple", ) async def serveDPGProfile(self, interaction: Interaction, button: ui.Button): - SupabaseClient().logVCAction(interaction.user, "DPG Profile Button") + PostgresClient().logVCAction(interaction.user, "DPG Profile Button") if not self.isCommunityContributor(interaction.user.roles): await interaction.response.send_message( "You're not currently a registered contributor! Head over to <#1211992155673862204> and register as a Verified C4GT Community Contributor :fireworks:", @@ -231,7 +231,7 @@ async def resetSelectMenu(self, interaction): ], ) async def selectAProgram(self, interaction: Interaction, select: ui.Select): - SupabaseClient().logVCAction(interaction.user, "Clicked on Dropdown") + PostgresClient().logVCAction(interaction.user, "Clicked on Dropdown") selected_option = select.values[0] if selected_option == "ccbp": await interaction.response.send_message( diff --git a/helpers/supabaseClient.py b/helpers/supabaseClient.py index 8d16101..a46cf98 100644 --- a/helpers/supabaseClient.py +++ b/helpers/supabaseClient.py @@ -2,9 +2,13 @@ from discord import Member, User from supabase import Client, create_client - from helpers.roleHelpers import lookForChapterRoles, lookForGenderRoles +from dotenv import load_dotenv +from sqlalchemy import create_engine,select,desc,update,delete +from sqlalchemy.orm import sessionmaker +from models import * +load_dotenv() class SupabaseClient: def __init__(self, url=None, key=None) -> None: @@ -149,3 +153,254 @@ def deleteContributorDiscord(self, contributorDiscordIds): table = "contributors_discord" for id in contributorDiscordIds: self.client.table(table).delete().eq("discord_id", id).execute() + +class PostgresClient: + def __init__(self): + DB_HOST = os.getenv('POSTGRES_DB_HOST') + DB_NAME = os.getenv('POSTGRES_DB_NAME') + DB_USER = os.getenv('POSTGRES_DB_USER') + DB_PASS = os.getenv('POSTGRES_DB_PASS') + + engine = create_engine(f'postgresql://{DB_USER}:{DB_PASS}@{DB_HOST}/{DB_NAME}') + Session = sessionmaker(bind=engine) + self.session = Session() + + def convert_dict(self,data): + try: + if type(data) == list: + data = [val.to_dict() for val in data] + else: + return [data.to_dict()] + + return data + except Exception as e: + print(e) + raise Exception + + def getStatsStorage(self, fileName): + return self.client.storage.from_("c4gt-github-profile").download(fileName) + + + def logVCAction(self,user, action): + try: + new_log = VcLogs(discord_id=user.id, discord_name=user.name, option=action) + self.session.add(new_log) + self.session.commit() + return self.convert_dict(new_log) + except Exception as e: + self.session.rollback() + print("Error logging VC action:", e) + return None + + def getLeaderboard(self, id: int): + data = self.session.query(Leaderboard).where(Leaderboard.discord_id == id).all() + return self.convert_dict(data) + + + def read(self, table_class, query_key, query_value, columns=None): + try: + stmt = select(table_class) + stmt = stmt.where(getattr(table_class, query_key) == query_value) + + if columns: + stmt = stmt.with_only_columns(*(getattr(table_class, col) for col in columns)) + result = self.session.execute(stmt) + rows = result.fetchall() + column_names = [col.name for col in stmt.columns] + data = [dict(zip(column_names, row)) for row in rows] + return data + + result = self.session.execute(stmt) + return self.convert_dict(result.scalars().all()) + + except Exception as e: + print(f"Error reading data from table '{table_class}':", e) + return None + + + + def read_by_order_limit(self, table_class, query_key, query_value, order_column, order_by=False, limit=1, columns="*"): + try: + stmt = select(table_class) + stmt = stmt.where(getattr(table_class, query_key) == query_value) + if order_by: + stmt = stmt.order_by(desc(getattr(table_class, order_column))) + else: + stmt = stmt.order_by(getattr(table_class, order_column)) + + stmt = stmt.limit(limit) + if columns != "*": + stmt = stmt.with_only_columns(*(getattr(table_class, col) for col in columns)) + + result = self.session.execute(stmt) + results = result.fetchall() + + # Convert results to list of dictionaries + column_names = [col['name'] for col in result.keys()] + data = [dict(zip(column_names, row)) for row in results] + + return data + + except Exception as e: + print("Error reading data:", e) + return None + + def read_all(self, table): + data = self.session.query(table).all() + return self.convert_dict(data) + + def update(self, table_class, update_data, query_key, query_value): + try: + stmt = ( + update(table_class) + .where(getattr(table_class, query_key) == query_value) + .values(update_data) + .returning(*[getattr(table_class, col) for col in update_data.keys()]) # Return updated columns + ) + + result = self.session.execute(stmt) + self.session.commit() + updated_record = result.fetchone() + + if updated_record: + updated_record_dict = dict(zip(result.keys(), updated_record)) + return updated_record_dict + else: + return None + except Exception as e: + import pdb;pdb.set_trace() + print("Error updating record:", e) + return None + + + def insert(self, table, data): + try: + new_record = table(**data) + self.session.add(new_record) + self.session.commit() + return new_record.to_dict() + except Exception as e: + print("Error inserting data:", e) + self.session.rollback() # Rollback in case of error + return None + + + def memberIsAuthenticated(self, member: Member): + data = self.session.query(ContributorsRegistration).where(ContributorsRegistration.discord_id == member.id).all() + if data: + return True + else: + return False + + def addChapter(self, roleId: int, orgName: str, type: str): + try: + existing_record = self.session.query(Chapters).filter_by(discord_role_id=roleId).first() + + if existing_record: + existing_record.type = type + existing_record.org_name = orgName + else: + new_record = Chapters(discord_role_id=roleId, type=type, org_name=orgName) + self.session.add(new_record) + + self.session.commit() + return existing_record.to_dict() if existing_record else new_record.to_dict() + except Exception as e: + print("Error adding or updating chapter:", e) + return None + + + def deleteChapter(self,roleId: int): + try: + # Build the delete statement + stmt = delete(Chapters).where(Chapters.discord_role_id == roleId) + result = self.session.execute(stmt) + self.session.commit() + return True if result.rowcount else False + except Exception as e: + print("Error deleting chapter:", e) + return None + + def updateContributor(self, contributor: Member, table_class=None): + try: + if table_class == None: + table_class = ContributorsDiscord + chapters = lookForChapterRoles(contributor.roles) + gender = lookForGenderRoles(contributor.roles) + + # Prepare the data to be upserted + update_data = { + "discord_id": contributor.id, + "discord_username": contributor.name, + "chapter": chapters[0] if chapters else None, + "gender": gender, + "joined_at": contributor.joined_at, + } + + existing_record = self.session.query(table_class).filter_by(discord_id=contributor.id).first() + + if existing_record: + stmt = ( + update(table_class) + .where(table_class.discord_id == contributor.id) + .values(update_data) + ) + self.session.execute(stmt) + else: + new_record = table_class(**update_data) + self.session.add(new_record) + + # Commit the transaction + self.session.commit() + return True + except Exception as e: + print("Error updating contributor:", e) + return False + + + def updateContributors(self, contributors: [Member], table_class): + try: + for contributor in contributors: + chapters = lookForChapterRoles(contributor.roles) + gender = lookForGenderRoles(contributor.roles) + update_data = { + "discord_id": contributor.id, + "discord_username": contributor.name, + "chapter": chapters[0] if chapters else None, + "gender": gender, + "joined_at": contributor.joined_at, + } + existing_record = self.session.query(table_class).filter_by(discord_id=contributor.id).first() + + if existing_record: + stmt = ( + update(table_class) + .where(table_class.discord_id == contributor.id) + .values(update_data) + ) + self.session.execute(stmt) + else: + new_record = table_class(**update_data) + self.session.add(new_record) + + self.session.commit() + return True + except Exception as e: + print("Error updating contributors:", e) + return False + + + def deleteContributorDiscord(self, contributorDiscordIds, table_class=None): + try: + if table_class == None: + table_class = ContributorsDiscord + stmt = delete(table_class).where(table_class.discord_id.in_(contributorDiscordIds)) + self.session.execute(stmt) + self.session.commit() + + return True + except Exception as e: + print("Error deleting contributors:", e) + self.session.rollback() + return False + diff --git a/main.py b/main.py index 64ba1aa..2d06b9d 100644 --- a/main.py +++ b/main.py @@ -10,7 +10,7 @@ from discord.ext import commands from cogs.vcCog import VCProgramSelection -from helpers.supabaseClient import SupabaseClient +from helpers.supabaseClient import PostgresClient # Since there are user defined packages, adding current directory to python path current_directory = os.getcwd() @@ -164,13 +164,13 @@ async def on_submit(self, interaction: discord.Interaction): async def hasIntroduced(): print("Checking...") - authentication = SupabaseClient().read( + authentication = PostgresClient().read( "contributors_registration", "discord_id", user.id ) while not authentication: await asyncio.sleep(30) print("Found!") - discordEngagement = SupabaseClient().read( + discordEngagement = PostgresClient().read( "discord_engagement", "contributor", user.id )[0] return discordEngagement["has_introduced"] diff --git a/models.py b/models.py new file mode 100644 index 0000000..9334f22 --- /dev/null +++ b/models.py @@ -0,0 +1,1526 @@ +from datetime import datetime +from sqlalchemy import Column, Integer, String, Text, Float,BigInteger, Boolean, SmallInteger, func, ForeignKey,UniqueConstraint +from sqlalchemy.dialects.postgresql import UUID +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import relationship +from sqlalchemy.types import TypeDecorator, DateTime as SA_DateTime +from datetime import datetime + + +Base = declarative_base() + +class DateTime(TypeDecorator): + impl = SA_DateTime + + def process_bind_param(self, value, dialect): + if isinstance(value, str): + try: + # Convert string to datetime + return datetime.fromisoformat(value) + except ValueError: + # If conversion fails, return None + return None + return value + + def process_result_value(self, value, dialect): + return value + + +class AppComments(Base): + __tablename__ = 'app_comments' + + id = Column(UUID(as_uuid=True), primary_key=True) + updated_at = Column(DateTime, nullable=True) + api_url = Column(Text, nullable=True) + comment_id = Column(BigInteger, nullable=True) + issue_id = Column(BigInteger, unique=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': str(self.id), + 'updated_at': self.updated_at, + 'api_url': self.api_url, + 'comment_id': self.comment_id, + 'issue_id': self.issue_id + } + +class Badges(Base): + __tablename__ = 'badges' + id = Column(UUID(as_uuid=True), primary_key=True) + image = Column(Text, nullable=True) + text = Column(Text, nullable=True) + description = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + user_badges = relationship('UserBadges', back_populates='badge') + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'image': self.image, + 'text': self.text, + 'description': self.description, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + +class CcbpTickets(Base): + __tablename__ = 'ccbp_tickets' + __table_args__ = {'comment': 'A table to store details of CCBP Tickets from various projects'} + + created_at = Column(DateTime, nullable=True) + name = Column(Text, nullable=True) + product = Column(Text, nullable=True) + complexity = Column(Text, nullable=True) + project_category = Column(Text, nullable=True) + project_sub_category = Column(Text, nullable=True) + reqd_skills = Column(Text, nullable=True) + issue_id = Column(BigInteger, unique=True) + api_endpoint_url = Column(Text, unique=True, nullable=True) + url = Column(Text, unique=True, nullable=True) + ticket_points = Column(SmallInteger, nullable=True, comment='How many points the ticket is worth') + index = Column(SmallInteger, unique=True, autoincrement=True) + mentors = Column(Text, nullable=True) + uuid = Column(UUID(as_uuid=True), primary_key=True) + status = Column(Text, nullable=True) + community_label = Column(Boolean, nullable=True, comment='has community label') + organization = Column(Text, nullable=True) + closed_at = Column(DateTime, nullable=True, comment='date-time at which issue was closed') + assignees = Column(Text, nullable=True) + issue_author = Column(Text, nullable=True) + is_assigned = Column(Boolean, nullable=False) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'created_at': self.created_at, + 'name': self.name, + 'product': self.product, + 'complexity': self.complexity, + 'project_category': self.project_category, + 'project_sub_category': self.project_sub_category, + 'reqd_skills': self.reqd_skills, + 'issue_id': self.issue_id, + 'api_endpoint_url': self.api_endpoint_url, + 'url': self.url, + 'ticket_points': self.ticket_points, + 'index': self.index, + 'mentors': self.mentors, + 'uuid': str(self.uuid), + 'status': self.status, + 'community_label': self.community_label, + 'organization': self.organization, + 'closed_at': self.closed_at, + 'assignees': self.assignees, + 'issue_author': self.issue_author, + 'is_assigned': self.is_assigned + } + +class Chapters(Base): + __tablename__ = 'chapters' + + id = Column(UUID(as_uuid=True), primary_key=True) + type = Column(Text, nullable=True) + org_name = Column(Text, unique=True) + primary_organisation = Column(Text, nullable=True, comment='the organisation that the chapter is mapped to') + sessions = Column(Integer, nullable=True) + discord_role_id = Column(BigInteger, unique=True, comment='db id of the corresponding member role in discord server') + created_at = Column(DateTime, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'type': self.type, + 'org_name': self.org_name, + 'primary_organisation': self.primary_organisation, + 'sessions': self.sessions, + 'discord_role_id': self.discord_role_id, + 'created_at': self.created_at + } + + +## + +class ConnectedPrs(Base): + __tablename__ = 'connected_prs' + + id = Column(UUID(as_uuid=True), primary_key=True) + created_at = Column(DateTime, nullable=True) + api_url = Column(Text, nullable=True) + html_url = Column(Text, unique=True, nullable=True) + raised_by = Column(BigInteger, nullable=True) + raised_at = Column(DateTime, nullable=False) + raised_by_username = Column(Text, nullable=False) + status = Column(Text, nullable=True) + is_merged = Column(Boolean, nullable=True) + merged_by = Column(BigInteger, nullable=True) + merged_at = Column(Text, nullable=True) + merged_by_username = Column(Text, nullable=True) + pr_id = Column(BigInteger, nullable=False, comment='github id of the pr') + points = Column(SmallInteger, nullable=False) + ticket_url = Column(Text, nullable=False) + ticket_complexity = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'api_url': self.api_url, + 'html_url': self.html_url, + 'raised_by': self.raised_by, + 'raised_at': self.raised_at, + 'raised_by_username': self.raised_by_username, + 'status': self.status, + 'is_merged': self.is_merged, + 'merged_by': self.merged_by, + 'merged_at': self.merged_at, + 'merged_by_username': self.merged_by_username, + 'pr_id': self.pr_id, + 'points': self.points, + 'ticket_url': self.ticket_url, + 'ticket_complexity': self.ticket_complexity + } + +class ContributorNames(Base): + __tablename__ = 'contributor_names' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + discord_id = Column(BigInteger, nullable=False) + name = Column(Text, nullable=True) + country = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'discord_id': self.discord_id, + 'name': self.name, + 'country': self.country + } + +class ContributorsDiscord(Base): + __tablename__ = 'contributors_discord' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + discord_id = Column(BigInteger, unique=True, nullable=False) + github_id = Column(BigInteger, nullable=True) + github_url = Column(String, nullable=True) + discord_username = Column(String, nullable=True) + joined_at = Column(DateTime, nullable=False) + email = Column(Text, nullable=True) + field_name = Column(Text, nullable=True, name='name') # Adjusted field name + chapter = Column(Text, nullable=True, comment="the chapter they're associated with") + gender = Column(Text, nullable=True) + is_active = Column(Boolean, nullable=False) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'discord_id': self.discord_id, + 'github_id': self.github_id, + 'github_url': self.github_url, + 'discord_username': self.discord_username, + 'joined_at': self.joined_at, + 'email': self.email, + 'name': self.field_name, + 'chapter': self.chapter, + 'gender': self.gender, + 'is_active': self.is_active + } + +class ContributorsRegistration(Base): + __tablename__ = 'contributors_registration' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + discord_id = Column(BigInteger, unique=True, nullable=False) + github_id = Column(BigInteger, unique=True, nullable=False) + github_url = Column(String, nullable=False) + discord_username = Column(String, nullable=True) + joined_at = Column(DateTime, nullable=False) + email = Column(Text, nullable=True) + name = Column(Text, nullable=True) + + point_transactions = relationship('PointTransactions', back_populates='contributor') + + user_activities = relationship('UserActivity', back_populates='contributor') + user_points_mappings = relationship('UserPointsMapping', back_populates='contributor') + + + def __repr__(self): + return f"" + + + def to_dict(self): + return { + 'id': self.id, + 'discord_id': self.discord_id, + 'github_id': self.github_id, + 'github_url': self.github_url, + 'discord_username': self.discord_username, + 'joined_at': self.joined_at, + 'email': self.email, + 'name': self.name + } + +class DiscordChannels(Base): + __tablename__ = 'discord_channels' + + channel_id = Column(BigInteger, primary_key=True) + channel_name = Column(Text, nullable=True) + webhook = Column(Text, nullable=True) + should_notify = Column(Boolean, nullable=False) + + products = relationship('Product', back_populates='channel') + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'channel_id': self.channel_id, + 'channel_name': self.channel_name, + 'webhook': self.webhook, + 'should_notify': self.should_notify + } + +class DiscordEngagement(Base): + __tablename__ = 'discord_engagement' + __table_args__ = {'comment': 'engagement metrics for contributors'} + + id = Column(BigInteger, primary_key=True, autoincrement=True) + created_at = Column(DateTime, nullable=True) + contributor = Column(BigInteger, unique=True, nullable=False) + has_introduced = Column(Boolean, nullable=True) + total_message_count = Column(BigInteger, nullable=True) + total_reaction_count = Column(BigInteger, nullable=True) + converserbadge = Column(Boolean, nullable=True) + apprenticebadge = Column(Boolean, nullable=True) + rockstarbadge = Column(Boolean, nullable=True) + enthusiastbadge = Column(Boolean, nullable=True) + risingstarbadge = Column(Boolean, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'contributor': self.contributor, + 'has_introduced': self.has_introduced, + 'total_message_count': self.total_message_count, + 'total_reaction_count': self.total_reaction_count, + 'converserbadge': self.converserbadge, + 'apprenticebadge': self.apprenticebadge, + 'rockstarbadge': self.rockstarbadge, + 'enthusiastbadge': self.enthusiastbadge, + 'risingstarbadge': self.risingstarbadge + } + +class DmpIssueUpdates(Base): + __tablename__ = 'dmp_issue_updates' + __table_args__ = {'comment': 'Having records of dmp with issue details'} + + created_at = Column(DateTime, nullable=False) + body_text = Column(Text, nullable=True) + comment_link = Column(Text, nullable=True) + comment_id = Column(BigInteger, primary_key=True) + comment_api = Column(String, nullable=True) + comment_updated_at = Column(DateTime, nullable=True) + dmp_id = Column(BigInteger, ForeignKey('dmp_issues.id'), nullable=False) + created_by = Column(Text, nullable=False) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'created_at': self.created_at, + 'body_text': self.body_text, + 'comment_link': self.comment_link, + 'comment_id': self.comment_id, + 'comment_api': self.comment_api, + 'comment_updated_at': self.comment_updated_at, + 'dmp_id': self.dmp_id, + 'created_by': self.created_by + } + + +class DmpIssues(Base): + __tablename__ = 'dmp_issues' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + issue_url = Column(String, nullable=False) + issue_number = Column(BigInteger, nullable=False) + mentor_username = Column(Text, nullable=True) + contributor_username = Column(Text, nullable=True) + title = Column(Text, nullable=False) + org_id = Column(BigInteger, ForeignKey('dmp_orgs.id'), nullable=False) + description = Column(Text, nullable=False) + repo = Column(Text, nullable=False) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'issue_url': self.issue_url, + 'issue_number': self.issue_number, + 'mentor_username': self.mentor_username, + 'contributor_username': self.contributor_username, + 'title': self.title, + 'org_id': self.org_id, + 'description': self.description, + 'repo': self.repo + } + +class DmpOrgs(Base): + __tablename__ = 'dmp_orgs' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + created_at = Column(DateTime, nullable=False) + name = Column(Text, nullable=False) + description = Column(Text, nullable=False) + link = Column(Text, nullable=False) + repo_owner = Column(Text, nullable=False) + + issues = relationship('Issues', backref='organization', lazy='joined') + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'name': self.name, + 'description': self.description, + 'link': self.link, + 'repo_owner': self.repo_owner + } + +class DmpPrUpdates(Base): + __tablename__ = 'dmp_pr_updates' + __table_args__ = {'comment': 'Having PR related records'} + + created_at = Column(DateTime, nullable=False) + pr_id = Column(BigInteger, primary_key=True) + status = Column(String, nullable=False) + title = Column(Text, nullable=False) + pr_updated_at = Column(DateTime, nullable=True) + merged_at = Column(DateTime, nullable=True) + closed_at = Column(DateTime, nullable=True) + dmp_id = Column(BigInteger, ForeignKey('dmp_issues.id'), nullable=False) + link = Column(Text, nullable=False) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'created_at': self.created_at, + 'pr_id': self.pr_id, + 'status': self.status, + 'title': self.title, + 'pr_updated_at': self.pr_updated_at, + 'merged_at': self.merged_at, + 'closed_at': self.closed_at, + 'dmp_id': self.dmp_id, + 'link': self.link + } + +class DmpTickets(Base): + __tablename__ = 'dmp_tickets' + + created_at = Column(DateTime, nullable=True) + name = Column(Text, nullable=True) + product = Column(Text, nullable=True) + complexity = Column(Text, nullable=True) + project_category = Column(Text, nullable=True) + project_sub_category = Column(Text, nullable=True) + reqd_skills = Column(Text, nullable=True) + issue_id = Column(BigInteger, unique=True, nullable=False) + api_endpoint_url = Column(Text, unique=True, nullable=True) + url = Column(Text, unique=True, nullable=True) + ticket_points = Column(Integer, nullable=True, comment='How many points the ticket is worth') + index = Column(Integer, unique=True, autoincrement=True) + mentors = Column(Text, nullable=True) + uuid = Column(UUID(as_uuid=True), primary_key=True) + status = Column(Text, nullable=True) + community_label = Column(Boolean, nullable=True, comment='has community label') + organization = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'created_at': self.created_at, + 'name': self.name, + 'product': self.product, + 'complexity': self.complexity, + 'project_category': self.project_category, + 'project_sub_category': self.project_sub_category, + 'reqd_skills': self.reqd_skills, + 'issue_id': self.issue_id, + 'api_endpoint_url': self.api_endpoint_url, + 'url': self.url, + 'ticket_points': self.ticket_points, + 'index': self.index, + 'mentors': self.mentors, + 'uuid': self.uuid, + 'status': self.status, + 'community_label': self.community_label, + 'organization': self.organization + } + +class DmpWeekUpdates(Base): + __tablename__ = 'dmp_week_updates' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + issue_url = Column(Text, nullable=False) + week = Column(BigInteger, nullable=True) + total_task = Column(BigInteger, nullable=True) + completed_task = Column(BigInteger, nullable=True) + progress = Column(Float, nullable=True) + task_data = Column(Text, nullable=True) + dmp_id = Column(BigInteger, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'issue_url': self.issue_url, + 'week': self.week, + 'total_task': self.total_task, + 'completed_task': self.completed_task, + 'progress': self.progress, + 'task_data': self.task_data, + 'dmp_id': self.dmp_id + } + +class GithubClassroomData(Base): + __tablename__ = 'github_classroom_data' + __table_args__ = {'comment': 'Table for saving the details about github classroom assignment data'} + + id = Column(BigInteger, primary_key=True, autoincrement=True) + created_at = Column(DateTime, nullable=False) + assignment_name = Column(Text, nullable=False) + assignment_url = Column(Text, nullable=False) + assignment_id = Column(Text, nullable=True) + starter_code_url = Column(Text, nullable=False) + github_username = Column(Text, nullable=True) + roster_identifier = Column(Text, nullable=True) + student_repository_name = Column(Text, nullable=True) + student_repository_url = Column(Text, nullable=True) + submission_timestamp = Column(DateTime, nullable=False) + points_awarded = Column(Integer, nullable=True) + points_available = Column(Integer, nullable=True) + c4gt_points = Column(Integer, nullable=True) + discord_id = Column(Text, nullable=True) + updated_at = Column(DateTime, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'assignment_name': self.assignment_name, + 'assignment_url': self.assignment_url, + 'assignment_id': self.assignment_id, + 'starter_code_url': self.starter_code_url, + 'github_username': self.github_username, + 'roster_identifier': self.roster_identifier, + 'student_repository_name': self.student_repository_name, + 'student_repository_url': self.student_repository_url, + 'submission_timestamp': self.submission_timestamp, + 'points_awarded': self.points_awarded, + 'points_available': self.points_available, + 'c4gt_points': self.c4gt_points, + 'discord_id': self.discord_id, + 'updated_at': self.updated_at + } + +class GithubInstallations(Base): + __tablename__ = 'github_installations' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + github_organisation = Column(Text, unique=True, nullable=False) + installation_id = Column(BigInteger, unique=True, nullable=False) + target_type = Column(Text, nullable=True, comment='Type of github entity that installed the app, usually "Organisation"') + github_ids = Column(Text, nullable=True, comment="Identifiers on the github database, prolly won't be used") + permissions_and_events = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + organisation = Column(Text, ForeignKey('community_organisations.name'), nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'github_organisation': self.github_organisation, + 'installation_id': self.installation_id, + 'target_type': self.target_type, + 'github_ids': self.github_ids, + 'permissions_and_events': self.permissions_and_events, + 'created_at': self.created_at, + 'organisation': self.organisation + } +## + +class GithubOrganisationsToOrganisations(Base): + __tablename__ = 'github_organisations_to_organisations' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + github_organisation = Column(Text, nullable=False) + organisation = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True, comment='Creation date of organization ticket') + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'github_organisation': self.github_organisation, + 'organisation': self.organisation, + 'created_at': self.created_at + } + +class IssueContributors(Base): + __tablename__ = 'issue_contributors' + + contributor_id = Column(BigInteger, ForeignKey('contributors_registration.id'), primary_key=True) + issue_id = Column(BigInteger, ForeignKey('issues.id'), primary_key=True) + role_id = Column(BigInteger, ForeignKey('role_master.id'), nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'contributor_id': self.contributor_id, + 'issue_id': self.issue_id, + 'role_id': self.role_id, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + +class IssueMentors(Base): + __tablename__ = 'issue_mentors' + + issue_id = Column(BigInteger, ForeignKey('issues.id'), primary_key=True) + mentor_id = Column(BigInteger, ForeignKey('mentor_details.id'), primary_key=True) + createdat = Column(DateTime, nullable=True) + updatedat = Column(DateTime, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'issue_id': self.issue_id, + 'mentor_id': self.mentor_id, + 'createdat': self.createdat, + 'updatedat': self.updatedat + } + +class Issues(Base): + __tablename__ = 'issues' + + id = Column(BigInteger, primary_key=True) + link = Column(Text, nullable=False) + labels = Column(Text, nullable=True) + complexity = Column(Text, nullable=True) + skills = Column(Text, nullable=True) + technology = Column(Text, nullable=True) + status = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + title = Column(Text, nullable=True) + description = Column(Text, nullable=True) + org_id = Column(BigInteger, ForeignKey('dmp_orgs.id'), nullable=True) + issue_id = Column(BigInteger, nullable=True) + + point_transactions = relationship('PointTransactions', back_populates='issue') + user_activities = relationship('UserActivity', back_populates='issue') + + + + def __repr__(self): + return f"" + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'link': self.link, + 'labels': self.labels, + 'complexity': self.complexity, + 'skills': self.skills, + 'technology': self.technology, + 'status': self.status, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'title': self.title, + 'description': self.description, + 'org_id': self.org_id, + 'issue_id': self.issue_id + } + +class MentorDetails(Base): + __tablename__ = 'mentor_details' + + id = Column(BigInteger, primary_key=True) + name = Column(String(255), nullable=True) + email = Column(String(255), nullable=True) + discord_id = Column(String(255), nullable=True) + discord_username = Column(String(255), nullable=True) + github_id = Column(String(255), nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + point_transactions = relationship('PointTransactions', back_populates='mentor') + user_activities = relationship('UserActivity', back_populates='mentor') + user_points_mappings = relationship('UserPointsMapping', back_populates='mentor') + + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'name': self.name, + 'email': self.email, + 'discord_id': self.discord_id, + 'discord_username': self.discord_username, + 'github_id': self.github_id, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + +class MentorshipProgramSiteStructure(Base): + __tablename__ = 'mentorship_program_site_structure' + + id = Column(BigInteger, primary_key=True) + product_id = Column(BigInteger, ForeignKey('product.id'), nullable=True) + project_id = Column(BigInteger, ForeignKey('mentorship_program_projects.id'), nullable=True) + contributor_id = Column(BigInteger, ForeignKey('mentorship_program_selected_contributors.id'), nullable=True) + website_directory_label = Column(Text, nullable=True) + directory_url = Column(Text, nullable=True) + + # project = relationship('MentorshipProgramProjects', back_populates='site_structures') + # contributor = relationship('MentorshipProgramSelectedContributors', back_populates='site_structures') + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'product_id': self.product_id, + 'project_id': self.project_id, + 'contributor_id': self.contributor_id, + 'website_directory_label': self.website_directory_label, + 'directory_url': self.directory_url + } + +class MentorshipProgramWebsiteComments(Base): + __tablename__ = 'mentorship_program_website_comments' + + comment_id = Column(BigInteger, primary_key=True) + url = Column(Text, nullable=True) + html_url = Column(Text, nullable=True) + commented_by_username = Column(Text, nullable=True) + commented_by_id = Column(BigInteger, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + body = Column(Text, nullable=True) + pr_id = Column(BigInteger, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'comment_id': self.comment_id, + 'url': self.url, + 'html_url': self.html_url, + 'commented_by_username': self.commented_by_username, + 'commented_by_id': self.commented_by_id, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'body': self.body, + 'pr_id': self.pr_id + } + +class MentorshipProgramWebsiteCommits(Base): + __tablename__ = 'mentorship_program_website_commits' + + node_id = Column(Text, primary_key=True) + url = Column(Text, nullable=True) + html_url = Column(Text, nullable=True) + comment_count = Column(Integer, nullable=True) + date = Column(DateTime, nullable=True) + author_id = Column(BigInteger, nullable=True) + author_username = Column(Text, nullable=True) + author_email = Column(Text, nullable=True) + committer_id = Column(BigInteger, nullable=True) + committer_username = Column(Text, nullable=True) + committer_email = Column(Text, nullable=True) + additions = Column(Integer, nullable=True) + deletions = Column(Integer, nullable=True) + files = Column(Text, nullable=True) + project_folder_name = Column(Text, nullable=True) + pr_id = Column(BigInteger, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'node_id': self.node_id, + 'url': self.url, + 'html_url': self.html_url, + 'comment_count': self.comment_count, + 'date': self.date, + 'author_id': self.author_id, + 'author_username': self.author_username, + 'author_email': self.author_email, + 'committer_id': self.committer_id, + 'committer_username': self.committer_username, + 'committer_email': self.committer_email, + 'additions': self.additions, + 'deletions': self.deletions, + 'files': self.files, + 'project_folder_name': self.project_folder_name, + 'pr_id': self.pr_id + } + +class MentorshipProgramWebsiteHasUpdated(Base): + __tablename__ = 'mentorship_program_website_has_updated' + + id = Column(BigInteger, primary_key=True) + project_id = Column(BigInteger, ForeignKey('mentorship_program_projects.id'), nullable=True) + week1_update_date = Column(DateTime, nullable=True) + week2_update_date = Column(DateTime, nullable=True) + week3_update_date = Column(DateTime, nullable=True) + week4_update_date = Column(DateTime, nullable=True) + week5_update_date = Column(DateTime, nullable=True) + week6_update_date = Column(DateTime, nullable=True) + week7_update_date = Column(DateTime, nullable=True) + week8_update_date = Column(DateTime, nullable=True) + week9_update_date = Column(DateTime, nullable=True) + week1_is_default_text = Column(Boolean, nullable=True) + week2_is_default_text = Column(Boolean, nullable=True) + week3_is_default_text = Column(Boolean, nullable=True) + week4_is_default_text = Column(Boolean, nullable=True) + week5_is_default_text = Column(Boolean, nullable=True) + week6_is_default_text = Column(Boolean, nullable=True) + week7_is_default_text = Column(Boolean, nullable=True) + week8_is_default_text = Column(Boolean, nullable=True) + week9_is_default_text = Column(Boolean, nullable=True) + product = Column(Text, nullable=True) + project_folder = Column(Text, unique=True, nullable=False) + all_links = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'project_id': self.project_id, + 'week1_update_date': self.week1_update_date, + 'week2_update_date': self.week2_update_date, + 'week3_update_date': self.week3_update_date, + 'week4_update_date': self.week4_update_date, + 'week5_update_date': self.week5_update_date, + 'week6_update_date': self.week6_update_date, + 'week7_update_date': self.week7_update_date, + 'week8_update_date': self.week8_update_date, + 'week9_update_date': self.week9_update_date, + 'week1_is_default_text': self.week1_is_default_text, + 'week2_is_default_text': self.week2_is_default_text, + 'week3_is_default_text': self.week3_is_default_text, + 'week4_is_default_text': self.week4_is_default_text, + 'week5_is_default_text': self.week5_is_default_text, + 'week6_is_default_text': self.week6_is_default_text, + 'week7_is_default_text': self.week7_is_default_text, + 'week8_is_default_text': self.week8_is_default_text, + 'week9_is_default_text': self.week9_is_default_text, + 'product': self.product, + 'project_folder': self.project_folder, + 'all_links': self.all_links + } + + + +## + +class MentorshipProgramWebsitePullRequest(Base): + __tablename__ = 'mentorship_program_website_pull_request' + + pr_url = Column(Text, nullable=True) + pr_id = Column(BigInteger, primary_key=True) + pr_node_id = Column(Text, unique=True, nullable=True) + html_url = Column(Text, nullable=True) + status = Column(Text, nullable=True) + title = Column(Text, nullable=True) + raised_by_username = Column(Text, nullable=True) + raised_by_id = Column(Integer, nullable=True) + body = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + closed_at = Column(DateTime, nullable=True) + merged_at = Column(DateTime, nullable=True) + assignees = Column(Text, nullable=True) + requested_reviewers = Column(Text, nullable=True) + labels = Column(Text, nullable=True) + review_comments_url = Column(Text, nullable=True) + comments_url = Column(Text, nullable=True) + repository_id = Column(Integer, nullable=True) + repository_owner_name = Column(Text, nullable=True) + repository_owner_id = Column(Integer, nullable=True) + repository_url = Column(Text, nullable=True) + merged = Column(Boolean, nullable=True) + number_of_commits = Column(Integer, nullable=True) + number_of_comments = Column(Integer, nullable=True) + lines_of_code_added = Column(Integer, nullable=True) + lines_of_code_removed = Column(Integer, nullable=True) + number_of_files_changed = Column(Integer, nullable=True) + merged_by_id = Column(BigInteger, nullable=True) + merged_by_username = Column(Text, nullable=True) + linked_ticket = Column(Text, nullable=True) + project_name = Column(Text, nullable=True) + project_folder_label = Column(Text, nullable=True) + week_number = Column(SmallInteger, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'pr_url': self.pr_url, + 'pr_id': self.pr_id, + 'pr_node_id': self.pr_node_id, + 'html_url': self.html_url, + 'status': self.status, + 'title': self.title, + 'raised_by_username': self.raised_by_username, + 'raised_by_id': self.raised_by_id, + 'body': self.body, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'closed_at': self.closed_at, + 'merged_at': self.merged_at, + 'assignees': self.assignees, + 'requested_reviewers': self.requested_reviewers, + 'labels': self.labels, + 'review_comments_url': self.review_comments_url, + 'comments_url': self.comments_url, + 'repository_id': self.repository_id, + 'repository_owner_name': self.repository_owner_name, + 'repository_owner_id': self.repository_owner_id, + 'repository_url': self.repository_url, + 'merged': self.merged, + 'number_of_commits': self.number_of_commits, + 'number_of_comments': self.number_of_comments, + 'lines_of_code_added': self.lines_of_code_added, + 'lines_of_code_removed': self.lines_of_code_removed, + 'number_of_files_changed': self.number_of_files_changed, + 'merged_by_id': self.merged_by_id, + 'merged_by_username': self.merged_by_username, + 'linked_ticket': self.linked_ticket, + 'project_name': self.project_name, + 'project_folder_label': self.project_folder_label, + 'week_number': self.week_number + } + +class MentorshipWebsiteContributorProject(Base): + __tablename__ = 'mentorship_website_contributor_project' + + project_folder = Column(Text, primary_key=True) + contributor = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'project_folder': self.project_folder, + 'contributor': self.contributor + } + +class PointSystem(Base): + __tablename__ = 'point_system' + + id = Column(BigInteger, primary_key=True) + complexity = Column(Text, nullable=False) + points = Column(SmallInteger, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'complexity': self.complexity, + 'points': self.points + } + +class PointTransactions(Base): + __tablename__ = 'point_transactions' + + id = Column(BigInteger, primary_key=True) + user_id = Column(BigInteger, ForeignKey('contributors_registration.id'), nullable=True) + issue_id = Column(BigInteger, ForeignKey('issues.id'), nullable=False) + point = Column(Integer, nullable=True) + type = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + mentor_id = Column(BigInteger, ForeignKey('mentor_details.id'), nullable=True) + + + contributor = relationship('ContributorsRegistration', back_populates='point_transactions') + issue = relationship('Issues', back_populates='point_transactions') + mentor = relationship('MentorDetails', back_populates='point_transactions') + + def __repr__(self): + return f"" + + + def to_dict(self): + return { + 'id': self.id, + 'user_id': self.user_id, + 'issue_id': self.issue_id, + 'point': self.point, + 'type': self.type, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'mentor_id': self.mentor_id + } + +class PointsMapping(Base): + __tablename__ = 'points_mapping' + + id = Column(BigInteger, primary_key=True) + role = Column(String(50), nullable=False) + complexity = Column(String(50), nullable=False) + points = Column(Integer, nullable=False) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'role': self.role, + 'complexity': self.complexity, + 'points': self.points, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + + + +### + +class PrHistory(Base): + __tablename__ = 'pr_history' + + id = Column(String(36), primary_key=True) # UUID field + created_at = Column(DateTime, nullable=True) + api_url = Column(Text, nullable=True) + html_url = Column(Text, unique=True, nullable=True) + raised_by = Column(BigInteger, nullable=True) + raised_at = Column(DateTime, nullable=False) + raised_by_username = Column(Text, nullable=False) + status = Column(Text, nullable=True) + is_merged = Column(Boolean, nullable=True) + merged_by = Column(BigInteger, nullable=True) + merged_at = Column(Text, nullable=True) + merged_by_username = Column(Text, nullable=True) + pr_id = Column(BigInteger, nullable=False) + points = Column(SmallInteger, nullable=False) + ticket_url = Column(Text, nullable=False) + ticket_complexity = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'api_url': self.api_url, + 'html_url': self.html_url, + 'raised_by': self.raised_by, + 'raised_at': self.raised_at, + 'raised_by_username': self.raised_by_username, + 'status': self.status, + 'is_merged': self.is_merged, + 'merged_by': self.merged_by, + 'merged_at': self.merged_at, + 'merged_by_username': self.merged_by_username, + 'pr_id': self.pr_id, + 'points': self.points, + 'ticket_url': self.ticket_url, + 'ticket_complexity': self.ticket_complexity + } + +class PrStaging(Base): + __tablename__ = 'pr_staging' + + id = Column(String(36), primary_key=True) # UUID field + created_at = Column(DateTime, nullable=True) + api_url = Column(Text, nullable=True) + html_url = Column(Text, unique=True, nullable=True) + raised_by = Column(BigInteger, nullable=True) + raised_at = Column(DateTime, nullable=False) + raised_by_username = Column(Text, nullable=False) + status = Column(Text, nullable=True) + is_merged = Column(Boolean, nullable=True) + merged_by = Column(BigInteger, nullable=True) + merged_at = Column(Text, nullable=True) + merged_by_username = Column(Text, nullable=True) + pr_id = Column(BigInteger, nullable=False) + points = Column(SmallInteger, nullable=False) + ticket_url = Column(Text, nullable=False) + ticket_complexity = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'api_url': self.api_url, + 'html_url': self.html_url, + 'raised_by': self.raised_by, + 'raised_at': self.raised_at, + 'raised_by_username': self.raised_by_username, + 'status': self.status, + 'is_merged': self.is_merged, + 'merged_by': self.merged_by, + 'merged_at': self.merged_at, + 'merged_by_username': self.merged_by_username, + 'pr_id': self.pr_id, + 'points': self.points, + 'ticket_url': self.ticket_url, + 'ticket_complexity': self.ticket_complexity + } + +class Product(Base): + __tablename__ = 'product' + + id = Column(BigInteger, primary_key=True) # Auto field + name = Column(Text, unique=True, nullable=False) + description = Column(Text, nullable=True) + wiki_url = Column(Text, nullable=True) + channel_id = Column(BigInteger, ForeignKey('discord_channels.channel_id'), nullable=True) # Assumes 'DiscordChannels' model + + channel = relationship('DiscordChannels', back_populates='products') + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'name': self.name, + 'description': self.description, + 'wiki_url': self.wiki_url, + 'channel_id': self.channel_id + } + +class RoleMaster(Base): + __tablename__ = 'role_master' + + id = Column(BigInteger, primary_key=True) # Auto field + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=True) + role = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'role': self.role + } + +class TicketComments(Base): + __tablename__ = 'ticket_comments' + + id = Column(BigInteger, primary_key=True) + url = Column(Text, nullable=True) + html_url = Column(Text, nullable=True) + issue_url = Column(Text, nullable=True) + node_id = Column(Text, nullable=True) + commented_by = Column(Text, nullable=True) + commented_by_id = Column(BigInteger, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + content = Column(Text, nullable=True) + reactions_url = Column(Text, nullable=True) + ticket_url = Column(Text, nullable=False) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'url': self.url, + 'html_url': self.html_url, + 'issue_url': self.issue_url, + 'node_id': self.node_id, + 'commented_by': self.commented_by, + 'commented_by_id': self.commented_by_id, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'content': self.content, + 'reactions_url': self.reactions_url, + 'ticket_url': self.ticket_url + } + +class UnlistedTickets(Base): + __tablename__ = 'unlisted_tickets' + + created_at = Column(DateTime, nullable=True) + name = Column(Text, nullable=True) + product = Column(Text, nullable=True) + complexity = Column(Text, nullable=True) + project_category = Column(Text, nullable=True) + project_sub_category = Column(Text, nullable=True) + reqd_skills = Column(Text, nullable=True) + issue_id = Column(BigInteger, unique=True, nullable=False) + api_endpoint_url = Column(Text, unique=True, nullable=True) + url = Column(Text, unique=True, nullable=True) + ticket_points = Column(SmallInteger, nullable=True) + index = Column(SmallInteger, unique=True, nullable=False) + mentors = Column(Text, nullable=True) + uuid = Column(String(36), primary_key=True) # UUID field + status = Column(Text, nullable=True) + organization = Column(Text, nullable=True) + + __table_args__ = (UniqueConstraint('uuid', 'issue_id'),) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'created_at': self.created_at, + 'name': self.name, + 'product': self.product, + 'complexity': self.complexity, + 'project_category': self.project_category, + 'project_sub_category': self.project_sub_category, + 'reqd_skills': self.reqd_skills, + 'issue_id': self.issue_id, + 'api_endpoint_url': self.api_endpoint_url, + 'url': self.url, + 'ticket_points': self.ticket_points, + 'index': self.index, + 'mentors': self.mentors, + 'uuid': self.uuid, + 'status': self.status, + 'organization': self.organization + } + +class UnstructuredDiscordData(Base): + __tablename__ = 'unstructured_discord_data' + + text = Column(Text, nullable=True) + author = Column(BigInteger, nullable=True) + channel = Column(BigInteger, nullable=True) + channel_name = Column(Text, nullable=True) + uuid = Column(String(36), primary_key=True) # UUID field + author_name = Column(Text, nullable=True) + author_roles = Column(Text, nullable=True) + sent_at = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'text': self.text, + 'author': self.author, + 'channel': self.channel, + 'channel_name': self.channel_name, + 'uuid': self.uuid, + 'author_name': self.author_name, + 'author_roles': self.author_roles, + 'sent_at': self.sent_at + } + +class UserActivity(Base): + __tablename__ = 'user_activity' + + id = Column(UUID(as_uuid=True), primary_key=True) + contributor_id = Column(BigInteger, ForeignKey('contributors_registration.id'), nullable=False) # Assumes 'ContributorsRegistration' model + issue_id = Column(BigInteger, ForeignKey('issues.id'), nullable=False) # Assumes 'Issues' model + activity = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + mentor_id = Column(BigInteger, ForeignKey('mentor_details.id'), nullable=True) # Assumes 'MentorDetails' model + + contributor = relationship('ContributorsRegistration', back_populates='user_activities') + issue = relationship('Issues', back_populates='user_activities') + mentor = relationship('MentorDetails', back_populates='user_activities') + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'contributor_id': self.contributor_id, + 'issue_id': self.issue_id, + 'activity': self.activity, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'mentor_id': self.mentor_id + } + +class UserBadges(Base): + __tablename__ = 'user_badges' + id = Column(UUID(as_uuid=True), primary_key=True) + user_id = Column(BigInteger, ForeignKey('users.id'), nullable=False) # Assumes 'Users' model + badge_id = Column(BigInteger, ForeignKey('badges.id'), nullable=False) # Assumes 'Badges' model + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + user = relationship('Users', back_populates='user_badges') + badge = relationship('Badges', back_populates='user_badges') + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'user_id': self.user_id, + 'badge_id': self.badge_id, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + +class UserCertificates(Base): + __tablename__ = 'user_certificates' + id = Column(UUID(as_uuid=True), primary_key=True) + user_id = Column(BigInteger, ForeignKey('users.id'), nullable=False) # Assumes 'Users' model + certificate_link = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + user = relationship('Users', back_populates='user_certificates') + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'user_id': self.user_id, + 'certificate_link': self.certificate_link, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + + + +### + +class UserPointsMapping(Base): + __tablename__ = 'user_points_mapping' + id = Column(UUID(as_uuid=True), primary_key=True) + contributor_id = Column(BigInteger, ForeignKey('contributors_registration.id'), nullable=True) # Assumes 'ContributorsRegistration' model + points = Column(Integer, nullable=False) + level = Column(String(50), nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + mentor_id = Column(BigInteger, ForeignKey('mentor_details.id'), nullable=True) # Assumes 'MentorDetails' model + + contributor = relationship('ContributorsRegistration', back_populates='user_points_mappings') + mentor = relationship('MentorDetails', back_populates='user_points_mappings') + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'contributor_id': self.contributor_id, + 'points': self.points, + 'level': self.level, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'mentor_id': self.mentor_id + } + +class Users(Base): + __tablename__ = 'users' + + id = Column(BigInteger, primary_key=True) # Assumes id is the primary key + name = Column(Text, nullable=True) + discord = Column(Text, unique=True, nullable=True) + github = Column(Text, nullable=True) + points = Column(Integer, nullable=True) + level = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + user_badges = relationship('UserBadges', back_populates='user') + user_certificates = relationship('UserCertificates', back_populates='user') + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'name': self.name, + 'discord': self.discord, + 'github': self.github, + 'points': self.points, + 'level': self.level, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + +class VcLogs(Base): + __tablename__ = 'vc_logs' + + id = Column(BigInteger, primary_key=True) # Auto field + created_at = Column(DateTime, default=func.now(), nullable=False) + discord_id = Column(BigInteger, nullable=True) + discord_name = Column(Text, nullable=True) + option = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'discord_id': self.discord_id, + 'discord_name': self.discord_name, + 'option': self.option + } + +class GitHubProfileData(Base): + __tablename__ = 'github_profile_data' + + github_username = Column(String, primary_key=True) + discord_id = Column(BigInteger, nullable=False) + classroom_points = Column(Integer, nullable=False, default=0) + prs_raised = Column(Integer, nullable=False, default=0) + prs_reviewed = Column(Integer, nullable=False, default=0) + prs_merged = Column(Integer, nullable=False, default=0) + dpg_points = Column(Integer, nullable=False, default=0) + milestone = Column(Integer, nullable=False, default=0) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'github_username': self.github_username, + 'discord_id': self.discord_id, + 'classroom_points': self.classroom_points, + 'prs_raised': self.prs_raised, + 'prs_reviewed': self.prs_reviewed, + 'prs_merged': self.prs_merged, + 'dpg_points': self.dpg_points, + 'milestone': self.milestone, + } + + + +class Leaderboard(Base): + __tablename__ = 'leaderboard' + + discord_id = Column(BigInteger, primary_key=True, autoincrement=False) + github_id = Column(BigInteger, nullable=False) + github_url = Column(Text, nullable=False) + apprentice_badge = Column(Boolean, nullable=True) + converser_badge = Column(Boolean, nullable=False, default=False) + rockstar_badge = Column(Boolean, nullable=False, default=False) + enthusiast_badge = Column(Boolean, nullable=False, default=False) + rising_star_badge = Column(Boolean, nullable=False, default=False) + github_x_discord_badge = Column(Boolean, nullable=False, default=False) + points = Column(Integer, nullable=False, default=0) + bronze_badge = Column(Boolean, nullable=False, default=False) + silver_badge = Column(Boolean, nullable=False, default=False) + gold_badge = Column(Boolean, nullable=False, default=False) + ruby_badge = Column(Boolean, nullable=False, default=False) + diamond_badge = Column(Boolean, nullable=False, default=False) + certificate_link = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'discord_id': self.discord_id, + 'github_id': self.github_id, + 'github_url': self.github_url, + 'apprentice_badge': self.apprentice_badge, + 'converser_badge': self.converser_badge, + 'rockstar_badge': self.rockstar_badge, + 'enthusiast_badge': self.enthusiast_badge, + 'rising_star_badge': self.rising_star_badge, + 'github_x_discord_badge': self.github_x_discord_badge, + 'points': self.points, + 'bronze_badge': self.bronze_badge, + 'silver_badge': self.silver_badge, + 'gold_badge': self.gold_badge, + 'ruby_badge': self.ruby_badge, + 'diamond_badge': self.diamond_badge, + 'certificate_link': self.certificate_link + } \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 5555f28..d4ea454 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,3 +17,5 @@ requests==2.31.0 urllib3==2.0.2 yarl==1.9.2 supabase==1.0.3 +SQLAlchemy==2.0.32 +psycopg2==2.9.9 From 353b425fbc0691238c7dd51d1005e8c39677c2f4 Mon Sep 17 00:00:00 2001 From: jaanbaaz <106968030+jaanbaaz@users.noreply.github.com> Date: Thu, 12 Sep 2024 19:28:29 +0530 Subject: [PATCH 03/21] Update build-and-push.yml file added to make builds on push to main and dev --- .github/workflows/build-and-push.yml | 47 +++++++++++++++++----------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index 03269f7..1e58239 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -4,43 +4,54 @@ on: push: branches: - main - + - dev + release: + types: [published] env: - DOCKER_USERNAME: ${{ github.actor }} - DOCKER_IMAGE_NAME: ${{ github.repository }} - DOCKER_REGISTRY: ghcr.io - DOCKER_IMAGE_TAG: ${{ github.ref_name }} + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} jobs: build-and-push: runs-on: ubuntu-latest + # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + permissions: + contents: read + packages: write steps: - - id: lower-repo - shell: pwsh - run: | - "::set-output name=repository::$($env:DOCKER_IMAGE_NAME.ToLowerInvariant())" - name: Checkout code uses: actions/checkout@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Login to Docker registry - uses: docker/login-action@v1 + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 with: - registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ env.DOCKER_USERNAME }} - password: ${{ secrets.PAT }} + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + # minimal + type=pep440,pattern={{version}},value=${{ github.ref_name }},enable=${{ github.event_name == 'release' }} + # branch event + type=ref,event=branch + type=raw,value=latest,enable=${{ github.event_name == 'release' }} - name: Build and Push Docker image uses: docker/build-push-action@v4 with: - build-args: | - "SERVER_RELEASE_VERSION=${{ github.sha }}" + # build-args: context: . push: true cache-from: type=gha cache-to: type=gha,mode=max - tags: ${{ env.DOCKER_REGISTRY }}/${{ steps.lower-repo.outputs.repository }}:${{env.DOCKER_IMAGE_TAG}} - labels: org.opencontainers.image.source=https://github.com/${{steps.lower-repo.outputs.repository}} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From 1f6976c423274eabd50924de3d864146854381ad Mon Sep 17 00:00:00 2001 From: Srijan Srivastava Date: Mon, 30 Sep 2024 17:08:43 +0530 Subject: [PATCH 04/21] Updated requirements.txt for psycopg2-binary --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d4ea454..66869c1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,4 +18,4 @@ urllib3==2.0.2 yarl==1.9.2 supabase==1.0.3 SQLAlchemy==2.0.32 -psycopg2==2.9.9 +psycopg2-binary==2.9.9 From d36cb2ecc92f6e9d54d2be9b34f236812b38b88b Mon Sep 17 00:00:00 2001 From: jaanbaaz Date: Fri, 15 Nov 2024 11:21:16 +0530 Subject: [PATCH 05/21] MIgration from supabase to postgres changes --- cogs/discordDataScraper.py | 31 +-------------------------- cogs/userInteractions.py | 44 +------------------------------------- cogs/vcCog.py | 3 --- helpers/supabaseClient.py | 10 ++++----- main.py | 7 +++--- models.py | 13 ----------- 6 files changed, 11 insertions(+), 97 deletions(-) diff --git a/cogs/discordDataScraper.py b/cogs/discordDataScraper.py index b78565a..0457831 100644 --- a/cogs/discordDataScraper.py +++ b/cogs/discordDataScraper.py @@ -28,36 +28,7 @@ def __init__(self, bot) -> None: @commands.Cog.listener() async def on_message(self, message): pass - # contributor = PostgresClient().read( - # "discord_engagement", "contributor", message.author.id - # ) - # print("message", len(message.content)) - # if not contributor: - # PostgresClient().insert( - # "discord_engagement", - # { - # "contributor": message.author.id, - # "has_introduced": False, - # "total_message_count": 1, - # "total_reaction_count": 0, - # }, - # ) - # return - # if len(message.content) > 20: - # if message.channel.id == INTRODUCTIONS_CHANNEL_ID: - # print("intro") - # PostgresClient().update( - # "discord_engagement", - # {"has_introduced": True}, - # "contributor", - # message.author.id, - # ) - # PostgresClient("discord_engagement").update( - # "discord_engagement", - # {"total_message_count": contributor[0]["total_message_count"] + 1}, - # "contributor", - # message.author.id, - # ) + @commands.Cog.listener() async def on_reaction_add(self, reaction, user): diff --git a/cogs/userInteractions.py b/cogs/userInteractions.py index 142a292..757c198 100644 --- a/cogs/userInteractions.py +++ b/cogs/userInteractions.py @@ -65,10 +65,6 @@ async def list_badges(self, ctx): return - # @commands.command() - # async def give_badges(self, ctx): - # self.give_discord_badges.start() - @tasks.loop(minutes=10) async def update_contributors(self): contributors = PostgresClient().read_all("contributors_registration") @@ -84,45 +80,7 @@ async def update_contributors(self): print(member.name) await member.add_roles(contributor_role) print(f"Given Roles to {member.name if member else 'None'}") - # add to discord engagement - # PostgresClient("discord_engagement").insert({"contributor": member.id}) - - # update engagement - # for contributor in contributors: - # contributorData = PostgresClient("discord_engagement").read("contributor", contributor["discord_id"])[0] - # member = await guild.fetch_member(contributorData["contributor"]) - # print(f"-----Contributor-----{member.name}-------") - # badges = Badges(member.name) - # if contributorData: - # if contributorData["total_message_count"]>10 and not contributorData["converserBadge"]: - # PostgresClient("discord_engagement").update({"converserBadge":True},"contributor", contributorData["contributor"]) - # dmchannel = member.dm_channel if member.dm_channel else await member.create_dm() - # await dmchannel.send(embed=badges.converseBadge) - # if contributorData["total_reaction_count"]>5 and not contributorData["rockstarBadge"]: - # PostgresClient("discord_engagement").update({"rockstarBadge":True},"contributor", contributorData["contributor"]) - # dmchannel = member.dm_channel if member.dm_channel else await member.create_dm() - # await dmchannel.send(embed=badges.rockstarBadge) - # if contributorData["has_introduced"] and not contributorData["apprenticeBadge"]: - # PostgresClient("discord_engagement").update({"apprenticeBadge":True},"contributor", contributorData["contributor"]) - # dmchannel = member.dm_channel if member.dm_channel else await member.create_dm() - # await dmchannel.send(embed=badges.apprenticeBadge) - # github_id = contributor["github_id"] - # prData = { - # "raised": PostgresClient(table="pull_requests").read(query_key="raised_by", query_value=github_id), - # "merged":PostgresClient(table="pull_requests").read(query_key="merged_by", query_value=github_id) - # } - # points = 0 - # for action in prData.keys(): - # prs = prData[action] - # for pr in prs: - # points+=pr["points"] - # if len(prData["raised"])+len(prData["merged"])>0and not contributorData["enthusiastBadge"]: - # PostgresClient("discord_engagement").update({"enthusiastBadge":True},"contributor", contributorData["contributor"]) - # await dmchannel.send(embed=Badges(member.name, points=points).enthusiastBadge) - # if points>=30 and not contributorData["risingStarBadge"]: - # PostgresClient("discord_engagement").update({"risingStarBadge":True},"contributor", contributorData["contributor"]) - # await dmchannel.send(embed=badges.risingStarBadge) - + return @commands.command() diff --git a/cogs/vcCog.py b/cogs/vcCog.py index dc6427e..3387bab 100644 --- a/cogs/vcCog.py +++ b/cogs/vcCog.py @@ -227,7 +227,6 @@ async def resetSelectMenu(self, interaction): placeholder="Which program are you seeking credentials for?", options=[ SelectOption(label="Community Program", value="ccbp"), - # SelectOption(label="Mentoring Program", value="dmp") ], ) async def selectAProgram(self, interaction: Interaction, select: ui.Select): @@ -237,8 +236,6 @@ async def selectAProgram(self, interaction: Interaction, select: ui.Select): await interaction.response.send_message( view=CommunityVCView(), ephemeral=True ) - # elif selected_option == "dmp": - # await interaction.response.send_message(view=DMPVCView(), ephemeral=True) else: await interaction.response.send_message( "Unknown selection.", ephemeral=True diff --git a/helpers/supabaseClient.py b/helpers/supabaseClient.py index a2b8179..3f99230 100644 --- a/helpers/supabaseClient.py +++ b/helpers/supabaseClient.py @@ -2,7 +2,7 @@ from discord import Member, User from supabase import Client, create_client -from helpers.roleHelpers import lookForChapterRoles, lookForGenderRoles +from helpers.roleHelpers import lookForRoles from dotenv import load_dotenv from sqlalchemy import create_engine,select,desc,update,delete from sqlalchemy.orm import sessionmaker @@ -335,8 +335,8 @@ def updateContributor(self, contributor: Member, table_class=None): try: if table_class == None: table_class = ContributorsDiscord - chapters = lookForChapterRoles(contributor.roles) - gender = lookForGenderRoles(contributor.roles) + chapters = lookForRoles(contributor.roles)["chapter_roles"] + gender = lookForRoles(contributor.roles)["gender"] # Prepare the data to be upserted update_data = { @@ -371,8 +371,8 @@ def updateContributor(self, contributor: Member, table_class=None): def updateContributors(self, contributors: [Member], table_class): try: for contributor in contributors: - chapters = lookForChapterRoles(contributor.roles) - gender = lookForGenderRoles(contributor.roles) + chapters = lookForRoles(contributor.roles)["chapter_roles"] + gender = lookForRoles(contributor.roles)["gender"] update_data = { "discord_id": contributor.id, "discord_username": contributor.name, diff --git a/main.py b/main.py index 28e3c5b..4f0281c 100644 --- a/main.py +++ b/main.py @@ -73,10 +73,11 @@ async def on_submit(self, interaction: discord.Interaction): "discord_id": user.id, "country": self.country.value } - supaClient = SupabaseClient() + # supaClient = SupabaseClient() try: - response = (supaClient.client.table("contributors_discord") - .upsert(user_data, on_conflict="discord_id").execute()) + # response = (supaClient.client.table("contributors_discord") + # .upsert(user_data, on_conflict="discord_id").execute()) + response = PostgresClient().updateContributor(user_data) print("DB updated for user:", response.data[0]["discord_id"]) except Exception as e: print("Failed to update credentials for user: "+e) diff --git a/models.py b/models.py index 9334f22..efacb0a 100644 --- a/models.py +++ b/models.py @@ -744,9 +744,6 @@ class MentorshipProgramSiteStructure(Base): website_directory_label = Column(Text, nullable=True) directory_url = Column(Text, nullable=True) - # project = relationship('MentorshipProgramProjects', back_populates='site_structures') - # contributor = relationship('MentorshipProgramSelectedContributors', back_populates='site_structures') - def __repr__(self): return f"" @@ -890,9 +887,6 @@ def to_dict(self): } - -## - class MentorshipProgramWebsitePullRequest(Base): __tablename__ = 'mentorship_program_website_pull_request' @@ -1061,9 +1055,6 @@ def to_dict(self): } - -### - class PrHistory(Base): __tablename__ = 'pr_history' @@ -1371,10 +1362,6 @@ def to_dict(self): 'updated_at': self.updated_at } - - -### - class UserPointsMapping(Base): __tablename__ = 'user_points_mapping' id = Column(UUID(as_uuid=True), primary_key=True) From c20b8151ab08ae759e39d456ddbc22b2cd651965 Mon Sep 17 00:00:00 2001 From: jaanbaaz Date: Fri, 15 Nov 2024 12:18:45 +0530 Subject: [PATCH 06/21] MIgration from supabase to postgres changes --- cogs/badges.py | 14 ++++++++------ cogs/discordDataScraper.py | 19 ++++++++++--------- cogs/listeners/member_events_cog.py | 5 +++-- cogs/listeners/role_events_cog.py | 11 ++++++----- cogs/serverManagement.py | 15 ++++++++------- cogs/userInteractions.py | 13 +++++++------ cogs/vcCog.py | 12 +++++++----- 7 files changed, 49 insertions(+), 40 deletions(-) diff --git a/cogs/badges.py b/cogs/badges.py index 7d728be..43f6f97 100644 --- a/cogs/badges.py +++ b/cogs/badges.py @@ -17,7 +17,9 @@ async def on_timeout(self, interaction): class BadgeContents: def __init__(self, name) -> None: + self.postgres_client = PostgresClient() apprentinceDesc = f"""Welcome *{name}*!! + Congratulations! 🎉 You have taken the first step to join & introduce yourself to this awesome community and earned the **Apprentice Badge**! 🎓 This badge shows that you are eager to learn and grow with our community! 😎 We are so happy to have you here and we can’t wait to see what you will create and solve! 🚀""" @@ -133,7 +135,7 @@ def get_user_badges(self, discord_id): userBadges = {"points": [], "achievements": []} if ( len( - PostgresClient().read( + self.postgres_client.read( "contributors_registration", query_key="discord_id", query_value=discord_id, @@ -143,7 +145,7 @@ def get_user_badges(self, discord_id): ): userBadges["achievements"].append(self.discordXGithubBadge) - discordMemberData = PostgresClient().read( + discordMemberData = self.postgres_client.read( "discord_engagement", "contributor", discord_id ) if discordMemberData: @@ -153,17 +155,17 @@ def get_user_badges(self, discord_id): userBadges["achievements"].append(self.rockstarBadge) if discordMemberData[0]["has_introduced"]: userBadges["achievements"].append(self.apprenticeBadge) - contributorData = PostgresClient().read( + contributorData = self.postgres_client.read( "contributors_registration", query_key="discord_id", query_value=discord_id ) if contributorData: github_id = contributorData[0]["github_id"] prData = { - "raised": PostgresClient().read( + "raised": self.postgres_client.read( table="connected_prs", query_key="raised_by", query_value=github_id ), - "merged": PostgresClient(table="connected_prs").read( - table="connected_prs", query_key="merged_by", query_value=github_id + "merged": self.postgres_client.read( + "connected_prs", query_key="merged_by", query_value=github_id ), } points = 0 diff --git a/cogs/discordDataScraper.py b/cogs/discordDataScraper.py index 0457831..6a1eb0c 100644 --- a/cogs/discordDataScraper.py +++ b/cogs/discordDataScraper.py @@ -24,6 +24,7 @@ class DiscordDataScaper(commands.Cog): def __init__(self, bot) -> None: self.bot = bot + self.postgres_client = PostgresClient() @commands.Cog.listener() async def on_message(self, message): @@ -33,11 +34,11 @@ async def on_message(self, message): @commands.Cog.listener() async def on_reaction_add(self, reaction, user): message = reaction.message - contributor = PostgresClient().read( + contributor = self.postgres_client.read( "discord_engagement", "contributor", message.author.id )[0] if not contributor: - PostgresClient().insert( + self.postgres_client.insert( "discord_engagement", { "contributor": message.author.id, @@ -48,7 +49,7 @@ async def on_reaction_add(self, reaction, user): ) return print("reaction") - PostgresClient().update( + self.postgres_client.update( "discord_engagement", {"total_reaction_count": contributor["total_reaction_count"] + 1}, "contributor", @@ -60,7 +61,7 @@ async def add_engagement(self, ctx): await ctx.channel.send("started") def addEngagmentData(data): - client = PostgresClient() + client = self.postgres_client client.insert("discord_engagement", data) return @@ -116,7 +117,7 @@ async def enable_webhook(self, ctx): channels = await guild.fetch_channels() enabled = [ channel["channel_id"] - for channel in PostgresClient().read_all("discord_channels") + for channel in self.postgres_client.read_all("discord_channels") ] for channel in channels: try: @@ -127,7 +128,7 @@ async def enable_webhook(self, ctx): webhook = await channel.create_webhook(name="New Ticket Alert") feedback = f"""URL: {webhook.url}\n Token:{"Yes" if webhook.token else "No"}""" await ctx.send(feedback) - PostgresClient().insert( + self.postgres_client.insert( "discord_channels", { "channel_id": channel.id, @@ -148,7 +149,7 @@ async def update_applicants(self, ctx): await ctx.send("Member List Count: " + str(len(members))) for member in members: try: - PostgresClient().insert( + self.postgres_client.insert( "applicant", {"sheet_username": member.name, "discord_id": member.id}, ) @@ -187,12 +188,12 @@ async def collect_all_messages(self): async def add_messages(self): def addMessageData(data): - client = PostgresClient() + client = self.postgres_client client.insert("unstructured discord data", data) return def getLastMessageObject(channelId): - last_message = PostgresClient().read_by_order_limit( + last_message = self.postgres_client.read_by_order_limit( table="unstructured discord data", query_key="channel", query_value=channelId, diff --git a/cogs/listeners/member_events_cog.py b/cogs/listeners/member_events_cog.py index 3a353e2..ebb6937 100644 --- a/cogs/listeners/member_events_cog.py +++ b/cogs/listeners/member_events_cog.py @@ -7,11 +7,12 @@ class MemberEventsListener(commands.Cog): def __init__(self, bot) -> None: self.bot = bot + self.postgres_client = PostgresClient() super().__init__() @commands.Cog.listener("on_member_join") async def on_member_join(self, member: discord.Member): - PostgresClient().updateContributor(member) + self.postgres_client.updateContributor(member) @commands.Cog.listener("on_member_remove") async def on_member_remove(self, member: discord.Member): @@ -20,7 +21,7 @@ async def on_member_remove(self, member: discord.Member): @commands.Cog.listener("on_member_update") async def on_member_update(self, before: discord.Member, after: discord.Member): - PostgresClient().updateContributor(after) + self.postgres_client.updateContributor(after) async def setup(bot: commands.Bot): diff --git a/cogs/listeners/role_events_cog.py b/cogs/listeners/role_events_cog.py index 68a2855..a497947 100644 --- a/cogs/listeners/role_events_cog.py +++ b/cogs/listeners/role_events_cog.py @@ -7,33 +7,34 @@ class RoleEventsListener(commands.Cog): def __init__(self, bot) -> None: self.bot = bot + self.postgres_client = PostgresClient() super().__init__() @commands.Cog.listener() async def on_guild_role_create(self, role: discord.Role): if role.name.startswith("College:"): orgName = role.name[len("College: ") :] - PostgresClient().addChapter(roleId=role.id, orgName=orgName, type="COLLEGE") + self.postgres_client.addChapter(roleId=role.id, orgName=orgName, type="COLLEGE") elif role.name.startswith("Corporate:"): orgName = role.name[len("Corporate: ") :] - PostgresClient().addChapter( + self.postgres_client.addChapter( roleId=role.id, orgName=orgName, type="CORPORATE" ) @commands.Cog.listener() async def on_guild_role_delete(self, role: discord.Role): - PostgresClient().deleteChapter(roleID=role.id) + self.postgres_client.deleteChapter(roleID=role.id) @commands.Cog.listener() async def on_guild_role_update(self, before: discord.Role, after: discord.Role): if after.name.startswith("College:"): orgName = after.name[len("College: ") :] - PostgresClient().addChapter( + self.postgres_client.addChapter( roleId=after.id, orgName=orgName, type="COLLEGE" ) elif after.name.startswith("Corporate:"): orgName = after.name[len("Corporate: ") :] - PostgresClient().addChapter( + self.postgres_client.addChapter( roleId=after.id, orgName=orgName, type="CORPORATE" ) diff --git a/cogs/serverManagement.py b/cogs/serverManagement.py index 681c510..b33c6b2 100644 --- a/cogs/serverManagement.py +++ b/cogs/serverManagement.py @@ -12,6 +12,7 @@ class ServerManagement(commands.Cog): def __init__(self, bot): self.bot: commands.Bot = bot self.assign_contributor_role.start() + self.postgres_client = PostgresClient() def validUser(self, ctx): authorised_users = [ @@ -40,20 +41,20 @@ async def updateServerData(self, ctx): if role.name.startswith("College:"): orgName = role.name[len("College: ") :] chapterRoles.append(role) - PostgresClient().addChapter( + self.postgres_client.addChapter( roleId=role.id, orgName=orgName, type="COLLEGE" ) elif role.name.startswith("Corporate:"): orgName = role.name[len("Corporate: ") :] chapterRoles.append(role) - PostgresClient().addChapter( + self.postgres_client.addChapter( roleId=role.id, orgName=orgName, type="CORPORATE" ) print("added chapters") - contributorsGithub = PostgresClient().read_all("contributors_registration") - contributorsDiscord = PostgresClient().read_all_active("contributors_discord") + contributorsGithub = self.postgres_client.read_all("contributors_registration") + contributorsDiscord = self.postgres_client.read_all_active("contributors_discord") ## Give contributor role contributorIds = [ @@ -71,7 +72,7 @@ async def updateServerData(self, ctx): print(count) - PostgresClient().updateContributors(guild.members) + self.postgres_client.updateContributors(guild.members) recordedMembers = [ contributor["discord_id"] for contributor in contributorsDiscord ] @@ -79,14 +80,14 @@ async def updateServerData(self, ctx): currentMembers = [member.id for member in guild.members] membersWhoLeft = list(set(recordedMembers) - set(currentMembers)) print(f"{len(membersWhoLeft)} members left") - PostgresClient().invalidateContributorDiscord(membersWhoLeft) + self.postgres_client.invalidateContributorDiscord(membersWhoLeft) print("Updated Contributors") @tasks.loop(minutes=30) async def assign_contributor_role(self): guild = self.bot.get_guild(serverConfig.SERVER) contributorRole = guild.get_role(serverConfig.Roles.CONTRIBUTOR_ROLE) - contributorsGithub = PostgresClient().read_all("contributors_registration") + contributorsGithub = self.postgres_client.read_all("contributors_registration") contributorIds = [ contributor["discord_id"] for contributor in contributorsGithub diff --git a/cogs/userInteractions.py b/cogs/userInteractions.py index 757c198..8166ce9 100644 --- a/cogs/userInteractions.py +++ b/cogs/userInteractions.py @@ -16,11 +16,12 @@ class UserHandler(commands.Cog): def __init__(self, bot) -> None: self.bot = bot self.update_contributors.start() + self.postgres_client = PostgresClient() @tasks.loop(minutes=60) async def update_contributors(self): print("update_contributors running") - contributors = PostgresClient().read_all("contributors_registration") + contributors = self.postgres_client.read_all("contributors_registration") print("Contributors in DB: ", len(contributors)) guild = await self.bot.fetch_guild(os.getenv("SERVER_ID")) contributor_role = guild.get_role(VERIFIED_CONTRIBUTOR_ROLE_ID) @@ -67,7 +68,7 @@ async def list_badges(self, ctx): @tasks.loop(minutes=10) async def update_contributors(self): - contributors = PostgresClient().read_all("contributors_registration") + contributors = self.postgres_client.read_all("contributors_registration") guild = await self.bot.fetch_guild(os.getenv("SERVER_ID")) contributor_role = guild.get_role(VERIFIED_CONTRIBUTOR_ROLE_ID) count = 1 @@ -119,7 +120,7 @@ async def github_profile(self, ctx): **Know more about [badges & points](https://github.com/Code4GovTech/C4GT/wiki/Point-System-for-Contributors)**🧗""" noPointsGithubProfileEmbed = discord.Embed(title="", description=desc) - user = PostgresClient().read( + user = self.postgres_client.read( "github_profile_data", "discord_id", ctx.author.id ) if len(user) == 0: @@ -188,17 +189,17 @@ async def point_breakdown(self, ctx): async def get_points(self, ctx): if isinstance(ctx.channel, discord.DMChannel): discord_id = ctx.author.id - contributor = PostgresClient().read( + contributor = self.postgres_client.read( table="contributors_registration", query_key="discord_id", query_value=discord_id, ) print(contributor) github_id = contributor[0]["github_id"] - prs_raised = PostgresClient().read( + prs_raised = self.postgres_client.read( table="connected_prs", query_key="raised_by", query_value=github_id ) - prs_merged = PostgresClient().read( + prs_merged = self.postgres_client.read( table="connected_prs", query_key="merged_by", query_value=github_id ) raise_points = 0 diff --git a/cogs/vcCog.py b/cogs/vcCog.py index 3387bab..bfc6f90 100644 --- a/cogs/vcCog.py +++ b/cogs/vcCog.py @@ -21,6 +21,7 @@ class CommunityVCView(ui.View): def __init__(self, *, timeout=None): super().__init__(timeout=timeout) + self.postgres_client = PostgresClient() def isCommunityContributor(self, roles: list[Role]): CommunityContributorRoleID = ServerConfig.Roles.CONTRIBUTOR_ROLE @@ -29,7 +30,7 @@ def isCommunityContributor(self, roles: list[Role]): return False def getCommunityMember(self, memberId: Member): - data = PostgresClient().getLeaderboard(memberId) + data = self.postgres_client.getLeaderboard(memberId) if data: contributor = data[0] return contributor @@ -59,7 +60,7 @@ def getCertificateLink(self, contributor): def getStatsShowcaseImage(self, discordId=None, type=None): print(f"{discordId}-c4gt-contributions.jpeg") - imageBytes = PostgresClient().getStatsStorage( + imageBytes = self.postgres_client.getStatsStorage( f"{discordId}-c4gt-contributions.jpeg" ) with BytesIO(imageBytes) as imageFile: @@ -72,7 +73,7 @@ def getStatsShowcaseImage(self, discordId=None, type=None): custom_id=f"vc_view_button:my_cert:blurple", ) async def serveCertificateLink(self, interaction: Interaction, button: ui.Button): - PostgresClient().logVCAction(interaction.user, "My Certificate Button") + self.postgres_client.logVCAction(interaction.user, "My Certificate Button") contributor = self.getCommunityMember(interaction.user.id) if contributor["points"] < 10: await interaction.response.send_message( @@ -99,7 +100,7 @@ async def serveCertificateLink(self, interaction: Interaction, button: ui.Button custom_id=f"vc_view:my_profile:blurple", ) async def serveDPGProfile(self, interaction: Interaction, button: ui.Button): - PostgresClient().logVCAction(interaction.user, "DPG Profile Button") + self.postgres_client.logVCAction(interaction.user, "DPG Profile Button") if not self.isCommunityContributor(interaction.user.roles): await interaction.response.send_message( "You're not currently a registered contributor! Head over to <#1211992155673862204> and register as a Verified C4GT Community Contributor :fireworks:", @@ -214,6 +215,7 @@ async def serveCertificateLink(self, interaction: Interaction, button: ui.Button class VCProgramSelection(ui.View): def __init__(self, *, timeout=None): + self.postgres_client = PostgresClient() super().__init__(timeout=timeout) async def resetSelectMenu(self, interaction): @@ -230,7 +232,7 @@ async def resetSelectMenu(self, interaction): ], ) async def selectAProgram(self, interaction: Interaction, select: ui.Select): - PostgresClient().logVCAction(interaction.user, "Clicked on Dropdown") + self.postgres_client.logVCAction(interaction.user, "Clicked on Dropdown") selected_option = select.values[0] if selected_option == "ccbp": await interaction.response.send_message( From 83c419975c4129b4e5b5c762e8e6f45b09b6c8ab Mon Sep 17 00:00:00 2001 From: jaanbaaz Date: Fri, 15 Nov 2024 13:28:12 +0530 Subject: [PATCH 07/21] MIgration from supabase to postgres changes --- cogs/userInteractions.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/cogs/userInteractions.py b/cogs/userInteractions.py index 8166ce9..998792b 100644 --- a/cogs/userInteractions.py +++ b/cogs/userInteractions.py @@ -66,24 +66,6 @@ async def list_badges(self, ctx): return - @tasks.loop(minutes=10) - async def update_contributors(self): - contributors = self.postgres_client.read_all("contributors_registration") - guild = await self.bot.fetch_guild(os.getenv("SERVER_ID")) - contributor_role = guild.get_role(VERIFIED_CONTRIBUTOR_ROLE_ID) - count = 1 - for contributor in contributors: - print(count) - count += 1 - member = guild.get_member(contributor["discord_id"]) - if member and contributor_role not in member.roles: - # Give Contributor Role - print(member.name) - await member.add_roles(contributor_role) - print(f"Given Roles to {member.name if member else 'None'}") - - return - @commands.command() async def github_profile(self, ctx): if isinstance(ctx.channel, discord.DMChannel): From 469f82a7c00a9657e893bf8b8e5c1db06fe3cfab Mon Sep 17 00:00:00 2001 From: karntrehan Date: Mon, 25 Nov 2024 17:09:17 +0530 Subject: [PATCH 08/21] Fix env variables for postgres --- .env.sample | 7 +++++-- cogs/serverManagement.py | 20 -------------------- docker-compose.yml | 5 ++++- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/.env.sample b/.env.sample index 65f2e8f..82f6a66 100644 --- a/.env.sample +++ b/.env.sample @@ -4,8 +4,6 @@ SERVER_ID= INTRODUCTIONS_CHANNEL= NON_CONTRIBUTOR_ROLES= -FLASK_HOST= -GITHUB_PAT= WEBHOOK_URL= GITHUB_AUTHENTICATION_URL= @@ -13,3 +11,8 @@ GITHUB_AUTHENTICATION_URL= SUPABASE_URL= SUPABASE_KEY= VERIFIED_ROLE_ID= + +POSTGRES_DB_HOST= +POSTGRES_DB_NAME= +POSTGRES_DB_USER= +POSTGRES_DB_PASS= diff --git a/cogs/serverManagement.py b/cogs/serverManagement.py index b33c6b2..ba842ab 100644 --- a/cogs/serverManagement.py +++ b/cogs/serverManagement.py @@ -11,7 +11,6 @@ class ServerManagement(commands.Cog): def __init__(self, bot): self.bot: commands.Bot = bot - self.assign_contributor_role.start() self.postgres_client = PostgresClient() def validUser(self, ctx): @@ -83,24 +82,5 @@ async def updateServerData(self, ctx): self.postgres_client.invalidateContributorDiscord(membersWhoLeft) print("Updated Contributors") - @tasks.loop(minutes=30) - async def assign_contributor_role(self): - guild = self.bot.get_guild(serverConfig.SERVER) - contributorRole = guild.get_role(serverConfig.Roles.CONTRIBUTOR_ROLE) - contributorsGithub = self.postgres_client.read_all("contributors_registration") - - contributorIds = [ - contributor["discord_id"] for contributor in contributorsGithub - ] - - for member in guild.members: - if member.id in contributorIds and contributorRole not in member.roles: - await member.add_roles(contributorRole) - - @assign_contributor_role.before_loop - async def before_assign_contributor_role(self): - await self.bot.wait_until_ready() # Wait until the bot is logged in and ready - - async def setup(bot): await bot.add_cog(ServerManagement(bot)) diff --git a/docker-compose.yml b/docker-compose.yml index 1f24d76..db8677c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,11 +16,14 @@ services: SERVER_ID: ${SERVER_ID} INTRODUCTIONS_CHANNEL: ${INTRODUCTIONS_CHANNEL} NON_CONTRIBUTOR_ROLES: ${NON_CONTRIBUTOR_ROLES} - FLASK_HOST: ${FLASK_HOST} SUPABASE_URL: ${SUPABASE_URL} SUPABASE_KEY: ${SUPABASE_KEY} VERIFIED_ROLE_ID: ${VERIFIED_ROLE_ID} GITHUB_AUTHENTICATION_URL: ${GITHUB_AUTHENTICATION_URL} + POSTGRES_DB_HOST: ${POSTGRES_DB_HOST} + POSTGRES_DB_NAME: ${POSTGRES_DB_NAME} + POSTGRES_DB_USER: ${POSTGRES_DB_USER} + POSTGRES_DB_PASS: ${POSTGRES_DB_PASS} networks: logstash_common: From 3364a9085b7eb9dbfecd0911cbe4b3acd1356dec Mon Sep 17 00:00:00 2001 From: jaanbaaz Date: Tue, 26 Nov 2024 15:31:42 +0530 Subject: [PATCH 09/21] postgres initialization changes --- helpers/supabaseClient.py | 98 +++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 34 deletions(-) diff --git a/helpers/supabaseClient.py b/helpers/supabaseClient.py index 3f99230..598801e 100644 --- a/helpers/supabaseClient.py +++ b/helpers/supabaseClient.py @@ -7,6 +7,8 @@ from sqlalchemy import create_engine,select,desc,update,delete from sqlalchemy.orm import sessionmaker from models import * +from sqlalchemy.ext.declarative import DeclarativeMeta +from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession load_dotenv() @@ -171,9 +173,12 @@ def __init__(self): DB_USER = os.getenv('POSTGRES_DB_USER') DB_PASS = os.getenv('POSTGRES_DB_PASS') - engine = create_engine(f'postgresql://{DB_USER}:{DB_PASS}@{DB_HOST}/{DB_NAME}') - Session = sessionmaker(bind=engine) - self.session = Session() + engine = create_async_engine(f'postgresql+asyncpg://{DB_USER}:{DB_PASS}@{DB_HOST}/{DB_NAME}') + async_session = sessionmaker(autocommit=False, autoflush=False, bind=engine, class_=AsyncSession) + self.session = async_session + + def get_instance(): + return PostgresClient() def convert_dict(self,data): try: @@ -227,7 +232,16 @@ def read(self, table_class, query_key, query_value, columns=None): print(f"Error reading data from table '{table_class}':", e) return None - + def get_class_by_tablename(self,tablename): + try: + for cls in Base.registry._class_registry.values(): + if isinstance(cls, DeclarativeMeta): + if hasattr(cls, '__tablename__') and cls.__tablename__ == tablename: + return cls + return None + except Exception as e: + print(f"ERROR get_class_by_tablename - {e}") + return None def read_by_order_limit(self, table_class, query_key, query_value, order_column, order_by=False, limit=1, columns="*"): try: @@ -255,9 +269,20 @@ def read_by_order_limit(self, table_class, query_key, query_value, order_column, print("Error reading data:", e) return None - def read_all(self, table): - data = self.session.query(table).all() - return self.convert_dict(data) + async def read_all(self,table_class): + try: + table = self.get_class_by_tablename(table_class) + # Query all records from the specified table class + async with self.session() as session: + stmt = select(table) + result = await session.execute(stmt) + + data = result.scalars().all() + result = self.convert_dict(data) + return result + except Exception as e: + print(f"An error occurred -read_all_from_table : {e}") + return None def update(self, table_class, update_data, query_key, query_value): try: @@ -331,38 +356,43 @@ def deleteChapter(self,roleId: int): print("Error deleting chapter:", e) return None - def updateContributor(self, contributor: Member, table_class=None): + async def updateContributor(self, contributor: Member, table_class=None): try: - if table_class == None: - table_class = ContributorsDiscord - chapters = lookForRoles(contributor.roles)["chapter_roles"] - gender = lookForRoles(contributor.roles)["gender"] + async with self.session() as session: + if table_class == None: + table_class = ContributorsDiscord + chapters = lookForRoles(contributor.roles)["chapter_roles"] + gender = lookForRoles(contributor.roles)["gender"] - # Prepare the data to be upserted - update_data = { - "discord_id": contributor.id, - "discord_username": contributor.name, - "chapter": chapters[0] if chapters else None, - "gender": gender, - "joined_at": contributor.joined_at, - } + # Prepare the data to be upserted + update_data = { + "discord_id": contributor.id, + "discord_username": contributor.name, + "chapter": chapters[0] if chapters else None, + "gender": gender, + "joined_at": contributor.joined_at, + } - existing_record = self.session.query(table_class).filter_by(discord_id=contributor.id).first() + stmt = select(ContributorsDiscord).where(ContributorsDiscord.discord_id == contributor.id) + result = await session.execute(stmt) + existing_record = result.scalars().first() - if existing_record: - stmt = ( - update(table_class) - .where(table_class.discord_id == contributor.id) - .values(update_data) - ) - self.session.execute(stmt) - else: - new_record = table_class(**update_data) - self.session.add(new_record) + # existing_record = self.session.query(table_class).filter_by(discord_id=contributor.id).first() - # Commit the transaction - self.session.commit() - return True + if existing_record: + stmt = ( + update(table_class) + .where(table_class.discord_id == contributor.id) + .values(update_data) + ) + self.session.execute(stmt) + else: + new_record = table_class(**update_data) + self.session.add(new_record) + + # Commit the transaction + self.session.commit() + return True except Exception as e: print("Error updating contributor:", e) return False From cd8c28b58fd98401e2477315c9e689b3f39623a9 Mon Sep 17 00:00:00 2001 From: karntrehan Date: Thu, 28 Nov 2024 13:38:03 +0530 Subject: [PATCH 10/21] Add dependencies and fix logs --- cogs/userInteractions.py | 4 +++- main.py | 17 +---------------- requirements.txt | 8 +++++--- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/cogs/userInteractions.py b/cogs/userInteractions.py index 998792b..eba7602 100644 --- a/cogs/userInteractions.py +++ b/cogs/userInteractions.py @@ -21,8 +21,10 @@ def __init__(self, bot) -> None: @tasks.loop(minutes=60) async def update_contributors(self): print("update_contributors running") - contributors = self.postgres_client.read_all("contributors_registration") + contributors = await self.postgres_client.read_all("contributors_registration") print("Contributors in DB: ", len(contributors)) + ##TODO remove return + return guild = await self.bot.fetch_guild(os.getenv("SERVER_ID")) contributor_role = guild.get_role(VERIFIED_CONTRIBUTOR_ROLE_ID) for contributor in contributors: diff --git a/main.py b/main.py index 4f0281c..a5bf1fc 100644 --- a/main.py +++ b/main.py @@ -53,31 +53,16 @@ def __init__( async def on_submit(self, interaction: discord.Interaction): user = interaction.user - await interaction.response.send_message( - "Thanks! Now please sign in via Github!", - view=AuthenticationView(user.id), - ephemeral=True, - ) - print(self,"self") - await self.post_data( - { - "name": self.name.value, - "discord_id": user.id, - "country": self.country.value, - } - ) - # Upsert user data to db user_data = { "name": self.name.value, "discord_id": user.id, "country": self.country.value } - # supaClient = SupabaseClient() try: # response = (supaClient.client.table("contributors_discord") # .upsert(user_data, on_conflict="discord_id").execute()) - response = PostgresClient().updateContributor(user_data) + response = await PostgresClient().updateContributor(user_data) print("DB updated for user:", response.data[0]["discord_id"]) except Exception as e: print("Failed to update credentials for user: "+e) diff --git a/requirements.txt b/requirements.txt index 66869c1..9c7c781 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,9 @@ fuzzywuzzy==0.18.0 mistune==3.0.1 requests==2.31.0 -aiohttp==3.8.4 +aiohttp==3.11.8 aiosignal==1.3.1 -async-timeout==4.0.2 +async-timeout==5.0.1 attrs==23.1.0 certifi==2023.5.7 charset-normalizer==3.1.0 @@ -15,7 +15,9 @@ multidict==6.0.4 python-dotenv==1.0.0 requests==2.31.0 urllib3==2.0.2 -yarl==1.9.2 +yarl==1.18.0 supabase==1.0.3 SQLAlchemy==2.0.32 psycopg2-binary==2.9.9 +asyncpg==0.30.0 +greenlet==3.1.1 From ec6de60aa15f230f1c68ed5d1243d15d0084ee7c Mon Sep 17 00:00:00 2001 From: jaanbaaz Date: Tue, 10 Dec 2024 18:11:46 +0530 Subject: [PATCH 11/21] migration to postgres bug fixes in postgres queries --- cogs/userInteractions.py | 2 +- helpers/supabaseClient.py | 122 ++++++++++++++++++++------------------ main.py | 26 ++++---- 3 files changed, 81 insertions(+), 69 deletions(-) diff --git a/cogs/userInteractions.py b/cogs/userInteractions.py index eba7602..8744f2d 100644 --- a/cogs/userInteractions.py +++ b/cogs/userInteractions.py @@ -24,7 +24,7 @@ async def update_contributors(self): contributors = await self.postgres_client.read_all("contributors_registration") print("Contributors in DB: ", len(contributors)) ##TODO remove return - return + # return guild = await self.bot.fetch_guild(os.getenv("SERVER_ID")) contributor_role = guild.get_role(VERIFIED_CONTRIBUTOR_ROLE_ID) for contributor in contributors: diff --git a/helpers/supabaseClient.py b/helpers/supabaseClient.py index 598801e..d51971f 100644 --- a/helpers/supabaseClient.py +++ b/helpers/supabaseClient.py @@ -211,14 +211,52 @@ def getLeaderboard(self, id: int): data = self.session.query(Leaderboard).where(Leaderboard.discord_id == id).all() return self.convert_dict(data) - - def read(self, table_class, query_key, query_value, columns=None): + async def read(self, table, query_key, query_value, columns=None): + """ + Reads a single record from a table in the database using SQLAlchemy ORM. + + Args: + table (str): The name of the table to query. + query_key (str): The column name to filter by. + query_value (Any): The value to filter for in the specified column. + columns (list, optional): A list of column names to retrieve. Defaults to None (all columns). + + Returns: + dict: The record as a dictionary, or None if no record is found. + """ try: - stmt = select(table_class) - stmt = stmt.where(getattr(table_class, query_key) == query_value) + table_class = self.get_class_by_tablename(table) + # Build the query if columns: - stmt = stmt.with_only_columns(*(getattr(table_class, col) for col in columns)) + stmt = select([getattr(table_class, col) for col in columns]).where( + getattr(table_class, query_key) == query_value + ) + else: + stmt = select(table_class).where( + getattr(table_class, query_key) == query_value + ) + + # Execute the query + async with self.session() as session: + result = await session.execute(stmt) + record = result.scalar_one_or_none() # Fetch a single result or None + + # Convert the result to a dictionary if a record is found + return record.to_dict() if record else None + + except Exception as e: + print(f"An error occurred - read: {e}") + return None + + def read_old(self, table_class, query_key, query_value, columns=None): + try: + table = self.get_class_by_tablename(table_class) + stmt = select(table) + stmt = stmt.where(getattr(table, query_key) == query_value) + + if columns: + stmt = stmt.with_only_columns(*(getattr(table, col) for col in columns)) result = self.session.execute(stmt) rows = result.fetchall() column_names = [col.name for col in stmt.columns] @@ -358,78 +396,48 @@ def deleteChapter(self,roleId: int): async def updateContributor(self, contributor: Member, table_class=None): try: - async with self.session() as session: - if table_class == None: + async with self.session() as session: # Ensure self.session is AsyncSession + if table_class is None: table_class = ContributorsDiscord - chapters = lookForRoles(contributor.roles)["chapter_roles"] - gender = lookForRoles(contributor.roles)["gender"] - # Prepare the data to be upserted + # Extract roles + chapters = lookForRoles(contributor["roles"])["chapter_roles"] + gender = lookForRoles(contributor["roles"])["gender"] + + # Prepare data for upsert update_data = { - "discord_id": contributor.id, - "discord_username": contributor.name, + "discord_id": contributor["discord_id"], + "discord_username": contributor["name"], "chapter": chapters[0] if chapters else None, "gender": gender, - "joined_at": contributor.joined_at, + "email": "jaanbaaz@test.com", + "joined_at": contributor["joined_at"].replace(tzinfo=None), # Ensure naive datetime } - stmt = select(ContributorsDiscord).where(ContributorsDiscord.discord_id == contributor.id) + # Check if the record exists + stmt = select(table_class).where(table_class.discord_id == contributor["discord_id"]) result = await session.execute(stmt) existing_record = result.scalars().first() - # existing_record = self.session.query(table_class).filter_by(discord_id=contributor.id).first() - if existing_record: + # Update existing record stmt = ( update(table_class) - .where(table_class.discord_id == contributor.id) - .values(update_data) + .where(table_class.discord_id == contributor["discord_id"]) + .values(**update_data) # Pass the data as keyword arguments ) - self.session.execute(stmt) + await session.execute(stmt) + await session.commit() # Commit changes after executing the update else: + # Insert new record new_record = table_class(**update_data) - self.session.add(new_record) - - # Commit the transaction - self.session.commit() + session.add(new_record) # Add to session + await session.commit() # Commit changes after adding return True except Exception as e: print("Error updating contributor:", e) return False - - - def updateContributors(self, contributors: [Member], table_class): - try: - for contributor in contributors: - chapters = lookForRoles(contributor.roles)["chapter_roles"] - gender = lookForRoles(contributor.roles)["gender"] - update_data = { - "discord_id": contributor.id, - "discord_username": contributor.name, - "chapter": chapters[0] if chapters else None, - "gender": gender, - "joined_at": contributor.joined_at, - } - existing_record = self.session.query(table_class).filter_by(discord_id=contributor.id).first() - - if existing_record: - stmt = ( - update(table_class) - .where(table_class.discord_id == contributor.id) - .values(update_data) - ) - self.session.execute(stmt) - else: - new_record = table_class(**update_data) - self.session.add(new_record) - - self.session.commit() - return True - except Exception as e: - print("Error updating contributors:", e) - return False - - + def deleteContributorDiscord(self, contributorDiscordIds, table_class=None): try: if table_class == None: diff --git a/main.py b/main.py index a5bf1fc..ea4768b 100644 --- a/main.py +++ b/main.py @@ -52,18 +52,22 @@ def __init__( ) async def on_submit(self, interaction: discord.Interaction): - user = interaction.user - # Upsert user data to db - user_data = { - "name": self.name.value, - "discord_id": user.id, - "country": self.country.value - } try: - # response = (supaClient.client.table("contributors_discord") - # .upsert(user_data, on_conflict="discord_id").execute()) + print('inside on submit') + user = interaction.user + # Upsert user data to db + user_data = { + "name": self.name.value, + "discord_id": user.id, + "country": self.country.value, + "roles": user.roles, + "joined_at": user.joined_at + } + except Exception as e: + print('exception e ', e) + try: response = await PostgresClient().updateContributor(user_data) - print("DB updated for user:", response.data[0]["discord_id"]) + print("DB updated for user:", user_data["discord_id"]) except Exception as e: print("Failed to update credentials for user: "+e) @@ -88,7 +92,7 @@ async def hasIntroduced(): while not authentication: print("Not authenticated. Waiting") await asyncio.sleep(15) - authentication = PostgresClient().read("contributors_registration", "discord_id", user.id) + authentication = await PostgresClient().read("contributors_registration", "discord_id", user.id) print("User has authenticated") return True From ced3991a0ab50f378605ec77910b77ad3fd66066 Mon Sep 17 00:00:00 2001 From: karntrehan Date: Thu, 12 Dec 2024 21:44:10 +0530 Subject: [PATCH 12/21] Print token --- cogs/userInteractions.py | 4 +- models_old.py | 1515 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 1517 insertions(+), 2 deletions(-) create mode 100644 models_old.py diff --git a/cogs/userInteractions.py b/cogs/userInteractions.py index 8744f2d..63ea402 100644 --- a/cogs/userInteractions.py +++ b/cogs/userInteractions.py @@ -23,8 +23,8 @@ async def update_contributors(self): print("update_contributors running") contributors = await self.postgres_client.read_all("contributors_registration") print("Contributors in DB: ", len(contributors)) - ##TODO remove return - # return + #TODO remove return + return guild = await self.bot.fetch_guild(os.getenv("SERVER_ID")) contributor_role = guild.get_role(VERIFIED_CONTRIBUTOR_ROLE_ID) for contributor in contributors: diff --git a/models_old.py b/models_old.py new file mode 100644 index 0000000..0175189 --- /dev/null +++ b/models_old.py @@ -0,0 +1,1515 @@ +from datetime import datetime +from sqlalchemy import Column, Integer, String, Text, Float,BigInteger, Boolean, SmallInteger, func, ForeignKey,UniqueConstraint +from sqlalchemy.dialects.postgresql import UUID +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import relationship +from sqlalchemy.types import TypeDecorator, DateTime as SA_DateTime +from datetime import datetime + + +Base = declarative_base() + +class DateTime(TypeDecorator): + impl = SA_DateTime + + def process_bind_param(self, value, dialect): + if isinstance(value, str): + try: + # Convert string to datetime + return datetime.fromisoformat(value) + except ValueError: + # If conversion fails, return None + return None + return value + + def process_result_value(self, value, dialect): + return value + + +class AppComments(Base): + __tablename__ = 'app_comments' + + id = Column(UUID(as_uuid=True), primary_key=True) + updated_at = Column(DateTime, nullable=True) + api_url = Column(Text, nullable=True) + comment_id = Column(BigInteger, nullable=True) + issue_id = Column(BigInteger, unique=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': str(self.id), + 'updated_at': self.updated_at, + 'api_url': self.api_url, + 'comment_id': self.comment_id, + 'issue_id': self.issue_id + } + +class Badges(Base): + __tablename__ = 'badges' + id = Column(UUID(as_uuid=True), primary_key=True) + image = Column(Text, nullable=True) + text = Column(Text, nullable=True) + description = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + user_badges = relationship('UserBadges', back_populates='badge') + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'image': self.image, + 'text': self.text, + 'description': self.description, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + +class CcbpTickets(Base): + __tablename__ = 'ccbp_tickets' + __table_args__ = {'comment': 'A table to store details of CCBP Tickets from various projects'} + + created_at = Column(DateTime, nullable=True) + name = Column(Text, nullable=True) + product = Column(Text, nullable=True) + complexity = Column(Text, nullable=True) + project_category = Column(Text, nullable=True) + project_sub_category = Column(Text, nullable=True) + reqd_skills = Column(Text, nullable=True) + issue_id = Column(BigInteger, unique=True) + api_endpoint_url = Column(Text, unique=True, nullable=True) + url = Column(Text, unique=True, nullable=True) + ticket_points = Column(SmallInteger, nullable=True, comment='How many points the ticket is worth') + index = Column(SmallInteger, unique=True, autoincrement=True) + mentors = Column(Text, nullable=True) + uuid = Column(UUID(as_uuid=True), primary_key=True) + status = Column(Text, nullable=True) + community_label = Column(Boolean, nullable=True, comment='has community label') + organization = Column(Text, nullable=True) + closed_at = Column(DateTime, nullable=True, comment='date-time at which issue was closed') + assignees = Column(Text, nullable=True) + issue_author = Column(Text, nullable=True) + is_assigned = Column(Boolean, nullable=False) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'created_at': self.created_at, + 'name': self.name, + 'product': self.product, + 'complexity': self.complexity, + 'project_category': self.project_category, + 'project_sub_category': self.project_sub_category, + 'reqd_skills': self.reqd_skills, + 'issue_id': self.issue_id, + 'api_endpoint_url': self.api_endpoint_url, + 'url': self.url, + 'ticket_points': self.ticket_points, + 'index': self.index, + 'mentors': self.mentors, + 'uuid': str(self.uuid), + 'status': self.status, + 'community_label': self.community_label, + 'organization': self.organization, + 'closed_at': self.closed_at, + 'assignees': self.assignees, + 'issue_author': self.issue_author, + 'is_assigned': self.is_assigned + } + +class Chapters(Base): + __tablename__ = 'chapters' + + id = Column(UUID(as_uuid=True), primary_key=True) + type = Column(Text, nullable=True) + org_name = Column(Text, unique=True) + primary_organisation = Column(Text, nullable=True, comment='the organisation that the chapter is mapped to') + sessions = Column(Integer, nullable=True) + discord_role_id = Column(BigInteger, unique=True, comment='db id of the corresponding member role in discord server') + created_at = Column(DateTime, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'type': self.type, + 'org_name': self.org_name, + 'primary_organisation': self.primary_organisation, + 'sessions': self.sessions, + 'discord_role_id': self.discord_role_id, + 'created_at': self.created_at + } + + +## + +class ConnectedPrs(Base): + __tablename__ = 'connected_prs' + + id = Column(UUID(as_uuid=True), primary_key=True) + created_at = Column(DateTime, nullable=True) + api_url = Column(Text, nullable=True) + html_url = Column(Text, unique=True, nullable=True) + raised_by = Column(BigInteger, nullable=True) + raised_at = Column(DateTime, nullable=False) + raised_by_username = Column(Text, nullable=False) + status = Column(Text, nullable=True) + is_merged = Column(Boolean, nullable=True) + merged_by = Column(BigInteger, nullable=True) + merged_at = Column(Text, nullable=True) + merged_by_username = Column(Text, nullable=True) + pr_id = Column(BigInteger, nullable=False, comment='github id of the pr') + points = Column(SmallInteger, nullable=False) + ticket_url = Column(Text, nullable=False) + ticket_complexity = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'api_url': self.api_url, + 'html_url': self.html_url, + 'raised_by': self.raised_by, + 'raised_at': self.raised_at, + 'raised_by_username': self.raised_by_username, + 'status': self.status, + 'is_merged': self.is_merged, + 'merged_by': self.merged_by, + 'merged_at': self.merged_at, + 'merged_by_username': self.merged_by_username, + 'pr_id': self.pr_id, + 'points': self.points, + 'ticket_url': self.ticket_url, + 'ticket_complexity': self.ticket_complexity + } + +class ContributorNames(Base): + __tablename__ = 'contributor_names' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + discord_id = Column(BigInteger, nullable=False) + name = Column(Text, nullable=True) + country = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'discord_id': self.discord_id, + 'name': self.name, + 'country': self.country + } + +class ContributorsDiscord(Base): + __tablename__ = 'contributors_discord' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + discord_id = Column(BigInteger, unique=True, nullable=False) + github_id = Column(BigInteger, nullable=True) + github_url = Column(String, nullable=True) + discord_username = Column(String, nullable=True) + joined_at = Column(DateTime, nullable=False) + email = Column(Text, nullable=True) + field_name = Column(Text, nullable=True, name='name') # Adjusted field name + chapter = Column(Text, nullable=True, comment="the chapter they're associated with") + gender = Column(Text, nullable=True) + is_active = Column(Boolean, nullable=False) + country = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'discord_id': self.discord_id, + 'github_id': self.github_id, + 'github_url': self.github_url, + 'discord_username': self.discord_username, + 'joined_at': self.joined_at, + 'email': self.email, + 'name': self.field_name, + 'chapter': self.chapter, + 'gender': self.gender, + 'is_active': self.is_active, + 'country': self.country + } + +class ContributorsRegistration(Base): + __tablename__ = 'contributors_registration' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + discord_id = Column(BigInteger, unique=True, nullable=False) + github_id = Column(BigInteger, unique=True, nullable=False) + github_url = Column(String, nullable=False) + discord_username = Column(String, nullable=True) + joined_at = Column(DateTime, nullable=False) + email = Column(Text, nullable=True) + name = Column(Text, nullable=True) + + point_transactions = relationship('PointTransactions', back_populates='contributor') + + user_activities = relationship('UserActivity', back_populates='contributor') + user_points_mappings = relationship('UserPointsMapping', back_populates='contributor') + + + def __repr__(self): + return f"" + + + def to_dict(self): + return { + 'id': self.id, + 'discord_id': self.discord_id, + 'github_id': self.github_id, + 'github_url': self.github_url, + 'discord_username': self.discord_username, + 'joined_at': self.joined_at, + 'email': self.email, + 'name': self.name + } + +class DiscordChannels(Base): + __tablename__ = 'discord_channels' + + channel_id = Column(BigInteger, primary_key=True) + channel_name = Column(Text, nullable=True) + webhook = Column(Text, nullable=True) + should_notify = Column(Boolean, nullable=False) + + products = relationship('Product', back_populates='channel') + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'channel_id': self.channel_id, + 'channel_name': self.channel_name, + 'webhook': self.webhook, + 'should_notify': self.should_notify + } + +class DiscordEngagement(Base): + __tablename__ = 'discord_engagement' + __table_args__ = {'comment': 'engagement metrics for contributors'} + + id = Column(BigInteger, primary_key=True, autoincrement=True) + created_at = Column(DateTime, nullable=True) + contributor = Column(BigInteger, unique=True, nullable=False) + has_introduced = Column(Boolean, nullable=True) + total_message_count = Column(BigInteger, nullable=True) + total_reaction_count = Column(BigInteger, nullable=True) + converserbadge = Column(Boolean, nullable=True) + apprenticebadge = Column(Boolean, nullable=True) + rockstarbadge = Column(Boolean, nullable=True) + enthusiastbadge = Column(Boolean, nullable=True) + risingstarbadge = Column(Boolean, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'contributor': self.contributor, + 'has_introduced': self.has_introduced, + 'total_message_count': self.total_message_count, + 'total_reaction_count': self.total_reaction_count, + 'converserbadge': self.converserbadge, + 'apprenticebadge': self.apprenticebadge, + 'rockstarbadge': self.rockstarbadge, + 'enthusiastbadge': self.enthusiastbadge, + 'risingstarbadge': self.risingstarbadge + } + +class DmpIssueUpdates(Base): + __tablename__ = 'dmp_issue_updates' + __table_args__ = {'comment': 'Having records of dmp with issue details'} + + created_at = Column(DateTime, nullable=False) + body_text = Column(Text, nullable=True) + comment_link = Column(Text, nullable=True) + comment_id = Column(BigInteger, primary_key=True) + comment_api = Column(String, nullable=True) + comment_updated_at = Column(DateTime, nullable=True) + dmp_id = Column(BigInteger, ForeignKey('dmp_issues.id'), nullable=False) + created_by = Column(Text, nullable=False) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'created_at': self.created_at, + 'body_text': self.body_text, + 'comment_link': self.comment_link, + 'comment_id': self.comment_id, + 'comment_api': self.comment_api, + 'comment_updated_at': self.comment_updated_at, + 'dmp_id': self.dmp_id, + 'created_by': self.created_by + } + + +class DmpIssues(Base): + __tablename__ = 'dmp_issues' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + issue_url = Column(String, nullable=False) + issue_number = Column(BigInteger, nullable=False) + mentor_username = Column(Text, nullable=True) + contributor_username = Column(Text, nullable=True) + title = Column(Text, nullable=False) + org_id = Column(BigInteger, ForeignKey('dmp_orgs.id'), nullable=False) + description = Column(Text, nullable=False) + repo = Column(Text, nullable=False) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'issue_url': self.issue_url, + 'issue_number': self.issue_number, + 'mentor_username': self.mentor_username, + 'contributor_username': self.contributor_username, + 'title': self.title, + 'org_id': self.org_id, + 'description': self.description, + 'repo': self.repo + } + +class DmpOrgs(Base): + __tablename__ = 'dmp_orgs' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + created_at = Column(DateTime, nullable=False) + name = Column(Text, nullable=False) + description = Column(Text, nullable=False) + link = Column(Text, nullable=False) + repo_owner = Column(Text, nullable=False) + + issues = relationship('Issues', backref='organization', lazy='joined') + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'name': self.name, + 'description': self.description, + 'link': self.link, + 'repo_owner': self.repo_owner + } + +class DmpPrUpdates(Base): + __tablename__ = 'dmp_pr_updates' + __table_args__ = {'comment': 'Having PR related records'} + + created_at = Column(DateTime, nullable=False) + pr_id = Column(BigInteger, primary_key=True) + status = Column(String, nullable=False) + title = Column(Text, nullable=False) + pr_updated_at = Column(DateTime, nullable=True) + merged_at = Column(DateTime, nullable=True) + closed_at = Column(DateTime, nullable=True) + dmp_id = Column(BigInteger, ForeignKey('dmp_issues.id'), nullable=False) + link = Column(Text, nullable=False) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'created_at': self.created_at, + 'pr_id': self.pr_id, + 'status': self.status, + 'title': self.title, + 'pr_updated_at': self.pr_updated_at, + 'merged_at': self.merged_at, + 'closed_at': self.closed_at, + 'dmp_id': self.dmp_id, + 'link': self.link + } + +class DmpTickets(Base): + __tablename__ = 'dmp_tickets' + + created_at = Column(DateTime, nullable=True) + name = Column(Text, nullable=True) + product = Column(Text, nullable=True) + complexity = Column(Text, nullable=True) + project_category = Column(Text, nullable=True) + project_sub_category = Column(Text, nullable=True) + reqd_skills = Column(Text, nullable=True) + issue_id = Column(BigInteger, unique=True, nullable=False) + api_endpoint_url = Column(Text, unique=True, nullable=True) + url = Column(Text, unique=True, nullable=True) + ticket_points = Column(Integer, nullable=True, comment='How many points the ticket is worth') + index = Column(Integer, unique=True, autoincrement=True) + mentors = Column(Text, nullable=True) + uuid = Column(UUID(as_uuid=True), primary_key=True) + status = Column(Text, nullable=True) + community_label = Column(Boolean, nullable=True, comment='has community label') + organization = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'created_at': self.created_at, + 'name': self.name, + 'product': self.product, + 'complexity': self.complexity, + 'project_category': self.project_category, + 'project_sub_category': self.project_sub_category, + 'reqd_skills': self.reqd_skills, + 'issue_id': self.issue_id, + 'api_endpoint_url': self.api_endpoint_url, + 'url': self.url, + 'ticket_points': self.ticket_points, + 'index': self.index, + 'mentors': self.mentors, + 'uuid': self.uuid, + 'status': self.status, + 'community_label': self.community_label, + 'organization': self.organization + } + +class DmpWeekUpdates(Base): + __tablename__ = 'dmp_week_updates' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + issue_url = Column(Text, nullable=False) + week = Column(BigInteger, nullable=True) + total_task = Column(BigInteger, nullable=True) + completed_task = Column(BigInteger, nullable=True) + progress = Column(Float, nullable=True) + task_data = Column(Text, nullable=True) + dmp_id = Column(BigInteger, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'issue_url': self.issue_url, + 'week': self.week, + 'total_task': self.total_task, + 'completed_task': self.completed_task, + 'progress': self.progress, + 'task_data': self.task_data, + 'dmp_id': self.dmp_id + } + +class GithubClassroomData(Base): + __tablename__ = 'github_classroom_data' + __table_args__ = {'comment': 'Table for saving the details about github classroom assignment data'} + + id = Column(BigInteger, primary_key=True, autoincrement=True) + created_at = Column(DateTime, nullable=False) + assignment_name = Column(Text, nullable=False) + assignment_url = Column(Text, nullable=False) + assignment_id = Column(Text, nullable=True) + starter_code_url = Column(Text, nullable=False) + github_username = Column(Text, nullable=True) + roster_identifier = Column(Text, nullable=True) + student_repository_name = Column(Text, nullable=True) + student_repository_url = Column(Text, nullable=True) + submission_timestamp = Column(DateTime, nullable=False) + points_awarded = Column(Integer, nullable=True) + points_available = Column(Integer, nullable=True) + c4gt_points = Column(Integer, nullable=True) + discord_id = Column(Text, nullable=True) + updated_at = Column(DateTime, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'assignment_name': self.assignment_name, + 'assignment_url': self.assignment_url, + 'assignment_id': self.assignment_id, + 'starter_code_url': self.starter_code_url, + 'github_username': self.github_username, + 'roster_identifier': self.roster_identifier, + 'student_repository_name': self.student_repository_name, + 'student_repository_url': self.student_repository_url, + 'submission_timestamp': self.submission_timestamp, + 'points_awarded': self.points_awarded, + 'points_available': self.points_available, + 'c4gt_points': self.c4gt_points, + 'discord_id': self.discord_id, + 'updated_at': self.updated_at + } + +class GithubInstallations(Base): + __tablename__ = 'github_installations' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + github_organisation = Column(Text, unique=True, nullable=False) + installation_id = Column(BigInteger, unique=True, nullable=False) + target_type = Column(Text, nullable=True, comment='Type of github entity that installed the app, usually "Organisation"') + github_ids = Column(Text, nullable=True, comment="Identifiers on the github database, prolly won't be used") + permissions_and_events = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + organisation = Column(Text, ForeignKey('community_organisations.name'), nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'github_organisation': self.github_organisation, + 'installation_id': self.installation_id, + 'target_type': self.target_type, + 'github_ids': self.github_ids, + 'permissions_and_events': self.permissions_and_events, + 'created_at': self.created_at, + 'organisation': self.organisation + } +## + +class GithubOrganisationsToOrganisations(Base): + __tablename__ = 'github_organisations_to_organisations' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + github_organisation = Column(Text, nullable=False) + organisation = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True, comment='Creation date of organization ticket') + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'github_organisation': self.github_organisation, + 'organisation': self.organisation, + 'created_at': self.created_at + } + +class IssueContributors(Base): + __tablename__ = 'issue_contributors' + + contributor_id = Column(BigInteger, ForeignKey('contributors_registration.id'), primary_key=True) + issue_id = Column(BigInteger, ForeignKey('issues.id'), primary_key=True) + role_id = Column(BigInteger, ForeignKey('role_master.id'), nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'contributor_id': self.contributor_id, + 'issue_id': self.issue_id, + 'role_id': self.role_id, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + +class IssueMentors(Base): + __tablename__ = 'issue_mentors' + + issue_id = Column(BigInteger, ForeignKey('issues.id'), primary_key=True) + mentor_id = Column(BigInteger, ForeignKey('mentor_details.id'), primary_key=True) + createdat = Column(DateTime, nullable=True) + updatedat = Column(DateTime, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'issue_id': self.issue_id, + 'mentor_id': self.mentor_id, + 'createdat': self.createdat, + 'updatedat': self.updatedat + } + +class Issues(Base): + __tablename__ = 'issues' + + id = Column(BigInteger, primary_key=True) + link = Column(Text, nullable=False) + labels = Column(Text, nullable=True) + complexity = Column(Text, nullable=True) + skills = Column(Text, nullable=True) + technology = Column(Text, nullable=True) + status = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + title = Column(Text, nullable=True) + description = Column(Text, nullable=True) + org_id = Column(BigInteger, ForeignKey('dmp_orgs.id'), nullable=True) + issue_id = Column(BigInteger, nullable=True) + + point_transactions = relationship('PointTransactions', back_populates='issue') + user_activities = relationship('UserActivity', back_populates='issue') + + + + def __repr__(self): + return f"" + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'link': self.link, + 'labels': self.labels, + 'complexity': self.complexity, + 'skills': self.skills, + 'technology': self.technology, + 'status': self.status, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'title': self.title, + 'description': self.description, + 'org_id': self.org_id, + 'issue_id': self.issue_id + } + +class MentorDetails(Base): + __tablename__ = 'mentor_details' + + id = Column(BigInteger, primary_key=True) + name = Column(String(255), nullable=True) + email = Column(String(255), nullable=True) + discord_id = Column(String(255), nullable=True) + discord_username = Column(String(255), nullable=True) + github_id = Column(String(255), nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + point_transactions = relationship('PointTransactions', back_populates='mentor') + user_activities = relationship('UserActivity', back_populates='mentor') + user_points_mappings = relationship('UserPointsMapping', back_populates='mentor') + + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'name': self.name, + 'email': self.email, + 'discord_id': self.discord_id, + 'discord_username': self.discord_username, + 'github_id': self.github_id, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + +class MentorshipProgramSiteStructure(Base): + __tablename__ = 'mentorship_program_site_structure' + + id = Column(BigInteger, primary_key=True) + product_id = Column(BigInteger, ForeignKey('product.id'), nullable=True) + project_id = Column(BigInteger, ForeignKey('mentorship_program_projects.id'), nullable=True) + contributor_id = Column(BigInteger, ForeignKey('mentorship_program_selected_contributors.id'), nullable=True) + website_directory_label = Column(Text, nullable=True) + directory_url = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'product_id': self.product_id, + 'project_id': self.project_id, + 'contributor_id': self.contributor_id, + 'website_directory_label': self.website_directory_label, + 'directory_url': self.directory_url + } + +class MentorshipProgramWebsiteComments(Base): + __tablename__ = 'mentorship_program_website_comments' + + comment_id = Column(BigInteger, primary_key=True) + url = Column(Text, nullable=True) + html_url = Column(Text, nullable=True) + commented_by_username = Column(Text, nullable=True) + commented_by_id = Column(BigInteger, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + body = Column(Text, nullable=True) + pr_id = Column(BigInteger, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'comment_id': self.comment_id, + 'url': self.url, + 'html_url': self.html_url, + 'commented_by_username': self.commented_by_username, + 'commented_by_id': self.commented_by_id, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'body': self.body, + 'pr_id': self.pr_id + } + +class MentorshipProgramWebsiteCommits(Base): + __tablename__ = 'mentorship_program_website_commits' + + node_id = Column(Text, primary_key=True) + url = Column(Text, nullable=True) + html_url = Column(Text, nullable=True) + comment_count = Column(Integer, nullable=True) + date = Column(DateTime, nullable=True) + author_id = Column(BigInteger, nullable=True) + author_username = Column(Text, nullable=True) + author_email = Column(Text, nullable=True) + committer_id = Column(BigInteger, nullable=True) + committer_username = Column(Text, nullable=True) + committer_email = Column(Text, nullable=True) + additions = Column(Integer, nullable=True) + deletions = Column(Integer, nullable=True) + files = Column(Text, nullable=True) + project_folder_name = Column(Text, nullable=True) + pr_id = Column(BigInteger, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'node_id': self.node_id, + 'url': self.url, + 'html_url': self.html_url, + 'comment_count': self.comment_count, + 'date': self.date, + 'author_id': self.author_id, + 'author_username': self.author_username, + 'author_email': self.author_email, + 'committer_id': self.committer_id, + 'committer_username': self.committer_username, + 'committer_email': self.committer_email, + 'additions': self.additions, + 'deletions': self.deletions, + 'files': self.files, + 'project_folder_name': self.project_folder_name, + 'pr_id': self.pr_id + } + +class MentorshipProgramWebsiteHasUpdated(Base): + __tablename__ = 'mentorship_program_website_has_updated' + + id = Column(BigInteger, primary_key=True) + project_id = Column(BigInteger, ForeignKey('mentorship_program_projects.id'), nullable=True) + week1_update_date = Column(DateTime, nullable=True) + week2_update_date = Column(DateTime, nullable=True) + week3_update_date = Column(DateTime, nullable=True) + week4_update_date = Column(DateTime, nullable=True) + week5_update_date = Column(DateTime, nullable=True) + week6_update_date = Column(DateTime, nullable=True) + week7_update_date = Column(DateTime, nullable=True) + week8_update_date = Column(DateTime, nullable=True) + week9_update_date = Column(DateTime, nullable=True) + week1_is_default_text = Column(Boolean, nullable=True) + week2_is_default_text = Column(Boolean, nullable=True) + week3_is_default_text = Column(Boolean, nullable=True) + week4_is_default_text = Column(Boolean, nullable=True) + week5_is_default_text = Column(Boolean, nullable=True) + week6_is_default_text = Column(Boolean, nullable=True) + week7_is_default_text = Column(Boolean, nullable=True) + week8_is_default_text = Column(Boolean, nullable=True) + week9_is_default_text = Column(Boolean, nullable=True) + product = Column(Text, nullable=True) + project_folder = Column(Text, unique=True, nullable=False) + all_links = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'project_id': self.project_id, + 'week1_update_date': self.week1_update_date, + 'week2_update_date': self.week2_update_date, + 'week3_update_date': self.week3_update_date, + 'week4_update_date': self.week4_update_date, + 'week5_update_date': self.week5_update_date, + 'week6_update_date': self.week6_update_date, + 'week7_update_date': self.week7_update_date, + 'week8_update_date': self.week8_update_date, + 'week9_update_date': self.week9_update_date, + 'week1_is_default_text': self.week1_is_default_text, + 'week2_is_default_text': self.week2_is_default_text, + 'week3_is_default_text': self.week3_is_default_text, + 'week4_is_default_text': self.week4_is_default_text, + 'week5_is_default_text': self.week5_is_default_text, + 'week6_is_default_text': self.week6_is_default_text, + 'week7_is_default_text': self.week7_is_default_text, + 'week8_is_default_text': self.week8_is_default_text, + 'week9_is_default_text': self.week9_is_default_text, + 'product': self.product, + 'project_folder': self.project_folder, + 'all_links': self.all_links + } + + +class MentorshipProgramWebsitePullRequest(Base): + __tablename__ = 'mentorship_program_website_pull_request' + + pr_url = Column(Text, nullable=True) + pr_id = Column(BigInteger, primary_key=True) + pr_node_id = Column(Text, unique=True, nullable=True) + html_url = Column(Text, nullable=True) + status = Column(Text, nullable=True) + title = Column(Text, nullable=True) + raised_by_username = Column(Text, nullable=True) + raised_by_id = Column(Integer, nullable=True) + body = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + closed_at = Column(DateTime, nullable=True) + merged_at = Column(DateTime, nullable=True) + assignees = Column(Text, nullable=True) + requested_reviewers = Column(Text, nullable=True) + labels = Column(Text, nullable=True) + review_comments_url = Column(Text, nullable=True) + comments_url = Column(Text, nullable=True) + repository_id = Column(Integer, nullable=True) + repository_owner_name = Column(Text, nullable=True) + repository_owner_id = Column(Integer, nullable=True) + repository_url = Column(Text, nullable=True) + merged = Column(Boolean, nullable=True) + number_of_commits = Column(Integer, nullable=True) + number_of_comments = Column(Integer, nullable=True) + lines_of_code_added = Column(Integer, nullable=True) + lines_of_code_removed = Column(Integer, nullable=True) + number_of_files_changed = Column(Integer, nullable=True) + merged_by_id = Column(BigInteger, nullable=True) + merged_by_username = Column(Text, nullable=True) + linked_ticket = Column(Text, nullable=True) + project_name = Column(Text, nullable=True) + project_folder_label = Column(Text, nullable=True) + week_number = Column(SmallInteger, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'pr_url': self.pr_url, + 'pr_id': self.pr_id, + 'pr_node_id': self.pr_node_id, + 'html_url': self.html_url, + 'status': self.status, + 'title': self.title, + 'raised_by_username': self.raised_by_username, + 'raised_by_id': self.raised_by_id, + 'body': self.body, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'closed_at': self.closed_at, + 'merged_at': self.merged_at, + 'assignees': self.assignees, + 'requested_reviewers': self.requested_reviewers, + 'labels': self.labels, + 'review_comments_url': self.review_comments_url, + 'comments_url': self.comments_url, + 'repository_id': self.repository_id, + 'repository_owner_name': self.repository_owner_name, + 'repository_owner_id': self.repository_owner_id, + 'repository_url': self.repository_url, + 'merged': self.merged, + 'number_of_commits': self.number_of_commits, + 'number_of_comments': self.number_of_comments, + 'lines_of_code_added': self.lines_of_code_added, + 'lines_of_code_removed': self.lines_of_code_removed, + 'number_of_files_changed': self.number_of_files_changed, + 'merged_by_id': self.merged_by_id, + 'merged_by_username': self.merged_by_username, + 'linked_ticket': self.linked_ticket, + 'project_name': self.project_name, + 'project_folder_label': self.project_folder_label, + 'week_number': self.week_number + } + +class MentorshipWebsiteContributorProject(Base): + __tablename__ = 'mentorship_website_contributor_project' + + project_folder = Column(Text, primary_key=True) + contributor = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'project_folder': self.project_folder, + 'contributor': self.contributor + } + +class PointSystem(Base): + __tablename__ = 'point_system' + + id = Column(BigInteger, primary_key=True) + complexity = Column(Text, nullable=False) + points = Column(SmallInteger, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'complexity': self.complexity, + 'points': self.points + } + +class PointTransactions(Base): + __tablename__ = 'point_transactions' + + id = Column(BigInteger, primary_key=True) + user_id = Column(BigInteger, ForeignKey('contributors_registration.id'), nullable=True) + issue_id = Column(BigInteger, ForeignKey('issues.id'), nullable=False) + point = Column(Integer, nullable=True) + type = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + mentor_id = Column(BigInteger, ForeignKey('mentor_details.id'), nullable=True) + + + contributor = relationship('ContributorsRegistration', back_populates='point_transactions') + issue = relationship('Issues', back_populates='point_transactions') + mentor = relationship('MentorDetails', back_populates='point_transactions') + + def __repr__(self): + return f"" + + + def to_dict(self): + return { + 'id': self.id, + 'user_id': self.user_id, + 'issue_id': self.issue_id, + 'point': self.point, + 'type': self.type, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'mentor_id': self.mentor_id + } + +class PointsMapping(Base): + __tablename__ = 'points_mapping' + + id = Column(BigInteger, primary_key=True) + role = Column(String(50), nullable=False) + complexity = Column(String(50), nullable=False) + points = Column(Integer, nullable=False) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'role': self.role, + 'complexity': self.complexity, + 'points': self.points, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + + +class PrHistory(Base): + __tablename__ = 'pr_history' + + id = Column(String(36), primary_key=True) # UUID field + created_at = Column(DateTime, nullable=True) + api_url = Column(Text, nullable=True) + html_url = Column(Text, unique=True, nullable=True) + raised_by = Column(BigInteger, nullable=True) + raised_at = Column(DateTime, nullable=False) + raised_by_username = Column(Text, nullable=False) + status = Column(Text, nullable=True) + is_merged = Column(Boolean, nullable=True) + merged_by = Column(BigInteger, nullable=True) + merged_at = Column(Text, nullable=True) + merged_by_username = Column(Text, nullable=True) + pr_id = Column(BigInteger, nullable=False) + points = Column(SmallInteger, nullable=False) + ticket_url = Column(Text, nullable=False) + ticket_complexity = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'api_url': self.api_url, + 'html_url': self.html_url, + 'raised_by': self.raised_by, + 'raised_at': self.raised_at, + 'raised_by_username': self.raised_by_username, + 'status': self.status, + 'is_merged': self.is_merged, + 'merged_by': self.merged_by, + 'merged_at': self.merged_at, + 'merged_by_username': self.merged_by_username, + 'pr_id': self.pr_id, + 'points': self.points, + 'ticket_url': self.ticket_url, + 'ticket_complexity': self.ticket_complexity + } + +class PrStaging(Base): + __tablename__ = 'pr_staging' + + id = Column(String(36), primary_key=True) # UUID field + created_at = Column(DateTime, nullable=True) + api_url = Column(Text, nullable=True) + html_url = Column(Text, unique=True, nullable=True) + raised_by = Column(BigInteger, nullable=True) + raised_at = Column(DateTime, nullable=False) + raised_by_username = Column(Text, nullable=False) + status = Column(Text, nullable=True) + is_merged = Column(Boolean, nullable=True) + merged_by = Column(BigInteger, nullable=True) + merged_at = Column(Text, nullable=True) + merged_by_username = Column(Text, nullable=True) + pr_id = Column(BigInteger, nullable=False) + points = Column(SmallInteger, nullable=False) + ticket_url = Column(Text, nullable=False) + ticket_complexity = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'api_url': self.api_url, + 'html_url': self.html_url, + 'raised_by': self.raised_by, + 'raised_at': self.raised_at, + 'raised_by_username': self.raised_by_username, + 'status': self.status, + 'is_merged': self.is_merged, + 'merged_by': self.merged_by, + 'merged_at': self.merged_at, + 'merged_by_username': self.merged_by_username, + 'pr_id': self.pr_id, + 'points': self.points, + 'ticket_url': self.ticket_url, + 'ticket_complexity': self.ticket_complexity + } + +class Product(Base): + __tablename__ = 'product' + + id = Column(BigInteger, primary_key=True) # Auto field + name = Column(Text, unique=True, nullable=False) + description = Column(Text, nullable=True) + wiki_url = Column(Text, nullable=True) + channel_id = Column(BigInteger, ForeignKey('discord_channels.channel_id'), nullable=True) # Assumes 'DiscordChannels' model + + channel = relationship('DiscordChannels', back_populates='products') + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'name': self.name, + 'description': self.description, + 'wiki_url': self.wiki_url, + 'channel_id': self.channel_id + } + +class RoleMaster(Base): + __tablename__ = 'role_master' + + id = Column(BigInteger, primary_key=True) # Auto field + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=True) + role = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'role': self.role + } + +class TicketComments(Base): + __tablename__ = 'ticket_comments' + + id = Column(BigInteger, primary_key=True) + url = Column(Text, nullable=True) + html_url = Column(Text, nullable=True) + issue_url = Column(Text, nullable=True) + node_id = Column(Text, nullable=True) + commented_by = Column(Text, nullable=True) + commented_by_id = Column(BigInteger, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + content = Column(Text, nullable=True) + reactions_url = Column(Text, nullable=True) + ticket_url = Column(Text, nullable=False) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'url': self.url, + 'html_url': self.html_url, + 'issue_url': self.issue_url, + 'node_id': self.node_id, + 'commented_by': self.commented_by, + 'commented_by_id': self.commented_by_id, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'content': self.content, + 'reactions_url': self.reactions_url, + 'ticket_url': self.ticket_url + } + +class UnlistedTickets(Base): + __tablename__ = 'unlisted_tickets' + + created_at = Column(DateTime, nullable=True) + name = Column(Text, nullable=True) + product = Column(Text, nullable=True) + complexity = Column(Text, nullable=True) + project_category = Column(Text, nullable=True) + project_sub_category = Column(Text, nullable=True) + reqd_skills = Column(Text, nullable=True) + issue_id = Column(BigInteger, unique=True, nullable=False) + api_endpoint_url = Column(Text, unique=True, nullable=True) + url = Column(Text, unique=True, nullable=True) + ticket_points = Column(SmallInteger, nullable=True) + index = Column(SmallInteger, unique=True, nullable=False) + mentors = Column(Text, nullable=True) + uuid = Column(String(36), primary_key=True) # UUID field + status = Column(Text, nullable=True) + organization = Column(Text, nullable=True) + + __table_args__ = (UniqueConstraint('uuid', 'issue_id'),) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'created_at': self.created_at, + 'name': self.name, + 'product': self.product, + 'complexity': self.complexity, + 'project_category': self.project_category, + 'project_sub_category': self.project_sub_category, + 'reqd_skills': self.reqd_skills, + 'issue_id': self.issue_id, + 'api_endpoint_url': self.api_endpoint_url, + 'url': self.url, + 'ticket_points': self.ticket_points, + 'index': self.index, + 'mentors': self.mentors, + 'uuid': self.uuid, + 'status': self.status, + 'organization': self.organization + } + +class UnstructuredDiscordData(Base): + __tablename__ = 'unstructured_discord_data' + + text = Column(Text, nullable=True) + author = Column(BigInteger, nullable=True) + channel = Column(BigInteger, nullable=True) + channel_name = Column(Text, nullable=True) + uuid = Column(String(36), primary_key=True) # UUID field + author_name = Column(Text, nullable=True) + author_roles = Column(Text, nullable=True) + sent_at = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'text': self.text, + 'author': self.author, + 'channel': self.channel, + 'channel_name': self.channel_name, + 'uuid': self.uuid, + 'author_name': self.author_name, + 'author_roles': self.author_roles, + 'sent_at': self.sent_at + } + +class UserActivity(Base): + __tablename__ = 'user_activity' + + id = Column(UUID(as_uuid=True), primary_key=True) + contributor_id = Column(BigInteger, ForeignKey('contributors_registration.id'), nullable=False) # Assumes 'ContributorsRegistration' model + issue_id = Column(BigInteger, ForeignKey('issues.id'), nullable=False) # Assumes 'Issues' model + activity = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + mentor_id = Column(BigInteger, ForeignKey('mentor_details.id'), nullable=True) # Assumes 'MentorDetails' model + + contributor = relationship('ContributorsRegistration', back_populates='user_activities') + issue = relationship('Issues', back_populates='user_activities') + mentor = relationship('MentorDetails', back_populates='user_activities') + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'contributor_id': self.contributor_id, + 'issue_id': self.issue_id, + 'activity': self.activity, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'mentor_id': self.mentor_id + } + +class UserBadges(Base): + __tablename__ = 'user_badges' + id = Column(UUID(as_uuid=True), primary_key=True) + user_id = Column(BigInteger, ForeignKey('users.id'), nullable=False) # Assumes 'Users' model + badge_id = Column(BigInteger, ForeignKey('badges.id'), nullable=False) # Assumes 'Badges' model + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + user = relationship('Users', back_populates='user_badges') + badge = relationship('Badges', back_populates='user_badges') + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'user_id': self.user_id, + 'badge_id': self.badge_id, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + +class UserCertificates(Base): + __tablename__ = 'user_certificates' + id = Column(UUID(as_uuid=True), primary_key=True) + user_id = Column(BigInteger, ForeignKey('users.id'), nullable=False) # Assumes 'Users' model + certificate_link = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + user = relationship('Users', back_populates='user_certificates') + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'user_id': self.user_id, + 'certificate_link': self.certificate_link, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + +class UserPointsMapping(Base): + __tablename__ = 'user_points_mapping' + id = Column(UUID(as_uuid=True), primary_key=True) + contributor_id = Column(BigInteger, ForeignKey('contributors_registration.id'), nullable=True) # Assumes 'ContributorsRegistration' model + points = Column(Integer, nullable=False) + level = Column(String(50), nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + mentor_id = Column(BigInteger, ForeignKey('mentor_details.id'), nullable=True) # Assumes 'MentorDetails' model + + contributor = relationship('ContributorsRegistration', back_populates='user_points_mappings') + mentor = relationship('MentorDetails', back_populates='user_points_mappings') + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'contributor_id': self.contributor_id, + 'points': self.points, + 'level': self.level, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'mentor_id': self.mentor_id + } + +class Users(Base): + __tablename__ = 'users' + + id = Column(BigInteger, primary_key=True) # Assumes id is the primary key + name = Column(Text, nullable=True) + discord = Column(Text, unique=True, nullable=True) + github = Column(Text, nullable=True) + points = Column(Integer, nullable=True) + level = Column(Text, nullable=True) + created_at = Column(DateTime, nullable=True) + updated_at = Column(DateTime, nullable=True) + + user_badges = relationship('UserBadges', back_populates='user') + user_certificates = relationship('UserCertificates', back_populates='user') + + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'name': self.name, + 'discord': self.discord, + 'github': self.github, + 'points': self.points, + 'level': self.level, + 'created_at': self.created_at, + 'updated_at': self.updated_at + } + +class VcLogs(Base): + __tablename__ = 'vc_logs' + + id = Column(BigInteger, primary_key=True) # Auto field + created_at = Column(DateTime, default=func.now(), nullable=False) + discord_id = Column(BigInteger, nullable=True) + discord_name = Column(Text, nullable=True) + option = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'id': self.id, + 'created_at': self.created_at, + 'discord_id': self.discord_id, + 'discord_name': self.discord_name, + 'option': self.option + } + +class GitHubProfileData(Base): + __tablename__ = 'github_profile_data' + + github_username = Column(String, primary_key=True) + discord_id = Column(BigInteger, nullable=False) + classroom_points = Column(Integer, nullable=False, default=0) + prs_raised = Column(Integer, nullable=False, default=0) + prs_reviewed = Column(Integer, nullable=False, default=0) + prs_merged = Column(Integer, nullable=False, default=0) + dpg_points = Column(Integer, nullable=False, default=0) + milestone = Column(Integer, nullable=False, default=0) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'github_username': self.github_username, + 'discord_id': self.discord_id, + 'classroom_points': self.classroom_points, + 'prs_raised': self.prs_raised, + 'prs_reviewed': self.prs_reviewed, + 'prs_merged': self.prs_merged, + 'dpg_points': self.dpg_points, + 'milestone': self.milestone, + } + + + +class Leaderboard(Base): + __tablename__ = 'leaderboard' + + discord_id = Column(BigInteger, primary_key=True, autoincrement=False) + github_id = Column(BigInteger, nullable=False) + github_url = Column(Text, nullable=False) + apprentice_badge = Column(Boolean, nullable=True) + converser_badge = Column(Boolean, nullable=False, default=False) + rockstar_badge = Column(Boolean, nullable=False, default=False) + enthusiast_badge = Column(Boolean, nullable=False, default=False) + rising_star_badge = Column(Boolean, nullable=False, default=False) + github_x_discord_badge = Column(Boolean, nullable=False, default=False) + points = Column(Integer, nullable=False, default=0) + bronze_badge = Column(Boolean, nullable=False, default=False) + silver_badge = Column(Boolean, nullable=False, default=False) + gold_badge = Column(Boolean, nullable=False, default=False) + ruby_badge = Column(Boolean, nullable=False, default=False) + diamond_badge = Column(Boolean, nullable=False, default=False) + certificate_link = Column(Text, nullable=True) + + def __repr__(self): + return f"" + + def to_dict(self): + return { + 'discord_id': self.discord_id, + 'github_id': self.github_id, + 'github_url': self.github_url, + 'apprentice_badge': self.apprentice_badge, + 'converser_badge': self.converser_badge, + 'rockstar_badge': self.rockstar_badge, + 'enthusiast_badge': self.enthusiast_badge, + 'rising_star_badge': self.rising_star_badge, + 'github_x_discord_badge': self.github_x_discord_badge, + 'points': self.points, + 'bronze_badge': self.bronze_badge, + 'silver_badge': self.silver_badge, + 'gold_badge': self.gold_badge, + 'ruby_badge': self.ruby_badge, + 'diamond_badge': self.diamond_badge, + 'certificate_link': self.certificate_link + } \ No newline at end of file From 8b7aaf4572c139fccb1a258e697796c436395af9 Mon Sep 17 00:00:00 2001 From: karntrehan Date: Thu, 12 Dec 2024 21:48:08 +0530 Subject: [PATCH 13/21] Print token --- cogs/userInteractions.py | 2 -- main.py | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cogs/userInteractions.py b/cogs/userInteractions.py index 63ea402..270c0b6 100644 --- a/cogs/userInteractions.py +++ b/cogs/userInteractions.py @@ -23,8 +23,6 @@ async def update_contributors(self): print("update_contributors running") contributors = await self.postgres_client.read_all("contributors_registration") print("Contributors in DB: ", len(contributors)) - #TODO remove return - return guild = await self.bot.fetch_guild(os.getenv("SERVER_ID")) contributor_role = guild.get_role(VERIFIED_CONTRIBUTOR_ROLE_ID) for contributor in contributors: diff --git a/main.py b/main.py index ea4768b..0786d15 100644 --- a/main.py +++ b/main.py @@ -183,6 +183,7 @@ async def load(): async def main(): async with client: await load() + print(os.getenv("TOKEN")) await client.start(os.getenv("TOKEN")) From 23c444ebbbf416e9af65439364610db72d690a63 Mon Sep 17 00:00:00 2001 From: karntrehan Date: Thu, 12 Dec 2024 21:54:21 +0530 Subject: [PATCH 14/21] Adding logs to token --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 0786d15..f2fb5cd 100644 --- a/main.py +++ b/main.py @@ -183,7 +183,7 @@ async def load(): async def main(): async with client: await load() - print(os.getenv("TOKEN")) + print("Token is: "+os.getenv("TOKEN")) await client.start(os.getenv("TOKEN")) From 92e9af321e22f6a89b5482de5c463ec407242418 Mon Sep 17 00:00:00 2001 From: Karun Agarwal <113603846+singhalkarun@users.noreply.github.com> Date: Fri, 13 Dec 2024 10:48:01 +0530 Subject: [PATCH 15/21] add dev branch in the build worflow --- .github/workflows/build-and-push.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index 6674227..9bfa9e0 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -4,6 +4,7 @@ on: push: branches: - main + - dev workflow_dispatch: env: From 0fd046489e082420c488cf6c9dcf6fcc189d936b Mon Sep 17 00:00:00 2001 From: jaanbaaz Date: Fri, 13 Dec 2024 12:45:20 +0530 Subject: [PATCH 16/21] is_active added to contributors discord --- helpers/supabaseClient.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/helpers/supabaseClient.py b/helpers/supabaseClient.py index d51971f..33fc4f4 100644 --- a/helpers/supabaseClient.py +++ b/helpers/supabaseClient.py @@ -410,7 +410,8 @@ async def updateContributor(self, contributor: Member, table_class=None): "discord_username": contributor["name"], "chapter": chapters[0] if chapters else None, "gender": gender, - "email": "jaanbaaz@test.com", + "email": contributor["email"], + "is_active": True, "joined_at": contributor["joined_at"].replace(tzinfo=None), # Ensure naive datetime } From 74486e97da3bf04f370e06ae61717eb1e9496232 Mon Sep 17 00:00:00 2001 From: jaanbaaz Date: Fri, 13 Dec 2024 17:39:42 +0530 Subject: [PATCH 17/21] is_active added --- helpers/supabaseClient.py | 2 +- main.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/helpers/supabaseClient.py b/helpers/supabaseClient.py index 33fc4f4..085074b 100644 --- a/helpers/supabaseClient.py +++ b/helpers/supabaseClient.py @@ -411,7 +411,7 @@ async def updateContributor(self, contributor: Member, table_class=None): "chapter": chapters[0] if chapters else None, "gender": gender, "email": contributor["email"], - "is_active": True, + "is_active": contributor["email"], "joined_at": contributor["joined_at"].replace(tzinfo=None), # Ensure naive datetime } diff --git a/main.py b/main.py index f2fb5cd..42cc86d 100644 --- a/main.py +++ b/main.py @@ -61,7 +61,8 @@ async def on_submit(self, interaction: discord.Interaction): "discord_id": user.id, "country": self.country.value, "roles": user.roles, - "joined_at": user.joined_at + "joined_at": user.joined_at, + "is_active": True, } except Exception as e: print('exception e ', e) From 163e7d7fb7c423d51bed2125944603adcce33197 Mon Sep 17 00:00:00 2001 From: jaanbaaz Date: Fri, 13 Dec 2024 17:53:49 +0530 Subject: [PATCH 18/21] registration bug fix --- helpers/supabaseClient.py | 2 +- main.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/helpers/supabaseClient.py b/helpers/supabaseClient.py index 085074b..098e8e3 100644 --- a/helpers/supabaseClient.py +++ b/helpers/supabaseClient.py @@ -411,7 +411,7 @@ async def updateContributor(self, contributor: Member, table_class=None): "chapter": chapters[0] if chapters else None, "gender": gender, "email": contributor["email"], - "is_active": contributor["email"], + "is_active": contributor["is_active"], "joined_at": contributor["joined_at"].replace(tzinfo=None), # Ensure naive datetime } diff --git a/main.py b/main.py index 42cc86d..263a3f6 100644 --- a/main.py +++ b/main.py @@ -63,6 +63,7 @@ async def on_submit(self, interaction: discord.Interaction): "roles": user.roles, "joined_at": user.joined_at, "is_active": True, + "email":"" } except Exception as e: print('exception e ', e) From 3dfb1e828fad79732089b0b098ffbc7d71c6dca0 Mon Sep 17 00:00:00 2001 From: jaanbaaz Date: Sun, 15 Dec 2024 23:34:44 +0530 Subject: [PATCH 19/21] email check added --- helpers/supabaseClient.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/helpers/supabaseClient.py b/helpers/supabaseClient.py index 098e8e3..fea1cda 100644 --- a/helpers/supabaseClient.py +++ b/helpers/supabaseClient.py @@ -410,7 +410,7 @@ async def updateContributor(self, contributor: Member, table_class=None): "discord_username": contributor["name"], "chapter": chapters[0] if chapters else None, "gender": gender, - "email": contributor["email"], + "email": contributor["email"] if contributor["email"] else "", "is_active": contributor["is_active"], "joined_at": contributor["joined_at"].replace(tzinfo=None), # Ensure naive datetime } @@ -420,6 +420,8 @@ async def updateContributor(self, contributor: Member, table_class=None): result = await session.execute(stmt) existing_record = result.scalars().first() + print('existing record ', existing_record) + if existing_record: # Update existing record stmt = ( From bc255cc553b4fb9628bb84a5801b30cd2d82a07f Mon Sep 17 00:00:00 2001 From: jaanbaaz Date: Tue, 24 Dec 2024 10:22:27 +0530 Subject: [PATCH 20/21] discord_username and name fix --- helpers/supabaseClient.py | 3 ++- main.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/helpers/supabaseClient.py b/helpers/supabaseClient.py index fea1cda..f1e5925 100644 --- a/helpers/supabaseClient.py +++ b/helpers/supabaseClient.py @@ -407,7 +407,8 @@ async def updateContributor(self, contributor: Member, table_class=None): # Prepare data for upsert update_data = { "discord_id": contributor["discord_id"], - "discord_username": contributor["name"], + "discord_username": contributor["discord_username"], + "field_name": contributor["name"], "chapter": chapters[0] if chapters else None, "gender": gender, "email": contributor["email"] if contributor["email"] else "", diff --git a/main.py b/main.py index 263a3f6..ee857b4 100644 --- a/main.py +++ b/main.py @@ -63,6 +63,7 @@ async def on_submit(self, interaction: discord.Interaction): "roles": user.roles, "joined_at": user.joined_at, "is_active": True, + "discord_username": user.display_name, "email":"" } except Exception as e: From 4a0f5deb66643ac7a7c6077d9576737fabedb76d Mon Sep 17 00:00:00 2001 From: jaanbaaz Date: Tue, 24 Dec 2024 11:04:39 +0530 Subject: [PATCH 21/21] log added --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index ee857b4..20da47b 100644 --- a/main.py +++ b/main.py @@ -66,6 +66,7 @@ async def on_submit(self, interaction: discord.Interaction): "discord_username": user.display_name, "email":"" } + print('user data before updating contributor is ', user_data) except Exception as e: print('exception e ', e) try: