From 2ed89fecbc976f15ac128eb75bb877dd3d0c2940 Mon Sep 17 00:00:00 2001 From: Jo Eskil Date: Thu, 13 Nov 2025 23:43:39 +0100 Subject: [PATCH] Cleaned project directory and added new development plan for simplified stack --- .gitignore | 1 - Dockerfile | 17 ---- PROGRESS_REPORT.md | 38 --------- Project Outline.md | 8 -- README.md | 30 ------- USAGE.md | 41 ---------- __pycache__/auth.cpython-313.pyc | Bin 3824 -> 0 bytes __pycache__/chat_listeners.cpython-313.pyc | Bin 3706 -> 0 bytes __pycache__/database.cpython-313.pyc | Bin 1906 -> 0 bytes __pycache__/main.cpython-313.pyc | Bin 5615 -> 0 bytes auth.py | 87 --------------------- chat_listeners.py | 65 --------------- dashboard.html | 22 ------ database.py | 35 --------- docker-compose.yml | 30 ------- index.html | 21 ----- login.html | 14 ---- main.py | 67 ---------------- multichat.db | Bin 20480 -> 0 bytes requirements.txt | 37 --------- uvicorn.log | 0 21 files changed, 513 deletions(-) delete mode 100644 .gitignore delete mode 100644 Dockerfile delete mode 100644 PROGRESS_REPORT.md delete mode 100644 Project Outline.md delete mode 100644 README.md delete mode 100644 USAGE.md delete mode 100644 __pycache__/auth.cpython-313.pyc delete mode 100644 __pycache__/chat_listeners.cpython-313.pyc delete mode 100644 __pycache__/database.cpython-313.pyc delete mode 100644 __pycache__/main.cpython-313.pyc delete mode 100644 auth.py delete mode 100644 chat_listeners.py delete mode 100644 dashboard.html delete mode 100644 database.py delete mode 100644 docker-compose.yml delete mode 100644 index.html delete mode 100644 login.html delete mode 100644 main.py delete mode 100644 multichat.db delete mode 100644 requirements.txt delete mode 100644 uvicorn.log diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 7cc280d..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.gemini/ diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 696187f..0000000 --- a/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -# Use an official Python runtime as a parent image -FROM python:3.9-slim - -# Set the working directory in the container -WORKDIR /app - -# Copy the requirements file into the container -COPY requirements.txt . - -# Install any needed packages specified in requirements.txt -RUN pip install --no-cache-dir -r requirements.txt - -# Copy the rest of the application code into the container -COPY . . - -# Command to run the application -CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "-w", "4", "-b", "0.0.0.0:8000", "main:app"] diff --git a/PROGRESS_REPORT.md b/PROGRESS_REPORT.md deleted file mode 100644 index ba7cc24..0000000 --- a/PROGRESS_REPORT.md +++ /dev/null @@ -1,38 +0,0 @@ -# Project Progress Report - -This document summarizes the key steps and decisions made during the initial setup and planning of the MultiChat Overlay project. - -## 1. Initial Setup & Environment Assessment -- **Environment Assessed:** The initial container environment was assessed, and `python3` and `git` were confirmed to be installed. -- **Project Directory:** The project directory was created at `/home/joe/MultiChatOverlay`. -- **Collaboration:** The directory permissions were configured to allow for collaboration by setting the group to `collaborators` and permissions to `775`. -- **Git Repository:** The project was cloned from the Gitea repository at `https://gitea.ramforth.net/ramforth/MultiChatOverlay`. - -## 2. Initial Development (Single-User Model) -- **Virtual Environment:** A Python virtual environment was created at `/home/joe/MultiChatOverlay/venv`. -- **Dependencies:** Initial Python dependencies (`fastapi`, `uvicorn`, `websockets`, `pytchat`, `twitchio`) were installed. -- **Basic Framework:** A basic FastAPI application was created with a WebSocket endpoint and a simple HTML overlay. -- **Chat Listeners:** Placeholder chat listener modules were created for YouTube and Twitch. - -## 3. Pivot to a Multi-User Service -- **New Requirement:** The project direction was updated to create a multi-user, web-based service where users can log in with their streaming accounts. -- **Revised Development Plan:** A new development plan (`DEVELOPMENT_PLAN.md` v3) was created to reflect this change. The new plan focuses on user authentication, a database, and dynamic management of chat listeners. -- **Plan Synced:** The revised development plan was pushed to the Gitea repository. - -## 4. Implementation of the Multi-User Framework -- **Database:** A SQLite database was initialized, and a `users` table schema was defined using SQLAlchemy. -- **Authentication:** A placeholder Twitch OAuth2 implementation was created in `auth.py`. -- **Login Frontend:** A `login.html` page and a corresponding FastAPI endpoint were created. -- **Session Management:** Basic session management using signed cookies was implemented to keep users logged in. -- **Dashboard:** A protected `/dashboard` endpoint and a simple `dashboard.html` page were created. -- **Usage Guide:** A `USAGE.md` file was created to document the login process for end-users. -- **Code Synced:** All changes for the initial multi-user framework were pushed to the Gitea repository. - -## 5. Pivot to a Production-Ready Docker-Based Framework -- **New Requirement:** The need for a more robust, scalable, and easily accessible framework was identified. -- **Revised Plan:** A new plan was created to use Docker Compose to manage the application services. -- **Docker Compose Plan:** - - A `web` service for the FastAPI application. - - A `db` service using PostgreSQL. - - The use of `gunicorn` with `uvicorn` workers for the production server. - - The use of Docker volumes to allow for easy collaboration on frontend files. diff --git a/Project Outline.md b/Project Outline.md deleted file mode 100644 index 30b4c81..0000000 --- a/Project Outline.md +++ /dev/null @@ -1,8 +0,0 @@ -There is a need for a chat overlay in live streaming circles that allows streamers to read chat from several of the primary platforms. Twitch and Youtube at the very least. - -The idea: -Use self hosted web server to present the user integration with account linking and setup instructions. Let the end user log in with Youtube and Twitch. Have preset templates for html overlay for OBS use. - -Must have functions to highlight single messages, preferably from a dockable html browser dock in OBS studio. - -This is a specific extension of project: /home/joe/Cloud9/Documents/Obisdian/projects/youtube-chat-webhook-v2 diff --git a/README.md b/README.md deleted file mode 100644 index 263bfd7..0000000 --- a/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Multi-Platform Chat Overlay - -A self-hosted tool to aggregate chat from multiple streaming platforms (YouTube, Twitch) and display it in a customizable OBS overlay. This project also provides a suite of tools for both the streamer (host) and their moderators to manage the chat. - -## Core Features - -* **Combined Chat:** Aggregates chat from YouTube and Twitch into a single feed. -* **OBS Overlay:** A customizable web-based overlay to display the chat in your stream. -* **Host Control Panel:** A dockable OBS panel for the streamer to: - * Highlight important messages to feature them on the overlay. - * View a queue of messages tagged by moderators. - * Dismiss queued messages after they have been addressed. -* **Moderator Panel:** A separate, secure web page for moderators to: - * View the combined chat feed. - * "Tag" or "Queue" important messages for the host's attention. - -## Technology Stack - -* **Backend:** Python 3.9+ with FastAPI and WebSockets. -* **Frontend:** HTML5, CSS3, and vanilla JavaScript. -* **Chat Libraries:** `pytchat` for YouTube and `TwitchIO` for Twitch. - -## Getting Started - -_(Instructions will be added here once the initial version is complete)_ - -1. Clone the repository. -2. Install Python dependencies. -3. Run the backend server. -4. Add the frontend components to OBS as Browser Sources/Docks. diff --git a/USAGE.md b/USAGE.md deleted file mode 100644 index 6347d2c..0000000 --- a/USAGE.md +++ /dev/null @@ -1,41 +0,0 @@ -# MultiChat Overlay Usage Guide - -This guide explains how to log in to the MultiChat Overlay service and connect your streaming accounts to generate a personalized chat overlay. - -## 1. Logging In - -To use the MultiChat Overlay, you first need to log in with your streaming platform account. - -1. **Access the Login Page:** Open your web browser and navigate to the service's login page (e.g., `http://localhost:8000/login`). -2. **Choose Your Platform:** On the login page, you will see options to log in with different streaming platforms. -3. **Authorize MultiChat Overlay:** - * Click on the "Login with Twitch" button. - * You will be redirected to Twitch's authorization page. Review the permissions requested by MultiChat Overlay and click "Authorize" to grant access. - * After successful authorization, you will be redirected back to the MultiChat Overlay dashboard. - -## 2. Connecting Services - -Currently, only Twitch is supported for connection. YouTube integration will be added in a future update. - -### Connecting Twitch - -Once you have logged in with your Twitch account, your Twitch channel will automatically be connected. You can verify this on your dashboard. - -## 3. Your Personalized Overlay - -After logging in and connecting your services, you will find your unique overlay URL on the dashboard. - -1. **Copy Overlay URL:** On the dashboard, locate and copy the provided "Overlay URL". This URL is unique to your account. -2. **Add to OBS (or other streaming software):** - * In OBS Studio, add a new "Browser Source". - * Paste your copied Overlay URL into the "URL" field of the Browser Source properties. - * Adjust the width and height of the browser source to match your desired overlay size. - * Click "OK". - -Your chat overlay should now appear in your streaming software, displaying messages from your connected Twitch channel. - -## 4. Future Integrations (Coming Soon) - -* **YouTube Integration:** Connect your YouTube channel to aggregate chat from both platforms. -* **Customization Options:** Personalize the look and feel of your chat overlay directly from the dashboard. -* **Moderator & Host Panels:** Access dedicated panels for advanced moderation and stream management. diff --git a/__pycache__/auth.cpython-313.pyc b/__pycache__/auth.cpython-313.pyc deleted file mode 100644 index 6878527c82be647524445aa8bad25f09c4bab1ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3824 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 tn~}*zHVbU`7S;2`nOP0fc!_>i>zGmZbmy diff --git a/__pycache__/chat_listeners.cpython-313.pyc b/__pycache__/chat_listeners.cpython-313.pyc deleted file mode 100644 index ddc0905c1358eddf9f795d21ff00f96cea5e7619..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3706 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 VTQ@hP15LU6{sme);bZ^+ diff --git a/__pycache__/main.cpython-313.pyc b/__pycache__/main.cpython-313.pyc deleted file mode 100644 index 1c6c0e5832159e35fd7c6db1225383081f2331df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5615 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 - - - MultiChat Overlay Dashboard - - -

Welcome to your Dashboard

-

This is your personalized dashboard. You can manage your connected accounts and configure your overlay here.

- -

Your Overlay URL

-

Use this URL as a browser source in your streaming software:

-

-
-    
-
-
diff --git a/database.py b/database.py
deleted file mode 100644
index cbf4b39..0000000
--- a/database.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import os
-from sqlalchemy import create_engine, Column, Integer, String
-from sqlalchemy.ext.declarative import declarative_base
-from sqlalchemy.orm import sessionmaker
-
-DATABASE_URL = os.environ.get("DATABASE_URL")
-
-engine = create_engine(DATABASE_URL)
-SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
-Base = declarative_base()
-
-class User(Base):
-    __tablename__ = "users"
-
-    id = Column(Integer, primary_key=True, index=True)
-    twitch_id = Column(String, unique=True, index=True)
-    twitch_username = Column(String)
-    # We will store encrypted tokens
-    twitch_access_token = Column(String)
-    twitch_refresh_token = Column(String)
-
-    youtube_id = Column(String, unique=True, index=True, nullable=True)
-    youtube_username = Column(String, nullable=True)
-    youtube_access_token = Column(String, nullable=True)
-    youtube_refresh_token = Column(String, nullable=True)
-
-def get_db():
-    db = SessionLocal()
-    try:
-        yield db
-    finally:
-        db.close()
-
-def create_tables():
-    Base.metadata.create_all(bind=engine)
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index ef450a6..0000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-version: '3.8'
-
-services:
-  web:
-    build: .
-    command: gunicorn -k uvicorn.workers.UvicornWorker -w 4 -b 0.0.0.0:8000 main:app
-    volumes:
-      - .:/app
-    ports:
-      - "8000:8000"
-    environment:
-      - DATABASE_URL=postgresql://user:password@db/mydatabase
-      - SECRET_KEY=YOUR_SECRET_KEY # This should be a long, random string
-      - TWITCH_CLIENT_ID=ogxx1fhpxbg8g89rov6oswuxeup2pb
-      - TWITCH_CLIENT_SECRET=2660uqpk2e1leayhpwcu35a27zidmh
-      - REDIRECT_URI=https://multichat.ramforth.net/auth/twitch/callback
-    depends_on:
-      - db
-
-  db:
-    image: postgres:13
-    volumes:
-      - postgres_data:/var/lib/postgresql/data/
-    environment:
-      - POSTGRES_USER=user
-      - POSTGRES_PASSWORD=password
-      - POSTGRES_DB=mydatabase
-
-volumes:
-  postgres_data:
diff --git a/index.html b/index.html
deleted file mode 100644
index c4fdf02..0000000
--- a/index.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-    MultiChat Overlay
-
-
-    

Chat Messages

-
    - - - diff --git a/login.html b/login.html deleted file mode 100644 index fef3ef5..0000000 --- a/login.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - Login to MultiChat Overlay - - -

    Login to MultiChat Overlay

    -

    Connect your streaming accounts to get started.

    - - - - - - diff --git a/main.py b/main.py deleted file mode 100644 index 8c73251..0000000 --- a/main.py +++ /dev/null @@ -1,67 +0,0 @@ -import asyncio -import json -from fastapi import FastAPI, WebSocket, Request, Depends -from fastapi.responses import HTMLResponse, RedirectResponse -from starlette.websockets import WebSocketDisconnect -from starlette.middleware.base import BaseHTTPMiddleware -from sqlalchemy.orm import Session - -from chat_listeners import listen_youtube_chat, listen_twitch_chat -from auth import router as auth_router, serializer -from database import get_db, User, create_tables - -app = FastAPI() - -@app.on_event("startup") -async def startup_event(): - create_tables() - # The chat listeners will be started dynamically based on user activity - # and not on application startup. - -class SessionMiddleware(BaseHTTPMiddleware): - async def dispatch(self, request: Request, call_next): - response = await call_next(request) - session_cookie = request.cookies.get("session") - if session_cookie: - try: - data = serializer.loads(session_cookie, max_age=3600 * 24 * 7) # 1 week - db = next(get_db()) - user = db.query(User).filter(User.id == data["user_id"]).first() - request.state.user = user - except Exception: - request.state.user = None - else: - request.state.user = None - return response - -@app.get("/") -async def read_root(): - return {"Hello": "World"} - -@app.get("/login", response_class=HTMLResponse) -async def get_login_page(): - with open("login.html", "r") as f: - return f.read() - -@app.get("/dashboard", response_class=HTMLResponse) -async def get_dashboard(user: User = Depends(get_current_user)): - if not user: - return RedirectResponse(url="/login") - with open("dashboard.html", "r") as f: - return f.read() - -@app.get("/overlay", response_class=HTMLResponse) -async def get_overlay(): - with open("index.html", "r") as f: - return f.read() - -@app.websocket("/ws") -async def websocket_endpoint(websocket: WebSocket): - await websocket.accept() - connected_clients.append(websocket) - try: - while True: - # Keep the connection alive, or handle incoming messages if needed - await websocket.receive_text() - except WebSocketDisconnect: - connected_clients.remove(websocket) diff --git a/multichat.db b/multichat.db deleted file mode 100644 index 1479c2b03dfa78462e8645c10aa0ea1615922128..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20480 zcmeI#O-lkn7{Kw_ToZ+)+n$1fE(#HZmyT_=lw@me8hMgcCt4~cUCFu?eXOp1uV%&d zrA+85|AE<;nb~LN`ORMDs#*?0C2xEEM?aJWu`LWk97!pJFm+Ap8kgujs&O&mhZT2I z?7u#3=>g`}r^tR~{p^l@pdf$%0tg_000IagfB*sr{7ax|rmO?YcuNG`jv57{=5V0; zgJ$>~gzdX#&>6obi=JcG99efu)w&}~?um0Fe~*pC;JMhd#{B!Ck+Lky_^5<_>p_k4 z7+*FfVQcnr*@^SZr1ct0Zp}G$Jn2?y(yf=vdoq)rCN8gSuXtvAbB$5BuK%c(bouSJ z8ff<3z3MLM?yK9r8r=QvpCvH=RouF4!np6R8RPyxr@Zt^7q-`s=T1ZB^yXyp(b-%d z`Y8w?fB*srAb