Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ platforms such as GitHub discussions/issues might be added in the future.
| DISCORD_CLIENT_SECRET | True | `None` | Discord OAuth2 client secret. |
| DISCORD_GITHUB_STATUS_CHANNEL_ID | True | `None` | Channel ID to send GitHub status updates to. |
| DISCORD_LEVEL_UP_CHANNEL_ID | False | `None` | Channel ID to send user level up messages to. |
| DISCORD_LOG_CHANNEL_ID | False | `None` | Channel ID to send bot log messages to. This should be a private channel. |
| DISCORD_REDDIT_CHANNEL_ID | True | `None` | Channel ID to send Reddit post updates to. |
| DISCORD_REDIRECT_URI | False | `https://localhost:8080/discord/callback` | The redirect uri for OAuth2. Must be publicly accessible. |
| DISCORD_SPONSORS_CHANNEL_ID | True | `None` | Channel ID to send sponsorship updates to. |
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ classifiers = [
]

dependencies = [
"colorlog==6.10.1",
"cryptography==46.0.5",
"Flask==3.1.2",
"Flask-WTF==1.2.2",
Expand Down
1 change: 1 addition & 0 deletions sample.env
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ SUPPORT_COMMANDS_BRANCH=master
# Secret settings
DISCORD_BOT_TOKEN=
DISCORD_LEVEL_UP_CHANNEL_ID=
DISCORD_LOG_CHANNEL_ID=
GRAVATAR_EMAIL=

# discord/github oauth2
Expand Down
13 changes: 12 additions & 1 deletion src/__main__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# standard imports
import logging
import time

# development imports
Expand All @@ -7,25 +8,35 @@

# local imports, import after env loaded
from src.common import globals # noqa: E402
from src.common import logging_config # noqa: E402
from src.discord_bot import bot as d_bot # noqa: E402
from src.common import webapp # noqa: E402
from src.reddit_bot import bot as r_bot # noqa: E402

# Get logger for this module
logger = logging.getLogger(__name__)


def main():
# Initialize logging system
discord_handler = logging_config.setup_logging()

webapp.start() # Start the web server

globals.DISCORD_BOT = d_bot.Bot()
globals.DISCORD_BOT.start_threaded() # Start the discord bot

# Configure Discord handler after bot is initialized
discord_handler.setup(globals.DISCORD_BOT)

globals.REDDIT_BOT = r_bot.Bot()
globals.REDDIT_BOT.start_threaded() # Start the reddit bot

try:
while globals.DISCORD_BOT.bot_thread.is_alive() or globals.REDDIT_BOT.bot_thread.is_alive():
time.sleep(0.5)
except KeyboardInterrupt:
print("Keyboard Interrupt Detected")
logger.info("Keyboard Interrupt Detected")
globals.DISCORD_BOT.stop()
globals.REDDIT_BOT.stop()

Expand Down
11 changes: 8 additions & 3 deletions src/common/crypto.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# standard imports
import logging
import os

# lib imports
Expand All @@ -12,6 +13,9 @@
# local imports
from src.common import common

# Get logger for this module
logger = logging.getLogger(__name__)

CERT_FILE = os.path.join(common.data_dir, "cert.pem")
KEY_FILE = os.path.join(common.data_dir, "key.pem")

Expand Down Expand Up @@ -58,12 +62,13 @@ def generate_certificate():


def initialize_certificate() -> tuple[str, str]:
print("Initializing SSL certificate")
logger.info("Initializing SSL certificate")
if os.path.exists(CERT_FILE) and os.path.exists(KEY_FILE):
cert_expires_in = check_expiration(CERT_FILE)
print(f"Certificate expires in {cert_expires_in} days.")
logger.info(f"Certificate expires in {cert_expires_in} days.")
if cert_expires_in >= 90:
return CERT_FILE, KEY_FILE
print("Generating new certificate")

logger.info("Generating new certificate")
generate_certificate()
return CERT_FILE, KEY_FILE
36 changes: 19 additions & 17 deletions src/common/database.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# standard imports
import logging
import os
from pathlib import Path
import shelve
import threading
import traceback
from typing import Union

# lib imports
Expand All @@ -15,6 +15,9 @@
# local imports
from src.common.common import data_dir

# Get logger for this module
logger = logging.getLogger(__name__)

# Constants
DATA_REPO_LOCK = threading.Lock()
GIT_ENABLED = True # disable to pause pushing to git, useful for heavy db operations
Expand Down Expand Up @@ -52,7 +55,7 @@ def __init__(self, db_name: str, db_dir: Union[str, Path] = data_dir, use_git: b

if not os.path.exists(self.db_dir):
# Clone repo if it doesn't exist
print(f"Cloning repository {self.repo_url} to {self.db_dir}")
logger.info(f"Cloning repository {self.repo_url} to {self.db_dir}")
try:
# Try cloning with the specified branch
self.repo = git.Repo.clone_from(clone_url, self.db_dir, branch=self.repo_branch)
Expand All @@ -61,7 +64,7 @@ def __init__(self, db_name: str, db_dir: Union[str, Path] = data_dir, use_git: b
except git.exc.GitCommandError as e:
# Check if the error is due to branch not found
if "Remote branch" in str(e) and "not found in upstream origin" in str(e):
print(f"Branch '{self.repo_branch}' not found in remote. Creating a new empty branch.")
logger.info(f"Branch '{self.repo_branch}' not found in remote. Creating a new empty branch.")
# Clone with default branch first
self.repo = git.Repo.clone_from(clone_url, self.db_dir)
# Configure the repo
Expand Down Expand Up @@ -99,9 +102,9 @@ def __init__(self, db_name: str, db_dir: Union[str, Path] = data_dir, use_git: b
# Push the new branch to remote
try:
self.repo.git.push('--set-upstream', 'origin', self.repo_branch)
print(f"Created and pushed new empty branch '{self.repo_branch}'")
logger.info(f"Created and pushed new empty branch '{self.repo_branch}'")
except git.exc.GitCommandError as e:
print(f"Failed to push new branch: {str(e)}")
logger.error(f"Failed to push new branch: {str(e)}")
# Continue anyway - we might not have push permissions
else:
# Re-raise if it's a different error
Expand Down Expand Up @@ -135,9 +138,10 @@ def __init__(self, db_name: str, db_dir: Union[str, Path] = data_dir, use_git: b
self.repo.git.add(gitkeep_path)
self.repo.git.commit('-m', f"Initialize empty branch '{self.repo_branch}'")
self.repo.git.push('--set-upstream', 'origin', self.repo_branch)
print(f"Created and pushed new empty branch '{self.repo_branch}'")
logger.info(f"Created and pushed new empty branch '{self.repo_branch}'")
except git.exc.GitCommandError:
print(f"Failed to work with branch '{self.repo_branch}'. Using current branch instead.")
logger.warning(
f"Failed to work with branch '{self.repo_branch}'. Using current branch instead.")
else:
# Branch exists locally, make sure it's checked out
self.repo.git.checkout(self.repo_branch)
Expand Down Expand Up @@ -181,7 +185,7 @@ def _configure_repo(self):
origin = self.repo.remote('origin')
origin.set_url(new_url)
except git.exc.GitCommandError as e:
print(f"Failed to update remote URL: {str(e)}")
logger.error(f"Failed to update remote URL: {str(e)}")
# Continue anyway, might work with stored credentials

def _check_for_migration(self):
Expand All @@ -191,7 +195,7 @@ def _check_for_migration(self):
json_exists = os.path.exists(self.json_path)

if shelve_exists and not json_exists:
print(f"Migrating database from shelve to TinyDB: {self.shelve_path}")
logger.info(f"Migrating database from shelve to TinyDB: {self.shelve_path}")
self._migrate_from_shelve()

def _migrate_from_shelve(self):
Expand Down Expand Up @@ -265,10 +269,9 @@ def _migrate_from_shelve(self):
migration_db.storage.flush()
migration_db.close()

print(f"Migration completed successfully: {self.json_path}")
logger.info(f"Migration completed successfully: {self.json_path}")
except Exception as e:
print(f"Migration failed: {str(e)}")
traceback.print_exc()
logger.error(f"Migration failed: {str(e)}")

def __enter__(self):
self.lock.acquire()
Expand Down Expand Up @@ -315,21 +318,20 @@ def sync(self):
# Commit all changes at once with a general message
commit_message = "Update database files"
self.repo.git.commit('-m', commit_message)
print("Committed changes to git data repository")
logger.info("Committed changes to git data repository")

# Push to remote with credentials
try:
# Ensure we're using the credentials for push
protocol, repo_path = self.repo_url.split("://", 1)
push_url = f"{protocol}://{self.git_user_name}:{self.git_token}@{repo_path}"
self.repo.git.push(push_url, self.repo_branch)
print("Pushed changes to remote git data repository")
logger.info("Pushed changes to remote git data repository")
except git.exc.GitCommandError as e:
print(f"Failed to push changes: {str(e)}")
logger.error(f"Failed to push changes: {str(e)}")

except Exception as e:
print(f"Git operation failed: {str(e)}")
traceback.print_exc()
logger.error(f"Git operation failed: {str(e)}")
finally:
# Ensure database is ready for next use
if self.tinydb is None:
Expand Down
Loading