1
0
personal-data/personal_data/fetchers/jellyfin_watch_history.py
Jon Michael Aanes b67089f911
Some checks failed
Run Python tests (through Pytest) / Test (push) Failing after 40s
Verify Python project can be installed, loaded and have version checked / Test (push) Successful in 30s
Standardized scraper name to not include scraper
2024-10-25 21:50:56 +02:00

86 lines
2.7 KiB
Python

import dataclasses
import logging
from collections.abc import Iterator
from typing import Any
from jellyfin_apiclient_python import JellyfinClient
from .. import _version, secrets
from ..data import DeduplicateMode, Scraper
logger = logging.getLogger(__name__)
URL_SITE_ROOT = 'https://steamcommunity.com/'
URL_GAME_ACHIVEMENTS = URL_SITE_ROOT + 'id/{username}/stats/appid/{appid}'
FORMAT_DATE_HEADER = '%d/%m/%YYYY'
def iterate_series(client):
result = client.jellyfin.user_items(
params={
'includeItemTypes': 'Series',
'parentId': 'a656b907eb3a73532e40e44b968d0225',
'userId': 'dd95c1085c1b4e83ba8e8853fbc644ab',
},
)
yield from result['Items']
def iterate_watched_episodes_of_series(client, series_id: str):
result = client.jellyfin.user_items(
params={
'filters': 'IsPlayed',
'recursive': True,
'includeItemTypes': 'Episode',
'parentId': series_id,
'userId': 'dd95c1085c1b4e83ba8e8853fbc644ab',
'fields': 'AirTime',
},
)
yield from result['Items']
@dataclasses.dataclass(frozen=True)
class JellyfinWatchHistory(Scraper):
dataset_name = 'show_episodes_watched'
deduplicate_mode = DeduplicateMode.BY_ALL_COLUMNS
def scrape(self) -> Iterator[dict[str, Any]]:
client = JellyfinClient()
client.config.app(
'personal_data',
_version.__version__,
'test_machine',
'unique_id_1',
)
client.config.data['auth.ssl'] = False
client.auth.connect_to_address(secrets.JELLYFIN_URL)
client.auth.login(
secrets.JELLYFIN_URL,
secrets.JELLYFIN_USERNAME,
secrets.JELLYFIN_PASSWORD,
)
for series_data in iterate_series(client):
series_id = series_data['Id']
for episode_data in iterate_watched_episodes_of_series(client, series_id):
episode_index = episode_data.get('IndexNumber')
if episode_index is None:
continue
yield {
'series.name': episode_data['SeriesName'],
'season.name': episode_data['SeasonName'],
'episode.index': int(episode_index),
'episode.name': episode_data['Name'],
'me.last_played_time': episode_data['UserData']['LastPlayedDate'],
'episode.duration_seconds': episode_data['RunTimeTicks'] / 10000000,
'episode.premiere_date': episode_data.get('PremiereDate'),
}
del episode_data
del series_data, series_id