mangayomi-mirror/lib/providers/storage_provider.dart
NBA2K1 4d564b9308 Put the database into its separate folder
On Android, iOS and macOS just like how it's done on Windows and Linux.
Before the database files were in the top directory.
2025-07-12 05:30:26 +02:00

199 lines
6.1 KiB
Dart

// ignore_for_file: depend_on_referenced_packages
import 'dart:io';
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/source_preference.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/download.dart';
import 'package:mangayomi/models/update.dart';
import 'package:mangayomi/models/history.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/models/sync_preference.dart';
import 'package:mangayomi/models/track.dart';
import 'package:mangayomi/models/track_preference.dart';
import 'package:mangayomi/utils/extensions/string_extensions.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:path/path.dart' as path;
class StorageProvider {
static bool _hasPermission = false;
Future<bool> requestPermission() async {
if (_hasPermission) return true;
if (Platform.isAndroid) {
Permission permission = Permission.manageExternalStorage;
if (await permission.isGranted) {
return true;
} else {
final result = await permission.request();
if (result == PermissionStatus.granted) {
_hasPermission = true;
return true;
}
return false;
}
}
return true;
}
Future<void> deleteBtDirectory() async {
final d = await getBtDirectory();
await Directory(d!.path).delete(recursive: true);
}
Future<void> deleteTmpDirectory() async {
final d = await getTmpDirectory();
await Directory(d!.path).delete(recursive: true);
}
Future<Directory?> getDefaultDirectory() async {
Directory? directory;
if (Platform.isAndroid) {
directory = Directory("/storage/emulated/0/Mangayomi/");
} else {
final dir = await getApplicationDocumentsDirectory();
directory = Directory(path.join(dir.path, 'Mangayomi'));
}
return directory;
}
Future<Directory?> getBtDirectory() async {
final gefaultDirectory = await getDefaultDirectory();
String dbDir = path.join(gefaultDirectory!.path, 'torrents');
await Directory(dbDir).create(recursive: true);
return Directory(dbDir);
}
Future<Directory?> getTmpDirectory() async {
final gefaultDirectory = await getDirectory();
String dbDir = path.join(gefaultDirectory!.path, 'tmp');
await Directory(dbDir).create(recursive: true);
return Directory(dbDir);
}
Future<Directory?> getIosBackupDirectory() async {
final gefaultDirectory = await getDefaultDirectory();
String dbDir = path.join(gefaultDirectory!.path, 'backup');
await Directory(dbDir).create(recursive: true);
return Directory(dbDir);
}
Future<Directory?> getDirectory() async {
Directory? directory;
String dPath = isar.settings.getSync(227)!.downloadLocation ?? "";
if (Platform.isAndroid) {
directory = Directory(
dPath.isEmpty ? "/storage/emulated/0/Mangayomi/" : "$dPath/",
);
} else {
final dir = await getApplicationDocumentsDirectory();
final p = dPath.isEmpty ? dir.path : dPath;
directory = Directory(path.join(p, 'Mangayomi'));
}
return directory;
}
Future<Directory?> getMangaMainDirectory(Chapter chapter) async {
final manga = chapter.manga.value!;
final itemType = chapter.manga.value!.itemType;
final itemTypePath = itemType == ItemType.manga
? "Manga"
: itemType == ItemType.anime
? "Anime"
: "Novel";
final dir = await getDirectory();
return Directory(
path.join(
dir!.path,
'downloads',
itemTypePath,
'${manga.source} (${manga.lang!.toUpperCase()})',
manga.name!.replaceForbiddenCharacters('_'),
),
);
}
Future<Directory?> getMangaChapterDirectory(
Chapter chapter, {
Directory? mangaMainDirectory,
}) async {
final basedir = mangaMainDirectory ?? await getMangaMainDirectory(chapter);
String scanlator = chapter.scanlator?.isNotEmpty ?? false
? "${chapter.scanlator!.replaceForbiddenCharacters('_')}_"
: "";
return Directory(
path.join(
basedir!.path,
scanlator + chapter.name!.replaceForbiddenCharacters('_').trim(),
),
);
}
Future<Directory?> getDatabaseDirectory() async {
final dir = await getApplicationDocumentsDirectory();
if (Platform.isAndroid || Platform.isIOS || Platform.isMacOS) {
String dbDir = path.join(dir.path, 'databases');
await Directory(dbDir).create(recursive: true);
return Directory(dbDir);
} else {
String dbDir = path.join(dir.path, 'Mangayomi', 'databases');
await Directory(dbDir).create(recursive: true);
return Directory(dbDir);
}
}
Future<Directory?> getGalleryDirectory() async {
String gPath = (await getDirectory())!.path;
if (Platform.isAndroid) {
gPath = "/storage/emulated/0/Pictures/Mangayomi/";
} else {
gPath = path.join(gPath, 'Pictures');
}
await Directory(gPath).create(recursive: true);
return Directory(gPath);
}
Future<Isar> initDB(String? path, {bool? inspector = false}) async {
Directory? dir;
if (path == null) {
dir = await getDatabaseDirectory();
} else {
dir = Directory(path);
}
final isar = await Isar.open(
[
MangaSchema,
ChangedPartSchema,
ChapterSchema,
CategorySchema,
UpdateSchema,
HistorySchema,
DownloadSchema,
SourceSchema,
SettingsSchema,
TrackPreferenceSchema,
TrackSchema,
SyncPreferenceSchema,
SourcePreferenceSchema,
SourcePreferenceStringValueSchema,
],
directory: dir!.path,
name: "mangayomiDb",
inspector: inspector!,
);
final settings = await isar.settings.filter().idEqualTo(227).findFirst();
if (settings == null) {
await isar.writeTxn(() async {
isar.settings.put(Settings());
});
}
return isar;
}
}