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 76ca419..681c510 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() @@ -40,20 +40,20 @@ async def updateServerData(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_active("contributors_discord") + contributorsGithub = PostgresClient().read_all("contributors_registration") + contributorsDiscord = PostgresClient().read_all_active("contributors_discord") ## Give contributor role contributorIds = [ @@ -71,7 +71,7 @@ async def updateServerData(self, ctx): print(count) - SupabaseClient().updateContributors(guild.members) + PostgresClient().updateContributors(guild.members) recordedMembers = [ contributor["discord_id"] for contributor in contributorsDiscord ] @@ -79,14 +79,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") - SupabaseClient().invalidateContributorDiscord(membersWhoLeft) + PostgresClient().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 = 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 7f5fff9..e6f0ffc 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: @@ -155,7 +159,274 @@ def deleteContributorDiscord(self, contributorDiscordIds): 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 + + + + def read_all_active(self, table): + if table == "contributors_discord": + table = ContributorsDiscord + data = self.session.query(table).where(table.is_active == True).all() + return self.convert_dict(data) + def invalidateContributorDiscord(self, contributorDiscordIds): - table = "contributors_discord" - for id in contributorDiscordIds: - self.client.table(table).update({ 'is_active': 'false' }).eq('discord_id', id).execute() + table = ContributorsDiscord + for id in contributorDiscordIds: + try: + stmt = (update(table).where(table.discord_id == id).values({ 'is_active': 'false' })) + self.session.execute(stmt) + self.session.commit() + except Exception as e: + print(e) + self.session.rollback() + continue + diff --git a/main.py b/main.py index 7f38e29..4a87290 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() @@ -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, @@ -163,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