Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(github): add github integration #371

Closed
wants to merge 1 commit into from
Closed
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
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ jobs:
- name: Test with pytest
id: test
env:
CI_EVENT_ID: ${{ github.event.number || github.sha }}
GITHUB_PYTEST: "true"
DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_TEST_BOT_TOKEN }}
DISCORD_WEBHOOK: ${{ secrets.DISCORD_TEST_BOT_WEBHOOK }}
DISCORD_GITHUB_STATUS_CHANNEL_ID: ${{ vars.DISCORD_GITHUB_STATUS_CHANNEL_ID }}
DISCORD_REDDIT_CHANNEL_ID: ${{ vars.DISCORD_REDDIT_CHANNEL_ID }}
DISCORD_SPONSORS_CHANNEL_ID: ${{ vars.DISCORD_SPONSORS_CHANNEL_ID }}
GRAVATAR_EMAIL: ${{ secrets.GRAVATAR_EMAIL }}
PRAW_CLIENT_ID: ${{ secrets.REDDIT_CLIENT_ID }}
PRAW_CLIENT_SECRET: ${{ secrets.REDDIT_CLIENT_SECRET }}
Expand Down
23 changes: 16 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,44 @@
ARG DAILY_TASKS=true
ARG DAILY_RELEASES=true
ARG DAILY_TASKS_UTC_HOUR=12
ARG DISCORD_GITHUB_STATUS_CHANNEL_ID
ARG DISCORD_REDDIT_CHANNEL_ID
ARG DISCORD_SPONSORS_CHANNEL_ID

# Secret config
ARG DISCORD_BOT_TOKEN
ARG DAILY_CHANNEL_ID
ARG DISCORD_BOT_TOKEN

Check warning on line 26 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "DISCORD_BOT_TOKEN") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 26 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "DISCORD_BOT_TOKEN") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 26 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "DISCORD_BOT_TOKEN") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ARG DISCORD_CLIENT_ID
ARG DISCORD_CLIENT_SECRET

Check warning on line 28 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "DISCORD_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 28 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "DISCORD_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ARG DISCORD_REDIRECT_URI
ARG GITHUB_WEBHOOK_SECRET_KEY

Check warning on line 30 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "GITHUB_WEBHOOK_SECRET_KEY") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 30 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "GITHUB_WEBHOOK_SECRET_KEY") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 30 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "GITHUB_WEBHOOK_SECRET_KEY") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ARG GRAVATAR_EMAIL
ARG IGDB_CLIENT_ID
ARG IGDB_CLIENT_SECRET

Check warning on line 33 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "IGDB_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 33 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "IGDB_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 33 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "IGDB_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ARG PRAW_CLIENT_ID
ARG PRAW_CLIENT_SECRET

Check warning on line 35 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "PRAW_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 35 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "PRAW_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 35 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "PRAW_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ARG PRAW_SUBREDDIT
ARG DISCORD_WEBHOOK
ARG GRAVATAR_EMAIL
ARG REDIRECT_URI

# Environment variables
ENV DAILY_TASKS=$DAILY_TASKS
ENV DAILY_RELEASES=$DAILY_RELEASES
ENV DAILY_CHANNEL_ID=$DAILY_CHANNEL_ID
ENV DAILY_TASKS_UTC_HOUR=$DAILY_TASKS_UTC_HOUR
ENV DISCORD_BOT_TOKEN=$DISCORD_BOT_TOKEN

Check warning on line 43 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "DISCORD_BOT_TOKEN") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 43 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "DISCORD_BOT_TOKEN") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 43 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "DISCORD_BOT_TOKEN") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV DISCORD_CLIENT_ID=$DISCORD_CLIENT_ID
ENV DISCORD_CLIENT_SECRET=$DISCORD_CLIENT_SECRET

Check warning on line 45 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "DISCORD_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 45 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "DISCORD_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV DISCORD_GITHUB_STATUS_CHANNEL_ID=$DISCORD_GITHUB_STATUS_CHANNEL_ID
ENV DISCORD_REDDIT_CHANNEL_ID=$DISCORD_REDDIT_CHANNEL_ID
ENV DISCORD_REDIRECT_URI=$DISCORD_REDIRECT_URI
ENV DISCORD_SPONSORS_CHANNEL_ID=$DISCORD_SPONSORS_CHANNEL_ID
ENV GITHUB_WEBHOOK_SECRET_KEY=$GITHUB_WEBHOOK_SECRET_KEY

Check warning on line 50 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "GITHUB_WEBHOOK_SECRET_KEY") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 50 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "GITHUB_WEBHOOK_SECRET_KEY") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 50 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "GITHUB_WEBHOOK_SECRET_KEY") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV GRAVATAR_EMAIL=$GRAVATAR_EMAIL
ENV IGDB_CLIENT_ID=$IGDB_CLIENT_ID
ENV IGDB_CLIENT_SECRET=$IGDB_CLIENT_SECRET

Check warning on line 53 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "IGDB_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 53 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "IGDB_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 53 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "IGDB_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV PRAW_CLIENT_ID=$PRAW_CLIENT_ID
ENV PRAW_CLIENT_SECRET=$PRAW_CLIENT_SECRET

Check warning on line 55 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "PRAW_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 55 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "PRAW_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 55 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "PRAW_CLIENT_SECRET") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV PRAW_SUBREDDIT=$PRAW_SUBREDDIT
ENV DISCORD_WEBHOOK=$DISCORD_WEBHOOK

Check warning on line 57 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$DISCORD_WEBHOOK' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/

Check warning on line 57 in Dockerfile

View workflow job for this annotation

GitHub Actions / Docker

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$DISCORD_WEBHOOK' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/
ENV GRAVATAR_EMAIL=$GRAVATAR_EMAIL
ENV REDIRECT_URI=$REDIRECT_URI

SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# install dependencies
Expand All @@ -69,7 +78,7 @@
set -e

# replace the version in the code
sed -i "s/version = '0.0.0'/version = '${BUILD_VERSION}'/g" src/common.py
sed -i "s/version = '0.0.0'/version = '${BUILD_VERSION}'/g" src/common/common.py

# install dependencies
python -m pip install --no-cache-dir -r requirements.txt
Expand Down
52 changes: 30 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
[![GitHub Workflow Status (CI)](https://img.shields.io/github/actions/workflow/status/lizardbyte/support-bot/ci.yml.svg?branch=master&label=CI%20build&logo=github&style=for-the-badge)](https://github.com/LizardByte/support-bot/actions/workflows/ci.yml?query=branch%3Amaster)
[![Codecov](https://img.shields.io/codecov/c/gh/LizardByte/support-bot.svg?token=900Q93P1DE&style=for-the-badge&logo=codecov&label=codecov)](https://app.codecov.io/gh/LizardByte/support-bot)

Support bot written in python to help manage LizardByte communities. The current focus is discord and reddit, but other
platforms such as GitHub discussions/issues could be added.
Support bot written in python to help manage LizardByte communities. The current focus is Discord and Reddit, but other
platforms such as GitHub discussions/issues might be added in the future.


## Overview
Expand All @@ -28,23 +28,25 @@ platforms such as GitHub discussions/issues could be added.
:exclamation: if using Docker these can be arguments.
:warning: Never publicly expose your tokens, secrets, or ids.

| variable | required | default | description |
|-------------------------|----------|------------------------------------------------------|---------------------------------------------------------------|
| DISCORD_BOT_TOKEN | True | `None` | Token from Bot page on discord developer portal. |
| DAILY_TASKS | False | `true` | Daily tasks on or off. |
| DAILY_RELEASES | False | `true` | Send a message for each game released on this day in history. |
| DAILY_CHANNEL_ID | False | `None` | Required if daily_tasks is enabled. |
| DAILY_TASKS_UTC_HOUR | False | `12` | The hour to run daily tasks. |
| GRAVATAR_EMAIL | False | `None` | Gravatar email address for bot avatar. |
| IGDB_CLIENT_ID | False | `None` | Required if daily_releases is enabled. |
| IGDB_CLIENT_SECRET | False | `None` | Required if daily_releases is enabled. |
| SUPPORT_COMMANDS_REPO | False | `https://github.com/LizardByte/support-bot-commands` | Repository for support commands. |
| SUPPORT_COMMANDS_BRANCH | False | `master` | Branch for support commands. |

* Running bot:
* `python -m src`
* Invite bot to server:
* `https://discord.com/api/oauth2/authorize?client_id=<the client id of the bot>&permissions=8&scope=bot%20applications.commands`
| variable | required | default | description |
|----------------------------------|----------|------------------------------------------------------|---------------------------------------------------------------|
| DISCORD_BOT_TOKEN | True | `None` | Token from Bot page on discord developer portal. |
| DISCORD_CLIENT_ID | True | `None` | Discord OAuth2 client id. |
| 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_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. |
| GITHUB_WEBHOOK_SECRET_KEY | True | `None` | A secret value to ensure webhooks are from trusted sources. |
| DAILY_TASKS | False | `true` | Daily tasks on or off. |
| DAILY_RELEASES | False | `true` | Send a message for each game released on this day in history. |
| DAILY_CHANNEL_ID | False | `None` | Required if daily_tasks is enabled. |
| DAILY_TASKS_UTC_HOUR | False | `12` | The hour to run daily tasks. |
| GRAVATAR_EMAIL | False | `None` | Gravatar email address for bot avatar. |
| IGDB_CLIENT_ID | False | `None` | Required if daily_releases is enabled. |
| IGDB_CLIENT_SECRET | False | `None` | Required if daily_releases is enabled. |
| SUPPORT_COMMANDS_REPO | False | `https://github.com/LizardByte/support-bot-commands` | Repository for support commands. |
| SUPPORT_COMMANDS_BRANCH | False | `master` | Branch for support commands. |


### Reddit
Expand All @@ -62,7 +64,13 @@ platforms such as GitHub discussions/issues could be added.
| DISCORD_WEBHOOK | False | None | URL of webhook to send discord notifications to |
| GRAVATAR_EMAIL | False | None | Gravatar email address to get avatar from |
| REDDIT_USERNAME | True | None | Reddit username |
* | REDDIT_PASSWORD | True | None | Reddit password |
| REDDIT_PASSWORD | True | None | Reddit password |

### Start

* Running bot:
* `python -m src`
```bash
python -m src
```

* Invite bot to server:
* `https://discord.com/api/oauth2/authorize?client_id=<the client id of the bot>&permissions=8&scope=bot%20applications.commands`
1 change: 0 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
betamax==0.9.0
betamax-serializers==0.2.1
pytest==8.3.3
pytest-asyncio==0.24.0
pytest-cov==6.0.0
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
cryptography==43.0.3
Flask==3.0.3
GitPython==3.1.43
igdb-api-v4==0.3.3
Expand All @@ -7,3 +8,4 @@ praw==7.8.1
py-cord==2.6.1
python-dotenv==1.0.1
requests==2.32.3
requests-oauthlib==2.0.0
33 changes: 13 additions & 20 deletions src/__main__.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,33 @@
# standard imports
import os
import time

# development imports
from dotenv import load_dotenv
load_dotenv(override=False) # environment secrets take priority over .env file

# local imports
if True: # hack for flake8
from src.discord import bot as d_bot
from src import keep_alive
from src.reddit import bot as r_bot
# local imports, import after env loaded
from src.common import globals # noqa: E402
from src.discord import bot as d_bot # noqa: E402
from src.common import webapp # noqa: E402
from src.reddit import bot as r_bot # noqa: E402

Check warning on line 12 in src/__main__.py

View check run for this annotation

Codecov / codecov/patch

src/__main__.py#L9-L12

Added lines #L9 - L12 were not covered by tests


def main():
# to run in replit
try:
os.environ['REPL_SLUG']
except KeyError:
pass # not running in replit
else:
keep_alive.keep_alive() # Start the web server
webapp.start() # Start the web server

Check warning on line 16 in src/__main__.py

View check run for this annotation

Codecov / codecov/patch

src/__main__.py#L16

Added line #L16 was not covered by tests

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

Check warning on line 19 in src/__main__.py

View check run for this annotation

Codecov / codecov/patch

src/__main__.py#L18-L19

Added lines #L18 - L19 were not covered by tests

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

Check warning on line 22 in src/__main__.py

View check run for this annotation

Codecov / codecov/patch

src/__main__.py#L21-L22

Added lines #L21 - L22 were not covered by tests

try:
while discord_bot.bot_thread.is_alive() or reddit_bot.bot_thread.is_alive():
while globals.DISCORD_BOT.bot_thread.is_alive() or globals.REDDIT_BOT.bot_thread.is_alive():

Check warning on line 25 in src/__main__.py

View check run for this annotation

Codecov / codecov/patch

src/__main__.py#L25

Added line #L25 was not covered by tests
time.sleep(0.5)
except KeyboardInterrupt:
print("Keyboard Interrupt Detected")
discord_bot.stop()
reddit_bot.stop()
globals.DISCORD_BOT.stop()
globals.REDDIT_BOT.stop()

Check warning on line 30 in src/__main__.py

View check run for this annotation

Codecov / codecov/patch

src/__main__.py#L29-L30

Added lines #L29 - L30 were not covered by tests


if __name__ == '__main__': # pragma: no cover
Expand Down
Empty file added src/common/__init__.py
Empty file.
File renamed without changes.
69 changes: 69 additions & 0 deletions src/common/crypto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# standard imports
import os

# lib imports
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
from datetime import datetime, timedelta, UTC

# local imports
from src.common import common

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


def check_expiration(cert_path: str) -> int:
with open(cert_path, "rb") as cert_file:
cert_data = cert_file.read()
cert = x509.load_pem_x509_certificate(cert_data, default_backend())
expiry_date = cert.not_valid_after_utc
return (expiry_date - datetime.now(UTC)).days


def generate_certificate():
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=4096,
)
subject = issuer = x509.Name([
x509.NameAttribute(x509.NameOID.COMMON_NAME, u"localhost"),
])
cert = x509.CertificateBuilder().subject_name(
subject
).issuer_name(
issuer
).public_key(
private_key.public_key()
).serial_number(
x509.random_serial_number()
).not_valid_before(
datetime.now(UTC)
).not_valid_after(
datetime.now(UTC) + timedelta(days=365)
).sign(private_key, hashes.SHA256())

with open(KEY_FILE, "wb") as f:
f.write(private_key.private_bytes(
encoding=Encoding.PEM,
format=PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=NoEncryption(),
))

with open(CERT_FILE, "wb") as f:
f.write(cert.public_bytes(Encoding.PEM))


def initialize_certificate() -> tuple[str, str]:
print("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.")
if cert_expires_in >= 90:
return CERT_FILE, KEY_FILE
print("Generating new certificate")
generate_certificate()
return CERT_FILE, KEY_FILE

Check warning on line 69 in src/common/crypto.py

View check run for this annotation

Codecov / codecov/patch

src/common/crypto.py#L67-L69

Added lines #L67 - L69 were not covered by tests
22 changes: 22 additions & 0 deletions src/common/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# standard imports
import shelve
import threading


class Database:
def __init__(self, db_path):
self.db_path = db_path
self.lock = threading.Lock()

def __enter__(self):
self.lock.acquire()
self.db = shelve.open(self.db_path, writeback=True)
return self.db

def __exit__(self, exc_type, exc_val, exc_tb):
self.sync()
self.db.close()
self.lock.release()

def sync(self):
self.db.sync()
2 changes: 2 additions & 0 deletions src/common/globals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DISCORD_BOT = None
REDDIT_BOT = None
73 changes: 73 additions & 0 deletions src/common/sponsors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# standard imports
import os
from typing import Union

# lib imports
import requests


tier_map = {
't4-sponsors': 15,
't3-sponsors': 10,
't2-sponsors': 5,
't1-sponsors': 3,
}


def get_github_sponsors() -> Union[dict, False]:
"""
Get list of GitHub sponsors.

Returns
-------
Union[dict, False]
JSON response containing the list of sponsors. False if an error occurred.
"""
token = os.getenv("GITHUB_TOKEN")
org_name = os.getenv("GITHUB_ORG_NAME", "LizardByte")

Check warning on line 27 in src/common/sponsors.py

View check run for this annotation

Codecov / codecov/patch

src/common/sponsors.py#L26-L27

Added lines #L26 - L27 were not covered by tests

graphql_url = "https://api.github.com/graphql"
headers = {

Check warning on line 30 in src/common/sponsors.py

View check run for this annotation

Codecov / codecov/patch

src/common/sponsors.py#L29-L30

Added lines #L29 - L30 were not covered by tests
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
query = """

Check warning on line 34 in src/common/sponsors.py

View check run for this annotation

Codecov / codecov/patch

src/common/sponsors.py#L34

Added line #L34 was not covered by tests
query {
organization(login: "%s") {
sponsorshipsAsMaintainer(first: 100) {
edges {
node {
sponsorEntity {
... on User {
login
name
avatarUrl
url
}
... on Organization {
login
name
avatarUrl
url
}
}
tier {
name
monthlyPriceInDollars
}
}
}
}
}
}
""" % org_name

response = requests.post(graphql_url, json={'query': query}, headers=headers)
data = response.json()

Check warning on line 66 in src/common/sponsors.py

View check run for this annotation

Codecov / codecov/patch

src/common/sponsors.py#L65-L66

Added lines #L65 - L66 were not covered by tests

if 'errors' in data:
print(data['errors'])
print('::error::An error occurred while fetching sponsors.')
return False

Check warning on line 71 in src/common/sponsors.py

View check run for this annotation

Codecov / codecov/patch

src/common/sponsors.py#L68-L71

Added lines #L68 - L71 were not covered by tests

return data

Check warning on line 73 in src/common/sponsors.py

View check run for this annotation

Codecov / codecov/patch

src/common/sponsors.py#L73

Added line #L73 was not covered by tests
Loading