mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-09 10:00:27 +00:00
feat: flutter ui integration
This commit is contained in:
1 parent
0fc133e46d
commit
c4a30dc4c2
170 files changed
+7783
-1
No files matched your search
@@ -0,0 +1,107 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dio/adapter.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:gopeed/api/model/create_task.dart';
|
||||
import 'package:gopeed/api/model/request.dart';
|
||||
import 'package:gopeed/api/model/resource.dart';
|
||||
import 'package:gopeed/api/model/result.dart';
|
||||
import 'package:gopeed/api/model/task.dart';
|
||||
|
||||
import '../core/libgopeed_boot.dart';
|
||||
import 'model/server_config.dart';
|
||||
|
||||
class _Client {
|
||||
static _Client? _instance;
|
||||
|
||||
late Dio dio;
|
||||
|
||||
_Client._internal();
|
||||
|
||||
factory _Client() {
|
||||
if (_instance == null) {
|
||||
_instance = _Client._internal();
|
||||
var dio = Dio();
|
||||
dio.options.baseUrl = "http://127.0.0.1:${LibgopeedBoot.instance.port}";
|
||||
_instance!.dio = dio;
|
||||
(_instance!.dio.httpClientAdapter as DefaultHttpClientAdapter)
|
||||
.onHttpClientCreate = (client) {
|
||||
if (LibgopeedBoot.instance.network == "unix") {
|
||||
client.connectionFactory =
|
||||
(Uri uri, String? proxyHost, int? proxyPort) {
|
||||
var address = InternetAddress(LibgopeedBoot.instance.address,
|
||||
type: InternetAddressType.unix);
|
||||
return Socket.startConnect(address, 0);
|
||||
};
|
||||
}
|
||||
return client;
|
||||
};
|
||||
}
|
||||
return _instance!;
|
||||
}
|
||||
}
|
||||
|
||||
var _client = _Client();
|
||||
|
||||
Future<T> _parse<T>(
|
||||
Future<Response> Function() fetch,
|
||||
T Function(dynamic json)? fromJsonT,
|
||||
) async {
|
||||
try {
|
||||
var resp = await fetch();
|
||||
if (fromJsonT != null) {
|
||||
return Result<T>.fromJson(jsonDecode(resp.data), fromJsonT).data as T;
|
||||
} else {
|
||||
return null as T;
|
||||
}
|
||||
} on DioError catch (e) {
|
||||
if (e.response == null) {
|
||||
throw Exception("Server error");
|
||||
}
|
||||
throw Exception(
|
||||
Result.fromJson(jsonDecode(e.response?.data), (_) => null).msg);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Resource> resolve(Request request) async {
|
||||
return _parse<Resource>(
|
||||
() => _client.dio.post("/api/v1/resolve", data: request),
|
||||
(data) => Resource.fromJson(data));
|
||||
}
|
||||
|
||||
Future<String> createTask(CreateTask createTask) async {
|
||||
print(jsonEncode(createTask));
|
||||
return _parse<String>(
|
||||
() => _client.dio.post("/api/v1/tasks", data: createTask),
|
||||
(data) => data as String);
|
||||
}
|
||||
|
||||
Future<List<Task>> getTasks(List<Status> statuses) async {
|
||||
return _parse<List<Task>>(
|
||||
() => _client.dio
|
||||
.get("/api/v1/tasks?status=${statuses.map((e) => e.name).join(",")}"),
|
||||
(data) => (data as List).map((e) => Task.fromJson(e)).toList());
|
||||
}
|
||||
|
||||
Future<void> pauseTask(String id) async {
|
||||
return _parse(() => _client.dio.put("/api/v1/tasks/$id/pause"), null);
|
||||
}
|
||||
|
||||
Future<void> continueTask(String id) async {
|
||||
return _parse(() => _client.dio.put("/api/v1/tasks/$id/continue"), null);
|
||||
}
|
||||
|
||||
Future<void> deleteTask(String id, bool force) async {
|
||||
return _parse(
|
||||
() => _client.dio.delete("/api/v1/tasks/$id?force=$force"), null);
|
||||
}
|
||||
|
||||
Future<ServerConfig> getConfig() async {
|
||||
return _parse(() => _client.dio.get("/api/v1/config"),
|
||||
(data) => ServerConfig.fromJson(data));
|
||||
}
|
||||
|
||||
Future<void> putConfig(ServerConfig config) async {
|
||||
return _parse(() => _client.dio.put("/api/v1/config", data: config), null);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'options.dart';
|
||||
import 'resource.dart';
|
||||
|
||||
part 'create_task.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class CreateTask {
|
||||
Resource res;
|
||||
Options? opts;
|
||||
|
||||
CreateTask({
|
||||
required this.res,
|
||||
this.opts,
|
||||
});
|
||||
|
||||
factory CreateTask.fromJson(Map<String, dynamic> json) =>
|
||||
_$CreateTaskFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$CreateTaskToJson(this);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'create_task.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
CreateTask _$CreateTaskFromJson(Map<String, dynamic> json) => CreateTask(
|
||||
res: Resource.fromJson(json['res'] as Map<String, dynamic>),
|
||||
opts: json['opts'] == null
|
||||
? null
|
||||
: Options.fromJson(json['opts'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$CreateTaskToJson(CreateTask instance) {
|
||||
final val = <String, dynamic>{
|
||||
'res': instance.res.toJson(),
|
||||
};
|
||||
|
||||
void writeNotNull(String key, dynamic value) {
|
||||
if (value != null) {
|
||||
val[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
writeNotNull('opts', instance.opts?.toJson());
|
||||
return val;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'options.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class Options {
|
||||
String name;
|
||||
String path;
|
||||
int connections;
|
||||
List<int> selectFiles;
|
||||
|
||||
Options({
|
||||
required this.name,
|
||||
required this.path,
|
||||
required this.connections,
|
||||
required this.selectFiles,
|
||||
});
|
||||
|
||||
factory Options.fromJson(Map<String, dynamic> json) =>
|
||||
_$OptionsFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$OptionsToJson(this);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'options.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Options _$OptionsFromJson(Map<String, dynamic> json) => Options(
|
||||
name: json['name'] as String,
|
||||
path: json['path'] as String,
|
||||
connections: json['connections'] as int,
|
||||
selectFiles:
|
||||
(json['selectFiles'] as List<dynamic>).map((e) => e as int).toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$OptionsToJson(Options instance) => <String, dynamic>{
|
||||
'name': instance.name,
|
||||
'path': instance.path,
|
||||
'connections': instance.connections,
|
||||
'selectFiles': instance.selectFiles,
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'request.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class Request {
|
||||
String url;
|
||||
Map<String, dynamic>? extra;
|
||||
|
||||
Request({
|
||||
required this.url,
|
||||
this.extra,
|
||||
});
|
||||
|
||||
factory Request.fromJson(Map<String, dynamic> json) =>
|
||||
_$RequestFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$RequestToJson(this);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'request.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Request _$RequestFromJson(Map<String, dynamic> json) => Request(
|
||||
url: json['url'] as String,
|
||||
extra: json['extra'] as Map<String, dynamic>?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$RequestToJson(Request instance) {
|
||||
final val = <String, dynamic>{
|
||||
'url': instance.url,
|
||||
};
|
||||
|
||||
void writeNotNull(String key, dynamic value) {
|
||||
if (value != null) {
|
||||
val[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
writeNotNull('extra', instance.extra);
|
||||
return val;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import 'request.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'resource.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class Resource {
|
||||
Request req;
|
||||
String name;
|
||||
int size;
|
||||
bool range;
|
||||
List<FileInfo> files;
|
||||
Map<String, dynamic>? extra;
|
||||
|
||||
Resource({
|
||||
required this.req,
|
||||
required this.name,
|
||||
required this.size,
|
||||
required this.range,
|
||||
required this.files,
|
||||
this.extra,
|
||||
});
|
||||
|
||||
factory Resource.fromJson(Map<String, dynamic> json) =>
|
||||
_$ResourceFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$ResourceToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class FileInfo {
|
||||
String name;
|
||||
String path;
|
||||
int size;
|
||||
|
||||
FileInfo({
|
||||
required this.name,
|
||||
required this.path,
|
||||
required this.size,
|
||||
});
|
||||
|
||||
factory FileInfo.fromJson(Map<String, dynamic> json) =>
|
||||
_$FileInfoFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$FileInfoToJson(this);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'resource.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Resource _$ResourceFromJson(Map<String, dynamic> json) => Resource(
|
||||
req: Request.fromJson(json['req'] as Map<String, dynamic>),
|
||||
name: json['name'] as String,
|
||||
size: json['size'] as int,
|
||||
range: json['range'] as bool,
|
||||
files: (json['files'] as List<dynamic>)
|
||||
.map((e) => FileInfo.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
extra: json['extra'] as Map<String, dynamic>?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ResourceToJson(Resource instance) {
|
||||
final val = <String, dynamic>{
|
||||
'req': instance.req.toJson(),
|
||||
'name': instance.name,
|
||||
'size': instance.size,
|
||||
'range': instance.range,
|
||||
'files': instance.files.map((e) => e.toJson()).toList(),
|
||||
};
|
||||
|
||||
void writeNotNull(String key, dynamic value) {
|
||||
if (value != null) {
|
||||
val[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
writeNotNull('extra', instance.extra);
|
||||
return val;
|
||||
}
|
||||
|
||||
FileInfo _$FileInfoFromJson(Map<String, dynamic> json) => FileInfo(
|
||||
name: json['name'] as String,
|
||||
path: json['path'] as String,
|
||||
size: json['size'] as int,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$FileInfoToJson(FileInfo instance) => <String, dynamic>{
|
||||
'name': instance.name,
|
||||
'path': instance.path,
|
||||
'size': instance.size,
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'result.g.dart';
|
||||
|
||||
@JsonSerializable(genericArgumentFactories: true)
|
||||
class Result<T> {
|
||||
String? msg;
|
||||
T? data;
|
||||
|
||||
Result({
|
||||
this.msg,
|
||||
this.data,
|
||||
});
|
||||
|
||||
factory Result.fromJson(
|
||||
Map<String, dynamic> json,
|
||||
T Function(dynamic json) fromJsonT,
|
||||
) =>
|
||||
_$ResultFromJson(json, fromJsonT);
|
||||
Map<String, dynamic> toJson() => {
|
||||
'msg': msg,
|
||||
'data': data is List
|
||||
? (data as dynamic)?.map((e) => e.toJson()).toList()
|
||||
: (data as dynamic)?.toJson(),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'result.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Result<T> _$ResultFromJson<T>(
|
||||
Map<String, dynamic> json,
|
||||
T Function(Object? json) fromJsonT,
|
||||
) =>
|
||||
Result<T>(
|
||||
msg: json['msg'] as String?,
|
||||
data: _$nullableGenericFromJson(json['data'], fromJsonT),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ResultToJson<T>(
|
||||
Result<T> instance,
|
||||
Object? Function(T value) toJsonT,
|
||||
) {
|
||||
final val = <String, dynamic>{};
|
||||
|
||||
void writeNotNull(String key, dynamic value) {
|
||||
if (value != null) {
|
||||
val[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
writeNotNull('msg', instance.msg);
|
||||
writeNotNull('data', _$nullableGenericToJson(instance.data, toJsonT));
|
||||
return val;
|
||||
}
|
||||
|
||||
T? _$nullableGenericFromJson<T>(
|
||||
Object? input,
|
||||
T Function(Object? json) fromJson,
|
||||
) =>
|
||||
input == null ? null : fromJson(input);
|
||||
|
||||
Object? _$nullableGenericToJson<T>(
|
||||
T? input,
|
||||
Object? Function(T value) toJson,
|
||||
) =>
|
||||
input == null ? null : toJson(input);
|
||||
@@ -0,0 +1,24 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'server_config.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class ServerConfig {
|
||||
late String host;
|
||||
late int port;
|
||||
late int connections;
|
||||
late String downloadDir;
|
||||
Map<String, dynamic>? extra;
|
||||
|
||||
ServerConfig({
|
||||
required this.host,
|
||||
required this.port,
|
||||
required this.connections,
|
||||
required this.downloadDir,
|
||||
this.extra,
|
||||
});
|
||||
|
||||
factory ServerConfig.fromJson(Map<String, dynamic> json) =>
|
||||
_$ServerConfigFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$ServerConfigToJson(this);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'server_config.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
ServerConfig _$ServerConfigFromJson(Map<String, dynamic> json) => ServerConfig(
|
||||
host: json['host'] as String,
|
||||
port: json['port'] as int,
|
||||
connections: json['connections'] as int,
|
||||
downloadDir: json['downloadDir'] as String,
|
||||
extra: json['extra'] as Map<String, dynamic>?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ServerConfigToJson(ServerConfig instance) {
|
||||
final val = <String, dynamic>{
|
||||
'host': instance.host,
|
||||
'port': instance.port,
|
||||
'connections': instance.connections,
|
||||
'downloadDir': instance.downloadDir,
|
||||
};
|
||||
|
||||
void writeNotNull(String key, dynamic value) {
|
||||
if (value != null) {
|
||||
val[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
writeNotNull('extra', instance.extra);
|
||||
return val;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import 'options.dart';
|
||||
import 'resource.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'task.g.dart';
|
||||
|
||||
enum Status { ready, running, pause, error, done }
|
||||
|
||||
@JsonSerializable()
|
||||
class Task {
|
||||
String id;
|
||||
Resource res;
|
||||
Options opts;
|
||||
Status status;
|
||||
Progress progress;
|
||||
int size;
|
||||
DateTime createdAt;
|
||||
|
||||
Task({
|
||||
required this.id,
|
||||
required this.res,
|
||||
required this.opts,
|
||||
required this.status,
|
||||
required this.progress,
|
||||
required this.size,
|
||||
required this.createdAt,
|
||||
});
|
||||
|
||||
factory Task.fromJson(Map<String, dynamic> json) => _$TaskFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$TaskToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class Progress {
|
||||
int used;
|
||||
int speed;
|
||||
int downloaded;
|
||||
|
||||
Progress({
|
||||
required this.used,
|
||||
required this.speed,
|
||||
required this.downloaded,
|
||||
});
|
||||
|
||||
factory Progress.fromJson(Map<String, dynamic> json) =>
|
||||
_$ProgressFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$ProgressToJson(this);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'task.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Task _$TaskFromJson(Map<String, dynamic> json) => Task(
|
||||
id: json['id'] as String,
|
||||
res: Resource.fromJson(json['res'] as Map<String, dynamic>),
|
||||
opts: Options.fromJson(json['opts'] as Map<String, dynamic>),
|
||||
status: $enumDecode(_$StatusEnumMap, json['status']),
|
||||
progress: Progress.fromJson(json['progress'] as Map<String, dynamic>),
|
||||
size: json['size'] as int,
|
||||
createdAt: DateTime.parse(json['createdAt'] as String),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$TaskToJson(Task instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'res': instance.res,
|
||||
'opts': instance.opts,
|
||||
'status': _$StatusEnumMap[instance.status]!,
|
||||
'progress': instance.progress,
|
||||
'size': instance.size,
|
||||
'createdAt': instance.createdAt.toIso8601String(),
|
||||
};
|
||||
|
||||
const _$StatusEnumMap = {
|
||||
Status.ready: 'ready',
|
||||
Status.running: 'running',
|
||||
Status.pause: 'pause',
|
||||
Status.error: 'error',
|
||||
Status.done: 'done',
|
||||
};
|
||||
|
||||
Progress _$ProgressFromJson(Map<String, dynamic> json) => Progress(
|
||||
used: json['used'] as int,
|
||||
speed: json['speed'] as int,
|
||||
downloaded: json['downloaded'] as int,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ProgressToJson(Progress instance) => <String, dynamic>{
|
||||
'used': instance.used,
|
||||
'speed': instance.speed,
|
||||
'downloaded': instance.downloaded,
|
||||
};
|
||||
Reference in new issue
Block a user