import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:lunasea/core.dart'; import 'package:lunasea/modules/home.dart'; class CalendarAPI extends API { final Map lidarr; final Map radarr; final Map sonarr; CalendarAPI._internal({ @required this.lidarr, @required this.radarr, @required this.sonarr, }); factory CalendarAPI.from(ProfileHiveObject profile) { return CalendarAPI._internal( lidarr: profile?.getLidarr(), radarr: profile?.getRadarr(), sonarr: profile?.getSonarr(), ); } void logError(String methodName, String text, Object error, StackTrace trace, { bool uploadToSentry = true, }) => LunaLogger.error( 'package:lunasea/core/api/calendar/api.dart', methodName, 'Home: $text', error, trace, uploadToSentry: uploadToSentry, ); void logWarning(String methodName, String text) => LunaLogger.warning( 'package:lunasea/core/api/calendar/api.dart', methodName, 'Home: $text', ); Future testConnection() async => true; Future> getUpcoming(DateTime today) async { Map _upcoming = {}; if( lidarr['enabled'] && HomeDatabaseValue.CALENDAR_ENABLE_LIDARR.data ) await _getLidarrUpcoming(_upcoming, today); if( radarr['enabled'] && HomeDatabaseValue.CALENDAR_ENABLE_RADARR.data ) await _getRadarrUpcoming(_upcoming, today); if( sonarr['enabled'] && HomeDatabaseValue.CALENDAR_ENABLE_SONARR.data ) await _getSonarrUpcoming(_upcoming, today); return _upcoming.isEmpty ? await Future.delayed(Duration(milliseconds: 500), () => {}) : _upcoming; } Future _getLidarrUpcoming(Map map, DateTime today) async { try { Map _headers = Map.from(lidarr['headers']); Dio _client = Dio( BaseOptions( baseUrl: '${lidarr['host']}/api/v1/', queryParameters: { if(lidarr['key'] != '') 'apikey': lidarr['key'], 'start': _startDate(today), 'end': _startDate(today), }, headers: _headers, followRedirects: true, maxRedirects: 5, ), ); Response response = await _client.get('calendar'); if(response.data.length > 0) { for(var entry in response.data) { DateTime date = DateTime.tryParse(entry['releaseDate'] ?? '')?.toLocal()?.lsDateTime_floor(); if(date != null) { List day = map[date] ?? []; day.add(CalendarLidarrData( id: entry['id'] ?? 0, title: entry['artist']['artistName'] ?? 'Unknown Artist', albumTitle: entry['title'] ?? 'Unknown Album Title', artistId: entry['artist']['id'] ?? 0, hasAllFiles: (entry['statistics'] != null ? entry['statistics']['percentOfTracks'] ?? 0 : 0) == 100, )); map[date] = day; } } } } on DioError catch (error, stack) { logError('_getLidarrUpcoming', 'Failed to fetch Lidarr upcoming content', error, stack, uploadToSentry: false); } catch (error, stack) { logError('_getLidarrUpcoming', 'Failed to fetch Lidarr upcoming content', error, stack); } return; } Future _getRadarrUpcoming(Map map, DateTime today) async { try { Map _headers = Map.from(radarr['headers']); Dio _client = Dio( BaseOptions( baseUrl: '${radarr['host']}/api/', queryParameters: { if(radarr['key'] != '') 'apikey': radarr['key'], 'start': _startDate(today), 'end': _endDate(today), }, headers: _headers, followRedirects: true, maxRedirects: 5, ), ); Response response = await _client.get('calendar'); if(response.data.length > 0) { for(var entry in response.data) { DateTime date = DateTime.tryParse(entry['physicalRelease'] ?? '')?.toLocal()?.lsDateTime_floor(); if(date != null) { List day = map[date] ?? []; day.add(CalendarRadarrData( id: entry['id'] ?? 0, title: entry['title'] ?? 'Unknown Title', hasFile: entry['hasFile'] ?? false, fileQualityProfile: entry['hasFile'] ? entry['movieFile']['quality']['quality']['name'] : '', year: entry['year'] ?? 0, runtime: entry['runtime'] ?? 0, )); map[date] = day; } } } } on DioError catch (error, stack) { logError('_getRadarrUpcoming', 'Failed to fetch Radarr upcoming content', error, stack, uploadToSentry: false); } catch (error, stack) { logError('_getRadarrUpcoming', 'Failed to fetch Radarr upcoming content', error, stack); } return; } Future _getSonarrUpcoming(Map map, DateTime today) async { try { Map _headers = Map.from(sonarr['headers']); Dio _client = Dio( BaseOptions( baseUrl: '${sonarr['host']}/api/', queryParameters: { if(sonarr['key'] != '') 'apikey': sonarr['key'], 'start': _startDate(today), 'end': _endDate(today), }, headers: _headers, followRedirects: true, maxRedirects: 5, ), ); Response response = await _client.get('calendar'); if(response.data.length > 0) { for(var entry in response.data) { DateTime date = DateTime.tryParse(entry['airDateUtc'] ?? '')?.toLocal()?.lsDateTime_floor(); if(date != null) { List day = map[date] ?? []; day.add(CalendarSonarrData( id: entry['id'] ?? 0, seriesID: entry['seriesId'] ?? 0, title: entry['series']['title'] ?? 'Unknown Series', episodeTitle: entry['title'] ?? 'Unknown Episode Title', seasonNumber: entry['seasonNumber'] ?? -1, episodeNumber: entry['episodeNumber'] ?? -1, airTime: entry['airDateUtc'] ?? '', hasFile: entry['hasFile'] ?? false, fileQualityProfile: entry['hasFile'] ? entry['episodeFile']['quality']['quality']['name'] : '', )); map[date] = day; } } } } on DioError catch (error, stack) { logError('_getSonarrUpcoming', 'Failed to fetch Sonarr upcoming content', error, stack, uploadToSentry: false); } catch (error, stack) { logError('_getSonarrUpcoming', 'Failed to fetch Sonarr upcoming content', error, stack); } return; } String _startDate(DateTime today) => DateFormat('y-MM-dd').format(today.subtract(Duration(days: HomeDatabaseValue.CALENDAR_DAYS_PAST.data))); String _endDate(DateTime today) => DateFormat('y-MM-dd').format(today.add(Duration(days: HomeDatabaseValue.CALENDAR_DAYS_FUTURE.data + 1))); }