Dockerize.

Signed-off-by: Abdulkadir Furkan Şanlı <me@abdulocra.cy>
This commit is contained in:
Abdulkadir Furkan Şanlı 2024-01-21 10:38:05 +01:00
parent 3d4483539b
commit 2c82286bfe
Signed by: afk
SSH Key Fingerprint: SHA256:s1hULLl4YWdqU501MUfGe1CAG/m1pf9Cs6vFsqeTNHk
5 changed files with 54 additions and 18 deletions

11
Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM python:3
ENV PYTHONUNBUFFERED=1
WORKDIR /usr/src/app
COPY main.py requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python", "./main.py"]

6
compose.yml Normal file
View File

@ -0,0 +1,6 @@
services:
parkerbot:
build: .
env_file: .env
volumes:
- ./data:/data

View File

@ -1,5 +1,5 @@
# Path of sqlite3 file to use.
DB_PATH = ""
# Path for persistent app data.
DATA_DIR = "/data"
# Matrix homeserver URL.
MATRIX_SERVER = ""
# Matrix room to monitor.
@ -9,6 +9,6 @@ MATRIX_USER = ""
# Password for bot's Matrix user.
MATRIX_PASSWORD = ""
# Title of the playlists created, date of the week's Monday will be appended.
PLAYLIST_TITLE = ""
YOUTUBE_PLAYLIST_TITLE = ""
# YouTube API client secret json path.
YOUTUBE_CLIENT_SECRETS_FILE = os.getenv("YOUTUBE_CLIENT_SECRETS_FILE")
YOUTUBE_CLIENT_SECRETS_FILE = ""

46
main.py
View File

@ -5,22 +5,27 @@ import asyncio
import os
import pickle
import re
import signal
import sqlite3
import sys
from datetime import datetime, timedelta
from dotenv import load_dotenv
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from nio import AsyncClient, ClientConfig, RoomMessageText, SyncResponse
from nio import AsyncClient, RoomMessageText, SyncResponse
DATA_DIR = os.getenv("DATA_DIR", "./")
DB_PATH = os.path.join(DATA_DIR, "parkerbot.sqlite3")
TOKEN_PATH = os.path.join(DATA_DIR, "sync_token")
PICKLE_PATH = os.path.join(DATA_DIR, "token.pickle")
load_dotenv()
DB_PATH = os.getenv("DB_PATH")
MATRIX_SERVER = os.getenv("MATRIX_SERVER")
MATRIX_ROOM = os.getenv("MATRIX_ROOM")
MATRIX_USER = os.getenv("MATRIX_USER")
MATRIX_PASSWORD = os.getenv("MATRIX_PASSWORD")
PLAYLIST_TITLE = os.getenv("PLAYLIST_TITLE")
YOUTUBE_PLAYLIST_TITLE = os.getenv("YOUTUBE_PLAYLIST_TITLE")
YOUTUBE_CLIENT_SECRETS_FILE = os.getenv("YOUTUBE_CLIENT_SECRETS_FILE")
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
@ -61,9 +66,9 @@ def define_tables():
def get_authenticated_service():
"""Get an authentivated YouTube service."""
credentials = None
# The file token.pickle stores the user's access and refresh tokens.
if os.path.exists("token.pickle"):
with open("token.pickle", "rb") as token:
# Stores the user's access and refresh tokens.
if os.path.exists(PICKLE_PATH):
with open(PICKLE_PATH, "rb") as token:
credentials = pickle.load(token)
# If there are no valid credentials available, let the user log in.
@ -77,7 +82,7 @@ def get_authenticated_service():
)
credentials = flow.run_local_server(port=8080)
# Save the credentials for the next run
with open("token.pickle", "wb") as token:
with open(PICKLE_PATH, "wb") as token:
pickle.dump(credentials, token)
return build("youtube", "v3", credentials=credentials)
@ -111,7 +116,7 @@ def make_playlist(youtube, title):
def get_or_make_playlist(youtube, monday_date):
"""Get ID of playlist for given Monday's week, make if doesn't exist."""
playlist_title = f"{PLAYLIST_TITLE} {monday_date.strftime('%Y-%m-%d')}"
playlist_title = f"{YOUTUBE_PLAYLIST_TITLE} {monday_date.strftime('%Y-%m-%d')}"
# Check if playlist exists in the database
cursor.execute(
@ -216,20 +221,23 @@ async def message_callback(client, room, event):
async def sync_callback(response):
"""Save Matrix sync token."""
# Save the sync token to a file or handle it as needed
with open("sync_token", "w") as f:
with open(TOKEN_PATH, "w") as f:
f.write(response.next_batch)
def load_sync_token():
"""Get an existing Matrix sync token if it exists."""
try:
with open("sync_token", "r") as file:
with open(TOKEN_PATH, "r") as file:
return file.read().strip()
except FileNotFoundError:
return None
async def get_client():
"""Returns configured and logged in Matrix client."""
client = AsyncClient(MATRIX_SERVER, MATRIX_USER)
client.add_event_callback(
lambda room, event: message_callback(client, room, event), RoomMessageText
@ -240,12 +248,24 @@ async def get_client():
return client
def sigterm_handler(signum, frame):
"""Gracefully stop syncing on SIGTERM."""
asyncio.get_event_loop().stop()
async def main():
"""Get DB and Matrix client ready, and start syncing."""
define_tables()
client = await get_client()
signal.signal(signal.SIGTERM, sigterm_handler)
sync_token = load_sync_token()
await client.sync_forever(30000, full_state=True, since=sync_token)
try:
await client.sync_forever(30000, full_state=True, since=sync_token)
finally:
conn.close()
await client.logout()
sys.exit()
if __name__ == "__main__":
asyncio.run(main())

View File

@ -1,4 +1,3 @@
matrix-nio
google-auth-oauthlib
google-api-python-client
python-dotenv