mirror of
https://github.com/jagandeepbrar/lunasea.git
synced 2026-08-31 12:42:34 +00:00
* [UI] Rounded all tile elements * [UI] Scaled entire UI down a few font sizes * [UI] Increase drawer font size, decrease PopupMenu font size * [UI] Sticky headers are now attached to AppBar * [TestFlight] v2.4.0 (240001) * [Clients/Queue] Animated play/pause icon * [Radarr] Releases are now shown as expandable tiles * [Headers] Match button size to input bar * [UI/Divider] Darken colour, slim down * [Sonarr/Releases] Updated release tiles to expandable tiles * [Sonarr] Removed sticky headers in upcoming & season details * [Sonarr] Remove unused routes * [Lidarr/Releases] Updated to expanded tile format * [Search] Updated result tiles to be expandable * [TestFlight] v2.4.0 (240002) * [Lists] Require or create a ScrollController for all LSLists * [Sonarr] Episode tiles now expandable, fixed statistics data crash * [TestFlight] v2.4.0 (240003) * [Popup Menu] Rounded shape on popup menus * [Sonarr] More sorting options for Sonarr catalogue & releases * [Sonarr/Catalogue] Sort by quality using id, not name * [AMOLED] Optional setting to add UI borders * [Refactor] Some file name changes * [Database] Cleanup reads and updates to database * [Module Flags] Hiding -rr's wouldn't hide the calendar setting * [Dropdowns] Changed remaining dropdowns to popup menus * [Sonarr] Safe-guard fetching episode queue * [TestFlight] v2.4.0 (240006) * [Changelog] Remove routes, redirect to documentation * [Search] Added sorting options to search/results, filter for results * [Sonarr/Add] Ability to set initial episode monitor status * [Images] Option to clear network image cache * [TestFlight] v3.0.0 (300001) * [Tweaks] Small tweaks to text, typos * [TestFlight] v3.0.0 (300002) * [Lidarr] Additional sorting options for catalogue * [Sonarr/Episode] Fix episode list crash * [Lidarr/Releases] Added widgets for hide, filter, sort * [Lidarr/Releases] Implemented sort, hide, and filter functionality * [TestFlight] v3.0.0 (300003) * [README] Added CI shield, updated version * [Sonarr] Ability to set initial page * [Radarr] Ability to set initial page * [Lidarr] Ability to set initial page * [NZBGet] Ability to set initial page * [SABnzbd] Ability to set initial page * [Home] Ability to set initial page * [Radarr] Implemented new sorting structure * [Radarr] Implemented filter, hide, and sorting of releases * [Radarr] Additional catalogue sorting methods * [TestFlight] v3.0.0 (300100)
201 lines
9.0 KiB
Dart
201 lines
9.0 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:dio/adapter.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) => Logger.error('package:lunasea/core/api/calendar/api.dart', methodName, 'Home: $text', error, StackTrace.current);
|
|
void logWarning(String methodName, String text) => Logger.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(
|
|
ModuleFlags.AUTOMATION &&
|
|
ModuleFlags.LIDARR &&
|
|
lidarr['enabled'] &&
|
|
HomeDatabaseValue.CALENDAR_ENABLE_LIDARR.data
|
|
) await _getLidarrUpcoming(_upcoming, today);
|
|
if(
|
|
ModuleFlags.AUTOMATION &&
|
|
ModuleFlags.RADARR &&
|
|
radarr['enabled'] &&
|
|
HomeDatabaseValue.CALENDAR_ENABLE_RADARR.data
|
|
) await _getRadarrUpcoming(_upcoming, today);
|
|
if(
|
|
ModuleFlags.AUTOMATION &&
|
|
ModuleFlags.SONARR &&
|
|
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, { int startOffset = 7, int endOffset = 60 }) async {
|
|
try {
|
|
String start = DateFormat('y-MM-dd').format(today.subtract(Duration(days: startOffset)));
|
|
String end = DateFormat('y-MM-dd').format(today.add(Duration(days: endOffset)));
|
|
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': start,
|
|
'end': end,
|
|
},
|
|
headers: _headers,
|
|
followRedirects: true,
|
|
maxRedirects: 5,
|
|
),
|
|
);
|
|
if(!lidarr['strict_tls']) {
|
|
(_client.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
|
|
client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
|
|
};
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
} catch (error) {
|
|
logError('_getLidarrUpcoming', 'Failed to fetch Lidarr upcoming content', error);
|
|
return;
|
|
}
|
|
}
|
|
|
|
Future<void> _getRadarrUpcoming(Map<DateTime, List> map, DateTime today, { int startOffset = 7, int endOffset = 60 }) async {
|
|
try {
|
|
String start = DateFormat('y-MM-dd').format(today.subtract(Duration(days: startOffset)));
|
|
String end = DateFormat('y-MM-dd').format(today.add(Duration(days: endOffset)));
|
|
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': start,
|
|
'end': end,
|
|
},
|
|
headers: _headers,
|
|
followRedirects: true,
|
|
maxRedirects: 5,
|
|
),
|
|
);
|
|
if(!radarr['strict_tls']) {
|
|
(_client.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
|
|
client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
|
|
};
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
} catch (error) {
|
|
logError('_getRadarrUpcoming', 'Failed to fetch Radarr upcoming content', error);
|
|
return;
|
|
}
|
|
}
|
|
|
|
Future<void> _getSonarrUpcoming(Map<DateTime, List> map, DateTime today, { int startOffset = 7, int endOffset = 60 }) async {
|
|
try {
|
|
String start = DateFormat('y-MM-dd').format(today.subtract(Duration(days: startOffset)));
|
|
String end = DateFormat('y-MM-dd').format(today.add(Duration(days: endOffset)));
|
|
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': start,
|
|
'end': end,
|
|
},
|
|
headers: _headers,
|
|
followRedirects: true,
|
|
maxRedirects: 5,
|
|
),
|
|
);
|
|
if(!sonarr['strict_tls']) {
|
|
(_client.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
|
|
client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
|
|
};
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
} catch (error) {
|
|
logError('_getSonarrUpcoming', 'Failed to fetch Sonarr upcoming content', error);
|
|
return;
|
|
}
|
|
}
|
|
} |