mirror of
https://github.com/jagandeepbrar/lunasea.git
synced 2026-08-30 20:24:25 +00:00
NEW - [Networking] Strict TLS/SSL validation is now disabled globally - [Routing] Hold the AppBar back button to pop back to the home page of the module - [Settings/Sonarr] Toggle to enable Sonarr v3 features - [Sonarr] Complete rewrite of Sonarr - [Sonarr] State is now held across module switches - [Sonarr/Overview] View tags applied to series - [Sonarr/Catalogue] (v3 only) Ability to set and update language profile - [Sonarr/Catalogue] Ability to view all, only monitored, or only unmonitored series - [Sonarr/Releases] (v3 only) Ability to interactively search for season packs - [Sonarr/Releases] Ability to view all, only approved, or only rejected releases TWEAKS - [Settings] Removed all toggles for strict TLS - [Sonarr] Many tweaks to Sonarr's design - [Sonarr/Add] (v3 only) Tapping an already-added series will take you to the series page - [Sonarr/Add] Automatically navigate to newly added series - [Sonarr/Series] Toggling monitored state of series has now been moved to the edit prompt FIXES - [Images] Images will now load for invalid/self-signed certificates - [Tautulli/Activity] Fix grey screen for music activity - [TextField] Fix TextField actions (cut, copy, paste, etc.) not showing - [Timestamps] Fix 12:xx AM being shown as 00:xx AM - Additional small bug fixes
194 lines
8.3 KiB
Dart
194 lines
8.3 KiB
Dart
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<String, dynamic> lidarr;
|
|
final Map<String, dynamic> radarr;
|
|
final Map<String, dynamic> 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<bool> testConnection() async => true;
|
|
|
|
Future<Map<DateTime, List>> getUpcoming(DateTime today) async {
|
|
Map<DateTime, List> _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<void> _getLidarrUpcoming(Map<DateTime, List> map, DateTime today) async {
|
|
try {
|
|
Map<String, dynamic> _headers = Map<String, dynamic>.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<void> _getRadarrUpcoming(Map<DateTime, List> map, DateTime today) async {
|
|
try {
|
|
Map<String, dynamic> _headers = Map<String, dynamic>.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<void> _getSonarrUpcoming(Map<DateTime, List> map, DateTime today) async {
|
|
try {
|
|
Map<String, dynamic> _headers = Map<String, dynamic>.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)));
|
|
} |