Skip to content

Commit

Permalink
forgot to add files.. will delete after (#332)
Browse files Browse the repository at this point in the history
* fix: add missing modules

---------

Co-authored-by: Spoked <Spoked@localhost>
Co-authored-by: davidemarcoli <davide@marcoli.ch>
  • Loading branch information
3 people authored Jun 3, 2024
1 parent 10a92f5 commit 25cd6b2
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 0 deletions.
67 changes: 67 additions & 0 deletions backend/controllers/models/overseerr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from typing import Any, List, Literal, Optional

from pydantic import BaseModel, field_validator

MediaType = Literal["movie", "tv"]


class Media(BaseModel):
media_type: MediaType
status: str
imdbId: str | None = None
tmdbId: int
tvdbId: int | None = None

@field_validator("imdbId", mode="after")
@classmethod
def stringify_imdb_id(cls, value: Any):
if value and isinstance(value, int):
return f"tt{int(value):07d}"
return None

@field_validator("tvdbId", "tmdbId", mode="before")
@classmethod
def validate_ids(cls, value: Any):
if value and isinstance(value, str) and value != "":
return int(value)
return None


class RequestInfo(BaseModel):
request_id: str
requestedBy_email: str
requestedBy_username: str
requestedBy_avatar: Optional[str]

class IssueInfo(BaseModel):
issue_id: str
issue_type: str
issue_status: str
reportedBy_email: str
reportedBy_username: str
reportedBy_avatar: Optional[str]

class CommentInfo(BaseModel):
comment_message: str
commentedBy_email: str
commentedBy_username: str
commentedBy_avatar: Optional[str]

class OverseerrWebhook(BaseModel):
notification_type: str
event: str
subject: str
message: Optional[str] = None
image: Optional[str] = None
media: Media
request: Optional[RequestInfo] = None
issue: Optional[IssueInfo] = None
comment: Optional[CommentInfo] = None
extra: List[dict[str, Any]] = []

@property
def requested_seasons(self) -> Optional[List[int]]:
for extra in self.extra:
if extra["name"] == "Requested Seasons":
return [int(x) for x in extra["value"].split(",")]
return None
66 changes: 66 additions & 0 deletions backend/controllers/models/plex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from typing import Optional

from pydantic import BaseModel, Field
from rich.console import Console
from rich.table import Table

console = Console()


class Account(BaseModel):
id: int
thumb: str
title: str

class Server(BaseModel):
title: str
uuid: str

class Player(BaseModel):
local: bool
publicAddress: str
title: str
uuid: str

class Metadata(BaseModel):
librarySectionType: str
ratingKey: str
key: str
guid: str
type: str
title: str
librarySectionTitle: str
librarySectionID: int
librarySectionKey: str
contentRating: str
summary: str
rating: Optional[float] = Field(None, description="Rating of the media")
audienceRating: Optional[float] = Field(None, description="Audience rating of the media")
year: int
tagline: Optional[str] = Field(None, description="Tagline of the media")
thumb: str

class PlexPayload(BaseModel):
event: str
user: bool
owner: bool
Account: Account
Server: Server
Player: Player
Metadata: Metadata


def log_plex_payload(plex_payload):
table = Table(title="Plex Payload Details")

table.add_column("Field", style="bold cyan")
table.add_column("Value", style="bold magenta")

table.add_row("Event", plex_payload.event)
table.add_row("User", plex_payload.Account.title)
table.add_row("User ID", str(plex_payload.Account.id))
table.add_row("Media Title", plex_payload.Metadata.title)
table.add_row("Media Type", plex_payload.Metadata.type)
table.add_row("Year", str(plex_payload.Metadata.year))

console.print(table)
124 changes: 124 additions & 0 deletions backend/controllers/webooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import json
from datetime import datetime

import pydantic
import requests
from fastapi import APIRouter, HTTPException, Request
from program.indexers.trakt import get_imdbid_from_tmdb
from program.settings.manager import settings_manager
from utils.logger import logger

from .models.overseerr import OverseerrWebhook

router = APIRouter(
responses={404: {"description": "Not found"}},
)


@router.post("/overseerr")
async def overseerr_webhook(request: Request):
response = await request.json()
logger.debug(f"Received request for: {response.get('subject', 'Unknown')}")
try:
req = OverseerrWebhook.model_validate(response)
except pydantic.ValidationError:
return {"success": False, "message": "Invalid request"}
imdb_id = req.media.imdbId
if not imdb_id:
imdb_id = get_imdbid_from_tmdb(req.media.tmdbId)
if not imdb_id:
logger.error(f"Failed to get imdb_id from TMDB: {req.media.tmdbId}")
return {"success": False, "message": "Failed to get imdb_id from TMDB", "title": req.subject}
item = {"imdb_id": imdb_id, "requested_by": "overseerr", "requested_at": datetime.now()}
request.app.program.add_to_queue(item)
return {"success": True}


@router.post("/plex")
async def plex_webhook(request: Request):
form = await request.form()
payload = form.get("payload")
if not payload:
logger.error("Missing payload in form data")
raise HTTPException(status_code=400, detail="Missing payload in form data")

try:
payload_dict = json.loads(payload)
plex_payload = PlexPayload(**payload_dict)
except json.JSONDecodeError:
logger.error("Invalid JSON payload")
raise HTTPException(status_code=400, detail="Invalid JSON payload")
except Exception as e:
logger.error(f"Unexpected error: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))

if plex_payload.event == "media.play":
logger.log("PLEX", f"Event: {plex_payload.event}")
logger.log("PLEX", f"User: {plex_payload.Account.title} (ID: {plex_payload.Account.id})")
logger.log("PLEX", f"Media Title: {plex_payload.Metadata.title}")
logger.log("PLEX", f"Media Type: {plex_payload.Metadata.type}")
logger.log("PLEX", f"Year: {plex_payload.Metadata.year}")

logger.log("EVENT", f"Event: {plex_payload.event}")
# Assuming you have a function to log the payload
# log_plex_payload(plex_payload)

return {"status": "received"}



### Plex Models

from pydantic import BaseModel


class Account(BaseModel):
id: int
thumb: str
title: str

class Server(BaseModel):
title: str
uuid: str

class Player(BaseModel):
local: bool
publicAddress: str
title: str
uuid: str

class Metadata(BaseModel):
librarySectionType: str
ratingKey: str
key: str
guid: str
type: str
title: str
librarySectionTitle: str
librarySectionID: int
librarySectionKey: str
contentRating: str
summary: str
rating: float
audienceRating: float
year: int
tagline: str
thumb: str

class PlexPayload(BaseModel):
event: str
user: bool
owner: bool
Account: Account
Server: Server
Player: Player
Metadata: Metadata

class TraktSettings(BaseModel):
trakt_id: str
trakt_secret: str

class Config:
env_file = ".env"

settings = TraktSettings()

0 comments on commit 25cd6b2

Please sign in to comment.