Skip to content

Commit

Permalink
feature: add trakt api
Browse files Browse the repository at this point in the history
  • Loading branch information
zeroquinc committed May 23, 2024
1 parent ef6fd81 commit ee8e29f
Show file tree
Hide file tree
Showing 15 changed files with 255 additions and 10 deletions.
31 changes: 31 additions & 0 deletions .github/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name-template: 'v$RESOLVED_VERSION'
tag-template: 'v$RESOLVED_VERSION'
categories:
- title: '🚀 Features'
labels:
- 'feature'
- 'enhancement'
- title: '🐛 Bug Fixes'
labels:
- 'fix'
- 'bugfix'
- 'bug'
- title: '🧰 Maintenance'
label: 'chore'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
version-resolver:
major:
labels:
- 'major'
minor:
labels:
- 'minor'
patch:
labels:
- 'patch'
default: patch
template: |
## Changes
$CHANGES
36 changes: 36 additions & 0 deletions .github/workflows/labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Label PRs based on PR title

on:
pull_request:
types: [opened, synchronize]

jobs:
labelPR:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Install GitHub CLI
run: |
curl -OL https://github.com/cli/cli/releases/download/v2.4.0/gh_2.4.0_linux_amd64.deb
sudo dpkg -i gh_2.4.0_linux_amd64.deb
- name: Get PR number
id: pr_number
run: echo "::set-output name=number::${{ github.event.pull_request.number }}"

- name: Add label
run: |
PR_TITLE="${{ github.event.pull_request.title }}"
if [[ "$PR_TITLE" == fix:* ]]; then
gh pr edit ${{ steps.pr_number.outputs.number }} --add-label "fix"
elif [[ "$PR_TITLE" == feature:* ]]; then
gh pr edit ${{ steps.pr_number.outputs.number }} --add-label "feature"
elif [[ "$PR_TITLE" == chore:* ]]; then
gh pr edit ${{ steps.pr_number.outputs.number }} --add-label "chore"
elif [[ "$PR_TITLE" == enhancement:* ]]; then
gh pr edit ${{ steps.pr_number.outputs.number }} --add-label "enhancement"
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21 changes: 21 additions & 0 deletions .github/workflows/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Release Drafter

on:
push:
branches:
- main

jobs:
release:
runs-on: ubuntu-latest

steps:
- name: Checkout Repository
uses: actions/checkout@v2

- name: Install Release Drafter
uses: release-drafter/release-drafter@v6
with:
config-name: release-drafter.yml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Empty file added api/trakt/__init__.py
Empty file.
25 changes: 25 additions & 0 deletions api/trakt/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import requests
from config.globals import TRAKT_API_URL, TRAKT_CLIENT_ID
from .exceptions import TraktAPIException

class TraktClient:
def __init__(self):
self.client_id = TRAKT_CLIENT_ID
self.session = requests.Session()
self.headers = {
"Content-Type": "application/json",
"trakt-api-version": "2",
"trakt-api-key": self.client_id
}
self.session.headers.update(self.headers)

def _get(self, endpoint, params=None):
url = f'{TRAKT_API_URL}/{endpoint}'
response = self.session.get(url, params=params)
if response.status_code != 200:
raise TraktAPIException(response.json())
return response.json()

def user(self, username):
from .endpoints.user import User
return User(self, username)
Empty file added api/trakt/endpoints/__init__.py
Empty file.
29 changes: 29 additions & 0 deletions api/trakt/endpoints/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from dateutil.parser import parse
from dateutil.tz import tzlocal

from api.trakt.models.rating import Rating

class User:
def __init__(self, client, username):
self.client = client
self.username = username

def convert_to_tz_aware(self, dt):
return dt.replace(tzinfo=tzlocal()) if dt is not None else None

def get_ratings(self, media_type="all", rating=None, start_time=None, end_time=None):
endpoint = f'users/{self.username}/ratings/{media_type}'
params = {}
if rating:
params['rating'] = rating

ratings = self.client._get(endpoint, params=params)
start_time = self.convert_to_tz_aware(start_time)
end_time = self.convert_to_tz_aware(end_time)

def is_within_time_range(rating_time):
return (start_time is None or rating_time >= start_time) and (end_time is None or rating_time <= end_time)

ratings = [Rating(rating) for rating in ratings if is_within_time_range(parse(rating['rated_at']).astimezone(tzlocal()))]

return ratings
5 changes: 5 additions & 0 deletions api/trakt/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class TraktAPIException(Exception):
def __init__(self, error_data):
self.status_code = error_data.get('status_code')
self.message = error_data.get('message')
super().__init__(self.message)
58 changes: 58 additions & 0 deletions api/trakt/models/rating.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from dateutil.parser import parse
from dateutil.tz import tzlocal

class Rating:
def __init__(self, data):
self.type = data['type']
self.rated = data['rating']
self.rated_at = parse(data['rated_at']).astimezone(tzlocal()) # Convert to local timezone
self.show_title = None
self.season_id = None
self.episode_id = None
media = create_media(data)
self.set_media_attributes(media)

def set_media_attributes(self, media):
self.title = media.title
self.year = media.year

if isinstance(media, (Episode, Season)):
self.show_title = media.show_title
self.season_id = media.season_id

if isinstance(media, Episode):
self.episode_id = media.episode_id

@classmethod
def from_json(cls, data):
return cls(data)

def create_media(data):
media_classes = {'movie': Movie, 'episode': Episode, 'season': Season, 'show': Show}
media_type = data['type']
return media_classes.get(media_type, lambda _: None)(data)

class Movie:
def __init__(self, data):
self.title = data['movie']['title']
self.year = data['movie']['year']

class Episode:
def __init__(self, data):
self.title = data['episode']['title']
self.show_title = data['show']['title']
self.season_id = "{:02}".format(data['episode']['season']) # Format as two-digit number
self.episode_id = "{:02}".format(data['episode']['number']) # Format as two-digit number
self.year = data['show']['year']

class Season:
def __init__(self, data):
self.title = data['show']['title']
self.show_title = data['show']['title']
self.season_id = "{:02}".format(data['season']['number']) # Format as two-digit number
self.year = data['show']['year']

class Show:
def __init__(self, data):
self.title = data['show']['title']
self.year = data['show']['year']
11 changes: 5 additions & 6 deletions config/globals.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
from dotenv import load_dotenv
import os

# DotEnv
load_dotenv()

# Discord Globals
# Discord
DISCORD_SERVER_ID = os.getenv("DISCORD_SERVER_ID")
TOKEN = os.environ["DISCORD_TOKEN"]
DISCORD_TOKEN = os.environ["DISCORD_TOKEN"]

# Trakt
TRAKT_USERNAME = "desileR"
TRAKT_CLIENTID = os.getenv("TRAKT_CLIENTID")
TRAKT_API_URL = "https://api.trakt.tv"
TRAKT_CLIENT_ID = os.getenv("TRAKT_CLIENTID")

# API Keys
# TMDB
TMDB_API_KEY = os.getenv("TMDB_API_KEY")
8 changes: 4 additions & 4 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import asyncio

from webhook import HandleWebHook
from bot import DiscordBot
from src.webhook.hook import HandleWebHook
from src.discord.bot import DiscordBot

from config.globals import TOKEN
from config.globals import DISCORD_TOKEN

if __name__ == "__main__":
discord_bot = DiscordBot(TOKEN)
discord_bot = DiscordBot(DISCORD_TOKEN)
webhook = HandleWebHook(discord_bot)

loop = asyncio.get_event_loop()
Expand Down
File renamed without changes.
20 changes: 20 additions & 0 deletions src/discord/embed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import discord

class EmbedBuilder:
def __init__(self, title='', description='', color=discord.Color.default()):
self.embed = discord.Embed(title=title, description=description, color=color)

def set_author(self, name, icon_url=None, url=None):
self.embed.set_author(name=name, icon_url=icon_url, url=url)
return self

def add_field(self, name, value, inline=True):
self.embed.add_field(name=name, value=value, inline=inline)
return self

def set_footer(self, text, icon_url=None):
self.embed.set_footer(text=text, icon_url=icon_url)
return self

def build(self):
return self.embed
File renamed without changes.
21 changes: 21 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from datetime import datetime, timedelta
from api.trakt.client import TraktClient

client = TraktClient()
user = client.user('desiler')

# Get the current time and the time one hour ago
now = datetime.now()
one_hour_ago = now - timedelta(hours=1)

#ratings = user.get_ratings(start_time=one_hour_ago, end_time=now)
ratings = user.get_ratings()
for rating in ratings:
print(f"Title: {rating.title}")
print(f"Media type: {rating.type}")
print(f"Season: {rating.season_id}")
print(f"Episode: {rating.episode_id}")
print(f"Rating: {rating.rated}")
print(f"Rated at: {rating.rated_at}")
print(f"Show title: {rating.show_title}")
print()

0 comments on commit ee8e29f

Please sign in to comment.