refactor: remove dead download code

This commit is contained in:
edde746
2026-04-16 07:27:05 +02:00
parent 74b2d76fea
commit 65e22fbbbd
5 changed files with 0 additions and 263 deletions
@@ -1817,11 +1817,6 @@ class DownloadManagerService {
}
}
/// Get all downloads with a specific status
Stream<List<DownloadedMediaItem>> watchDownloadsByStatus(DownloadStatus status) {
return (_database.select(_database.downloadedMedia)..where((t) => t.status.equals(status.index))).watch();
}
/// Get all downloaded media items (for loading persisted data)
Future<List<DownloadedMediaItem>> getAllDownloads() {
return _database.select(_database.downloadedMedia).get();
@@ -1879,18 +1874,6 @@ class DownloadManagerService {
await _apiCache.pinForOffline(serverId, ratingKey);
}
/// Cache children (seasons or episodes) in the API response format
Future<void> cacheChildrenForOffline(String serverId, String parentRatingKey, List<PlexMetadata> children) async {
final endpoint = '/library/metadata/$parentRatingKey/children';
// Build a response structure that matches the Plex API format
final cachedResponse = {
'MediaContainer': {'Metadata': children.map((c) => c.toJson()).toList()},
};
await _apiCache.put(serverId, endpoint, cachedResponse);
}
void dispose() {
_disposed = true;
for (final timer in _progressDebounceTimers.values) {
-112
View File
@@ -84,12 +84,6 @@ class DownloadStorageService {
return dir.path;
}
/// Get default download path (for "Reset to Default" functionality)
Future<String> getDefaultDownloadPath() async {
final baseDir = await _getBaseAppDir();
return path.join(baseDir.path, 'downloads');
}
/// Check if a directory is writable
Future<bool> isDirectoryWritable(Directory dir) async {
try {
@@ -194,12 +188,6 @@ class DownloadStorageService {
return path.join(mediaDir.path, 'video.$extension');
}
/// Get artwork file path (poster, art, thumb)
Future<String> getArtworkPath(String serverId, String ratingKey, String artworkType) async {
final mediaDir = await getMediaDirectory(serverId, ratingKey);
return path.join(mediaDir.path, '$artworkType.jpg');
}
/// Get subtitles directory
Future<Directory> getSubtitlesDirectory(String serverId, String ratingKey) async {
final mediaDir = await getMediaDirectory(serverId, ratingKey);
@@ -272,12 +260,6 @@ class DownloadStorageService {
return path.join(movieDir.path, '$fileName.$extension');
}
/// Get movie artwork path: .../Movie Name (YYYY)/{artworkType}.jpg
Future<String> getMovieArtworkPath(PlexMetadata movie, String artworkType) async {
final movieDir = await getMovieDirectory(movie);
return path.join(movieDir.path, '$artworkType.jpg');
}
/// Get show directory: downloads/TV Shows/{Show Name} ({Year})/
/// [showYear]: Pass the show's premiere year explicitly (for episodes, the episode's
/// year may differ from the show's year). If not provided, uses metadata.year.
@@ -287,12 +269,6 @@ class DownloadStorageService {
return _ensureDirectoryExists(Directory(path.join(baseDir.path, 'TV Shows', showFolder)));
}
/// Get show artwork path: downloads/TV Shows/{Show}/poster.jpg
Future<String> getShowArtworkPath(PlexMetadata metadata, String artworkType, {int? showYear}) async {
final showDir = await getShowDirectory(metadata, showYear: showYear);
return path.join(showDir.path, '$artworkType.jpg');
}
/// Get season directory: .../TV Shows/{Show}/Season {XX}/
/// [showYear]: Pass the show's premiere year (not episode or season year)
Future<Directory> getSeasonDirectory(PlexMetadata metadata, {int? showYear}) async {
@@ -301,12 +277,6 @@ class DownloadStorageService {
return _ensureDirectoryExists(Directory(path.join(showDir.path, 'Season $seasonNum')));
}
/// Get season artwork path: .../Season XX/poster.jpg
Future<String> getSeasonArtworkPath(PlexMetadata metadata, String artworkType, {int? showYear}) async {
final seasonDir = await getSeasonDirectory(metadata, showYear: showYear);
return path.join(seasonDir.path, '$artworkType.jpg');
}
/// Get base path info for episode files (season directory path and formatted filename).
/// [showYear]: Pass the show's premiere year (not episode year)
Future<({String seasonDirPath, String fileName})> _getEpisodeBasePath(PlexMetadata episode, {int? showYear}) async {
@@ -356,14 +326,6 @@ class DownloadStorageService {
return path.join(subsDir.path, '$trackId.$extension');
}
/// Delete all files for a media item
Future<void> deleteMediaFiles(String serverId, String ratingKey) async {
final mediaDir = await getMediaDirectory(serverId, ratingKey);
if (await mediaDir.exists()) {
await mediaDir.delete(recursive: true);
}
}
/// Convert an absolute file path to a relative path (for database storage)
/// This ensures paths remain valid across app reinstalls on iOS where
/// the container UUID can change.
@@ -469,80 +431,6 @@ class DownloadStorageService {
return fallback;
}
/// Calculate total storage used by downloads
Future<int> getTotalStorageUsed() async {
final baseDir = await getDownloadsDirectory();
return _calculateDirectorySize(baseDir);
}
Future<int> _calculateDirectorySize(Directory dir) async {
int size = 0;
if (!await dir.exists()) return size;
await for (var entity in dir.list(recursive: true, followLinks: false)) {
if (entity is File) {
try {
size += await entity.length();
} catch (_) {
// Ignore errors reading file size
}
}
}
return size;
}
/// Format bytes to human readable string
static String formatBytes(int bytes) => ByteFormatter.formatBytes(bytes);
// ============================================================
// SAF (Storage Access Framework) SUPPORT FOR ANDROID
// ============================================================
/// Get temporary cache directory for initial downloads
/// Files are downloaded here first, then copied to SAF if using SAF mode
Future<Directory> getCacheDownloadDirectory() async {
final cacheDir = await getApplicationDocumentsDirectory();
return _ensureDirectoryExists(Directory(path.join(cacheDir.path, '.download_cache')));
}
/// Get temporary file path for downloading (before copying to SAF)
Future<String> getTempDownloadPath(String fileName) async {
final cacheDir = await getCacheDownloadDirectory();
return path.join(cacheDir.path, fileName);
}
/// Get the MIME type for a file extension
String getMimeType(String extension) {
switch (extension.toLowerCase()) {
case 'mp4':
return 'video/mp4';
case 'mkv':
return 'video/x-matroska';
case 'm4v':
return 'video/x-m4v';
case 'avi':
return 'video/x-msvideo';
case 'ogv':
return 'video/ogg';
case 'webm':
return 'video/webm';
case 'srt':
return 'application/x-subrip';
case 'vtt':
return 'text/vtt';
case 'ass':
case 'ssa':
return 'text/x-ssa';
case 'jpg':
case 'jpeg':
return 'image/jpeg';
case 'png':
return 'image/png';
default:
return 'application/octet-stream';
}
}
/// Get path components for SAF based on media type
/// Returns list of directory names to create under the SAF base
List<String> getMovieSafPathComponents(PlexMetadata movie) {
-99
View File
@@ -1,11 +1,9 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:saf_util/saf_util.dart';
import '../utils/platform_detector.dart';
import 'package:saf_util/saf_util_platform_interface.dart';
import 'package:saf_stream/saf_stream.dart';
/// Handles Storage Access Framework (SAF) operations for Android
class SafStorageService {
@@ -14,7 +12,6 @@ class SafStorageService {
SafStorageService._();
final SafUtil _safUtil = SafUtil();
final SafStream _safStream = SafStream();
/// Check if SAF is available (Android only)
bool get isAvailable => Platform.isAndroid;
@@ -35,28 +32,6 @@ class SafStorageService {
}
}
/// Check if we have persisted access to a URI
Future<bool> hasPersistedPermission(String contentUri) async {
if (!isAvailable) return false;
try {
return await _safUtil.hasPersistedPermission(contentUri, checkRead: true, checkWrite: true);
} catch (e) {
debugPrint('SAF hasPersistedPermission error: $e');
return false;
}
}
/// Get document file info for a URI
Future<SafDocumentFile?> getDocumentFile(String contentUri, {bool isDir = true}) async {
if (!isAvailable) return null;
try {
return await _safUtil.documentFileFromUri(contentUri, isDir);
} catch (e) {
debugPrint('SAF getDocumentFile error: $e');
return null;
}
}
/// Create a subdirectory in a SAF directory
/// Returns the URI of the created directory
Future<String?> createDirectory(String parentUri, String name) async {
@@ -70,17 +45,6 @@ class SafStorageService {
}
}
/// List files in a SAF directory
Future<List<SafDocumentFile>> listDirectory(String contentUri) async {
if (!isAvailable) return [];
try {
return await _safUtil.list(contentUri);
} catch (e) {
debugPrint('SAF listDirectory error: $e');
return [];
}
}
/// Get a child file/directory in a SAF directory
Future<SafDocumentFile?> getChild(String parentUri, String name) async {
if (!isAvailable) return null;
@@ -92,30 +56,6 @@ class SafStorageService {
}
}
/// Delete a file or directory in SAF
Future<bool> delete(String contentUri, {bool isDir = false}) async {
if (!isAvailable) return false;
try {
await _safUtil.delete(contentUri, isDir);
return true;
} catch (e) {
debugPrint('SAF delete error: $e');
return false;
}
}
/// Get a display name for a SAF URI (for UI purposes)
Future<String?> getDisplayName(String contentUri) async {
if (!isAvailable) return null;
try {
final doc = await _safUtil.documentFileFromUri(contentUri, true);
return doc?.name;
} catch (e) {
debugPrint('SAF getDisplayName error: $e');
return null;
}
}
/// Create nested directories in a SAF directory
/// Returns the URI of the deepest directory
Future<String?> createNestedDirectories(String parentUri, List<String> pathComponents) async {
@@ -129,43 +69,4 @@ class SafStorageService {
}
}
/// Write bytes directly to a SAF file
/// Returns the SAF URI of the created file, or null on failure
Future<String?> writeFileBytes(String directoryUri, String fileName, String mimeType, Uint8List bytes) async {
if (!isAvailable) return null;
try {
final result = await _safStream.writeFileBytes(directoryUri, fileName, mimeType, bytes);
return result.uri.toString();
} catch (e) {
debugPrint('SAF writeFileBytes error: $e');
return null;
}
}
/// Read bytes from a SAF file
Future<Uint8List?> readFileBytes(String fileUri) async {
if (!isAvailable) return null;
try {
return await _safStream.readFileBytes(fileUri);
} catch (e) {
debugPrint('SAF readFileBytes error: $e');
return null;
}
}
/// Check if a file exists in a SAF directory
Future<bool> fileExists(String parentUri, String fileName) async {
if (!isAvailable) return false;
try {
final child = await _safUtil.child(parentUri, [fileName]);
return child != null;
} catch (e) {
debugPrint('SAF fileExists error: $e');
return false;
}
}
/// Get the content URI for a file that should be readable by MediaStore/media players
/// For SAF files, this returns the same URI as input (content:// URIs are already readable)
String getReadableUri(String safUri) => safUri;
}