Add local profile
This commit is contained in:
@@ -4,20 +4,31 @@ import 'package:hiddify/domain/profiles/profiles.dart';
|
||||
|
||||
extension ProfileMapper on Profile {
|
||||
ProfileEntriesCompanion toCompanion() {
|
||||
return ProfileEntriesCompanion.insert(
|
||||
id: id,
|
||||
active: active,
|
||||
name: name,
|
||||
url: url,
|
||||
lastUpdate: lastUpdate,
|
||||
updateInterval: Value(options?.updateInterval),
|
||||
upload: Value(subInfo?.upload),
|
||||
download: Value(subInfo?.download),
|
||||
total: Value(subInfo?.total),
|
||||
expire: Value(subInfo?.expire),
|
||||
webPageUrl: Value(extra?.webPageUrl),
|
||||
supportUrl: Value(extra?.supportUrl),
|
||||
);
|
||||
return switch (this) {
|
||||
RemoteProfile(:final url, :final options, :final subInfo) =>
|
||||
ProfileEntriesCompanion.insert(
|
||||
id: id,
|
||||
type: ProfileType.remote,
|
||||
active: active,
|
||||
name: name,
|
||||
url: Value(url),
|
||||
lastUpdate: lastUpdate,
|
||||
updateInterval: Value(options?.updateInterval),
|
||||
upload: Value(subInfo?.upload),
|
||||
download: Value(subInfo?.download),
|
||||
total: Value(subInfo?.total),
|
||||
expire: Value(subInfo?.expire),
|
||||
webPageUrl: Value(subInfo?.webPageUrl),
|
||||
supportUrl: Value(subInfo?.supportUrl),
|
||||
),
|
||||
LocalProfile() => ProfileEntriesCompanion.insert(
|
||||
id: id,
|
||||
type: ProfileType.local,
|
||||
active: active,
|
||||
name: name,
|
||||
lastUpdate: lastUpdate,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
static Profile fromEntry(ProfileEntry e) {
|
||||
@@ -36,26 +47,27 @@ extension ProfileMapper on Profile {
|
||||
download: e.download!,
|
||||
total: e.total!,
|
||||
expire: e.expire!,
|
||||
);
|
||||
}
|
||||
|
||||
ProfileExtra? extra;
|
||||
if (e.webPageUrl != null || e.supportUrl != null) {
|
||||
extra = ProfileExtra(
|
||||
webPageUrl: e.webPageUrl,
|
||||
supportUrl: e.supportUrl,
|
||||
);
|
||||
}
|
||||
|
||||
return Profile(
|
||||
id: e.id,
|
||||
active: e.active,
|
||||
name: e.name,
|
||||
url: e.url,
|
||||
lastUpdate: e.lastUpdate,
|
||||
options: options,
|
||||
subInfo: subInfo,
|
||||
extra: extra,
|
||||
);
|
||||
return switch (e.type) {
|
||||
ProfileType.remote => RemoteProfile(
|
||||
id: e.id,
|
||||
active: e.active,
|
||||
name: e.name,
|
||||
url: e.url!,
|
||||
lastUpdate: e.lastUpdate,
|
||||
options: options,
|
||||
subInfo: subInfo,
|
||||
),
|
||||
ProfileType.local => LocalProfile(
|
||||
id: e.id,
|
||||
active: e.active,
|
||||
name: e.name,
|
||||
lastUpdate: e.lastUpdate,
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@ import 'dart:io';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/native.dart';
|
||||
import 'package:hiddify/data/local/dao/dao.dart';
|
||||
import 'package:hiddify/data/local/schema_versions.dart';
|
||||
import 'package:hiddify/data/local/tables.dart';
|
||||
import 'package:hiddify/data/local/type_converters.dart';
|
||||
import 'package:hiddify/domain/profiles/profiles.dart';
|
||||
import 'package:hiddify/services/files_editor_service.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
@@ -17,7 +19,31 @@ class AppDatabase extends _$AppDatabase {
|
||||
AppDatabase.connect() : super(_openConnection());
|
||||
|
||||
@override
|
||||
int get schemaVersion => 1;
|
||||
int get schemaVersion => 2;
|
||||
|
||||
@override
|
||||
MigrationStrategy get migration {
|
||||
return MigrationStrategy(
|
||||
onCreate: (Migrator m) async {
|
||||
await m.createAll();
|
||||
},
|
||||
onUpgrade: stepByStep(
|
||||
// add type column to profile entries table
|
||||
// make url column nullable
|
||||
from1To2: (m, schema) async {
|
||||
await m.alterTable(
|
||||
TableMigration(
|
||||
schema.profileEntries,
|
||||
columnTransformer: {
|
||||
schema.profileEntries.type: const Constant<String>("remote"),
|
||||
},
|
||||
newColumns: [schema.profileEntries.type],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
LazyDatabase _openConnection() {
|
||||
|
||||
136
lib/data/local/schema_versions.dart
Normal file
136
lib/data/local/schema_versions.dart
Normal file
@@ -0,0 +1,136 @@
|
||||
import 'package:drift/internal/versioned_schema.dart' as i0;
|
||||
import 'package:drift/drift.dart' as i1;
|
||||
import 'package:drift/drift.dart'; // ignore_for_file: type=lint,unused_import
|
||||
|
||||
// GENERATED BY drift_dev, DO NOT MODIFY.
|
||||
final class _S2 extends i0.VersionedSchema {
|
||||
_S2({required super.database}) : super(version: 2);
|
||||
@override
|
||||
late final List<i1.DatabaseSchemaEntity> entities = [
|
||||
profileEntries,
|
||||
];
|
||||
late final Shape0 profileEntries = Shape0(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'profile_entries',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [
|
||||
'PRIMARY KEY(id)',
|
||||
],
|
||||
columns: [
|
||||
_column_0,
|
||||
_column_1,
|
||||
_column_2,
|
||||
_column_3,
|
||||
_column_4,
|
||||
_column_5,
|
||||
_column_6,
|
||||
_column_7,
|
||||
_column_8,
|
||||
_column_9,
|
||||
_column_10,
|
||||
_column_11,
|
||||
_column_12,
|
||||
],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null);
|
||||
}
|
||||
|
||||
class Shape0 extends i0.VersionedTable {
|
||||
Shape0({required super.source, required super.alias}) : super.aliased();
|
||||
i1.GeneratedColumn<String> get id =>
|
||||
columnsByName['id']! as i1.GeneratedColumn<String>;
|
||||
i1.GeneratedColumn<String> get type =>
|
||||
columnsByName['type']! as i1.GeneratedColumn<String>;
|
||||
i1.GeneratedColumn<bool> get active =>
|
||||
columnsByName['active']! as i1.GeneratedColumn<bool>;
|
||||
i1.GeneratedColumn<String> get name =>
|
||||
columnsByName['name']! as i1.GeneratedColumn<String>;
|
||||
i1.GeneratedColumn<String> get url =>
|
||||
columnsByName['url']! as i1.GeneratedColumn<String>;
|
||||
i1.GeneratedColumn<DateTime> get lastUpdate =>
|
||||
columnsByName['last_update']! as i1.GeneratedColumn<DateTime>;
|
||||
i1.GeneratedColumn<int> get updateInterval =>
|
||||
columnsByName['update_interval']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get upload =>
|
||||
columnsByName['upload']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get download =>
|
||||
columnsByName['download']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get total =>
|
||||
columnsByName['total']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<DateTime> get expire =>
|
||||
columnsByName['expire']! as i1.GeneratedColumn<DateTime>;
|
||||
i1.GeneratedColumn<String> get webPageUrl =>
|
||||
columnsByName['web_page_url']! as i1.GeneratedColumn<String>;
|
||||
i1.GeneratedColumn<String> get supportUrl =>
|
||||
columnsByName['support_url']! as i1.GeneratedColumn<String>;
|
||||
}
|
||||
|
||||
i1.GeneratedColumn<String> _column_0(String aliasedName) =>
|
||||
i1.GeneratedColumn<String>('id', aliasedName, false,
|
||||
type: i1.DriftSqlType.string);
|
||||
i1.GeneratedColumn<String> _column_1(String aliasedName) =>
|
||||
i1.GeneratedColumn<String>('type', aliasedName, false,
|
||||
type: i1.DriftSqlType.string);
|
||||
i1.GeneratedColumn<bool> _column_2(String aliasedName) =>
|
||||
i1.GeneratedColumn<bool>('active', aliasedName, false,
|
||||
type: i1.DriftSqlType.bool,
|
||||
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
|
||||
'CHECK ("active" IN (0, 1))'));
|
||||
i1.GeneratedColumn<String> _column_3(String aliasedName) =>
|
||||
i1.GeneratedColumn<String>('name', aliasedName, false,
|
||||
additionalChecks: i1.GeneratedColumn.checkTextLength(
|
||||
minTextLength: 1,
|
||||
),
|
||||
type: i1.DriftSqlType.string);
|
||||
i1.GeneratedColumn<String> _column_4(String aliasedName) =>
|
||||
i1.GeneratedColumn<String>('url', aliasedName, true,
|
||||
type: i1.DriftSqlType.string);
|
||||
i1.GeneratedColumn<DateTime> _column_5(String aliasedName) =>
|
||||
i1.GeneratedColumn<DateTime>('last_update', aliasedName, false,
|
||||
type: i1.DriftSqlType.dateTime);
|
||||
i1.GeneratedColumn<int> _column_6(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>('update_interval', aliasedName, true,
|
||||
type: i1.DriftSqlType.int);
|
||||
i1.GeneratedColumn<int> _column_7(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>('upload', aliasedName, true,
|
||||
type: i1.DriftSqlType.int);
|
||||
i1.GeneratedColumn<int> _column_8(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>('download', aliasedName, true,
|
||||
type: i1.DriftSqlType.int);
|
||||
i1.GeneratedColumn<int> _column_9(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>('total', aliasedName, true,
|
||||
type: i1.DriftSqlType.int);
|
||||
i1.GeneratedColumn<DateTime> _column_10(String aliasedName) =>
|
||||
i1.GeneratedColumn<DateTime>('expire', aliasedName, true,
|
||||
type: i1.DriftSqlType.dateTime);
|
||||
i1.GeneratedColumn<String> _column_11(String aliasedName) =>
|
||||
i1.GeneratedColumn<String>('web_page_url', aliasedName, true,
|
||||
type: i1.DriftSqlType.string);
|
||||
i1.GeneratedColumn<String> _column_12(String aliasedName) =>
|
||||
i1.GeneratedColumn<String>('support_url', aliasedName, true,
|
||||
type: i1.DriftSqlType.string);
|
||||
i0.MigrationStepWithVersion migrationSteps({
|
||||
required Future<void> Function(i1.Migrator m, _S2 schema) from1To2,
|
||||
}) {
|
||||
return (currentVersion, database) async {
|
||||
switch (currentVersion) {
|
||||
case 1:
|
||||
final schema = _S2(database: database);
|
||||
final migrator = i1.Migrator(database, schema);
|
||||
await from1To2(migrator, schema);
|
||||
return 2;
|
||||
default:
|
||||
throw ArgumentError.value('Unknown migration from $currentVersion');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
i1.OnUpgrade stepByStep({
|
||||
required Future<void> Function(i1.Migrator m, _S2 schema) from1To2,
|
||||
}) =>
|
||||
i0.VersionedSchema.stepByStepHelper(
|
||||
step: migrationSteps(
|
||||
from1To2: from1To2,
|
||||
));
|
||||
160
lib/data/local/schemas/drift_schema_v1.json
Normal file
160
lib/data/local/schemas/drift_schema_v1.json
Normal file
@@ -0,0 +1,160 @@
|
||||
{
|
||||
"_meta": {
|
||||
"description": "This file contains a serialized version of schema entities for drift.",
|
||||
"version": "1.1.0"
|
||||
},
|
||||
"options": {
|
||||
"store_date_time_values_as_text": true
|
||||
},
|
||||
"entities": [
|
||||
{
|
||||
"id": 0,
|
||||
"references": [],
|
||||
"type": "table",
|
||||
"data": {
|
||||
"name": "profile_entries",
|
||||
"was_declared_in_moor": false,
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"getter_name": "id",
|
||||
"moor_type": "string",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "active",
|
||||
"getter_name": "active",
|
||||
"moor_type": "bool",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"defaultConstraints": "CHECK (\"active\" IN (0, 1))",
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"getter_name": "name",
|
||||
"moor_type": "string",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [
|
||||
{
|
||||
"allowed-lengths": {
|
||||
"min": 1,
|
||||
"max": null
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"getter_name": "url",
|
||||
"moor_type": "string",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "last_update",
|
||||
"getter_name": "lastUpdate",
|
||||
"moor_type": "dateTime",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "update_interval",
|
||||
"getter_name": "updateInterval",
|
||||
"moor_type": "int",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [],
|
||||
"type_converter": {
|
||||
"dart_expr": "DurationTypeConverter()",
|
||||
"dart_type_name": "Duration"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "upload",
|
||||
"getter_name": "upload",
|
||||
"moor_type": "int",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "download",
|
||||
"getter_name": "download",
|
||||
"moor_type": "int",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "total",
|
||||
"getter_name": "total",
|
||||
"moor_type": "int",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "expire",
|
||||
"getter_name": "expire",
|
||||
"moor_type": "dateTime",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "web_page_url",
|
||||
"getter_name": "webPageUrl",
|
||||
"moor_type": "string",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "support_url",
|
||||
"getter_name": "supportUrl",
|
||||
"moor_type": "string",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
}
|
||||
],
|
||||
"is_virtual": false,
|
||||
"without_rowid": false,
|
||||
"constraints": [],
|
||||
"explicit_pk": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
174
lib/data/local/schemas/drift_schema_v2.json
Normal file
174
lib/data/local/schemas/drift_schema_v2.json
Normal file
@@ -0,0 +1,174 @@
|
||||
{
|
||||
"_meta": {
|
||||
"description": "This file contains a serialized version of schema entities for drift.",
|
||||
"version": "1.1.0"
|
||||
},
|
||||
"options": {
|
||||
"store_date_time_values_as_text": true
|
||||
},
|
||||
"entities": [
|
||||
{
|
||||
"id": 0,
|
||||
"references": [],
|
||||
"type": "table",
|
||||
"data": {
|
||||
"name": "profile_entries",
|
||||
"was_declared_in_moor": false,
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"getter_name": "id",
|
||||
"moor_type": "string",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"getter_name": "type",
|
||||
"moor_type": "string",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [],
|
||||
"type_converter": {
|
||||
"dart_expr": "const EnumNameConverter<ProfileType>(ProfileType.values)",
|
||||
"dart_type_name": "ProfileType"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "active",
|
||||
"getter_name": "active",
|
||||
"moor_type": "bool",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"defaultConstraints": "CHECK (\"active\" IN (0, 1))",
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"getter_name": "name",
|
||||
"moor_type": "string",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [
|
||||
{
|
||||
"allowed-lengths": {
|
||||
"min": 1,
|
||||
"max": null
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"getter_name": "url",
|
||||
"moor_type": "string",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "last_update",
|
||||
"getter_name": "lastUpdate",
|
||||
"moor_type": "dateTime",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "update_interval",
|
||||
"getter_name": "updateInterval",
|
||||
"moor_type": "int",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [],
|
||||
"type_converter": {
|
||||
"dart_expr": "DurationTypeConverter()",
|
||||
"dart_type_name": "Duration"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "upload",
|
||||
"getter_name": "upload",
|
||||
"moor_type": "int",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "download",
|
||||
"getter_name": "download",
|
||||
"moor_type": "int",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "total",
|
||||
"getter_name": "total",
|
||||
"moor_type": "int",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "expire",
|
||||
"getter_name": "expire",
|
||||
"moor_type": "dateTime",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "web_page_url",
|
||||
"getter_name": "webPageUrl",
|
||||
"moor_type": "string",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "support_url",
|
||||
"getter_name": "supportUrl",
|
||||
"moor_type": "string",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
}
|
||||
],
|
||||
"is_virtual": false,
|
||||
"without_rowid": false,
|
||||
"constraints": [],
|
||||
"explicit_pk": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:hiddify/data/local/type_converters.dart';
|
||||
import 'package:hiddify/domain/profiles/profiles.dart';
|
||||
|
||||
@DataClassName('ProfileEntry')
|
||||
class ProfileEntries extends Table {
|
||||
TextColumn get id => text()();
|
||||
TextColumn get type => textEnum<ProfileType>()();
|
||||
BoolColumn get active => boolean()();
|
||||
TextColumn get name => text().withLength(min: 1)();
|
||||
TextColumn get url => text()();
|
||||
TextColumn get url => text().nullable()();
|
||||
DateTimeColumn get lastUpdate => dateTime()();
|
||||
IntColumn get updateInterval =>
|
||||
integer().nullable().map(DurationTypeConverter())();
|
||||
|
||||
@@ -72,7 +72,7 @@ class ProfilesRepositoryImpl
|
||||
return exceptionHandler(
|
||||
() async {
|
||||
final existingProfile = await profilesDao.getProfileByUrl(url);
|
||||
if (existingProfile != null) {
|
||||
if (existingProfile case RemoteProfile()) {
|
||||
loggy.info("profile with url[$url] already exists, updating");
|
||||
final baseProfile = markAsActive
|
||||
? existingProfile.copyWith(active: true)
|
||||
@@ -105,7 +105,49 @@ class ProfilesRepositoryImpl
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<ProfileFailure, Unit> add(Profile baseProfile) {
|
||||
TaskEither<ProfileFailure, Unit> addByContent(
|
||||
String content, {
|
||||
required String name,
|
||||
bool markAsActive = false,
|
||||
}) {
|
||||
return exceptionHandler(
|
||||
() async {
|
||||
final profileId = const Uuid().v4();
|
||||
final tempPath = filesEditor.tempConfigPath(profileId);
|
||||
final path = filesEditor.configPath(profileId);
|
||||
try {
|
||||
await File(tempPath).writeAsString(content);
|
||||
final parseResult =
|
||||
await singbox.parseConfig(path, tempPath, false).run();
|
||||
return parseResult.fold(
|
||||
(l) async {
|
||||
loggy.warning("error parsing config: $l");
|
||||
return left(ProfileFailure.invalidConfig(l.msg));
|
||||
},
|
||||
(_) async {
|
||||
final profile = LocalProfile(
|
||||
id: profileId,
|
||||
active: markAsActive,
|
||||
name: name,
|
||||
lastUpdate: DateTime.now(),
|
||||
);
|
||||
await profilesDao.create(profile);
|
||||
return right(unit);
|
||||
},
|
||||
);
|
||||
} finally {
|
||||
if (await File(tempPath).exists()) await File(tempPath).delete();
|
||||
}
|
||||
},
|
||||
(error, stackTrace) {
|
||||
loggy.warning("error adding profile by content", error, stackTrace);
|
||||
return ProfileUnexpectedFailure(error, stackTrace);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<ProfileFailure, Unit> add(RemoteProfile baseProfile) {
|
||||
return exceptionHandler(
|
||||
() async {
|
||||
return fetch(baseProfile.url, baseProfile.id)
|
||||
@@ -114,7 +156,6 @@ class ProfilesRepositoryImpl
|
||||
await profilesDao.create(
|
||||
baseProfile.copyWith(
|
||||
subInfo: remoteProfile.subInfo,
|
||||
extra: remoteProfile.extra,
|
||||
lastUpdate: DateTime.now(),
|
||||
),
|
||||
);
|
||||
@@ -131,7 +172,7 @@ class ProfilesRepositoryImpl
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<ProfileFailure, Unit> update(Profile baseProfile) {
|
||||
TaskEither<ProfileFailure, Unit> update(RemoteProfile baseProfile) {
|
||||
return exceptionHandler(
|
||||
() async {
|
||||
loggy.debug(
|
||||
@@ -143,7 +184,6 @@ class ProfilesRepositoryImpl
|
||||
await profilesDao.edit(
|
||||
baseProfile.copyWith(
|
||||
subInfo: remoteProfile.subInfo,
|
||||
extra: remoteProfile.extra,
|
||||
lastUpdate: DateTime.now(),
|
||||
),
|
||||
);
|
||||
@@ -209,13 +249,13 @@ class ProfilesRepositoryImpl
|
||||
];
|
||||
|
||||
@visibleForTesting
|
||||
TaskEither<ProfileFailure, Profile> fetch(
|
||||
TaskEither<ProfileFailure, RemoteProfile> fetch(
|
||||
String url,
|
||||
String fileName,
|
||||
) {
|
||||
return TaskEither(
|
||||
() async {
|
||||
final tempPath = filesEditor.configPath("temp_$fileName");
|
||||
final tempPath = filesEditor.tempConfigPath(fileName);
|
||||
final path = filesEditor.configPath(fileName);
|
||||
try {
|
||||
final response = await dio.download(url.trim(), tempPath);
|
||||
|
||||
Reference in New Issue
Block a user