mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-02-02 06:46:22 +01:00
159 lines
4 KiB
Dart
159 lines
4 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:logging/logging.dart';
|
|
import 'package:nc_photos/account.dart';
|
|
import 'package:nc_photos/string_extension.dart';
|
|
import 'package:np_codegen/np_codegen.dart';
|
|
import 'package:to_string/to_string.dart';
|
|
import 'package:xml/xml.dart';
|
|
|
|
part 'api.g.dart';
|
|
part 'direct_api.dart';
|
|
part 'face_recognition_api.dart';
|
|
part 'files_api.dart';
|
|
part 'files_sharing_api.dart';
|
|
part 'systemtag_api.dart';
|
|
|
|
@toString
|
|
class Response {
|
|
Response(this.statusCode, this.headers, this.body);
|
|
|
|
bool get isGood => _isHttpStatusGood(statusCode);
|
|
|
|
@override
|
|
String toString() => _$toString();
|
|
|
|
final int statusCode;
|
|
@Format(r"...")
|
|
final Map<String, String> headers;
|
|
|
|
/// Content of the response body, String if isResponseString == true during
|
|
/// request, Uint8List otherwise
|
|
@Format(
|
|
r"${kDebugMode ? body.toString().replaceAll(RegExp(r'\n\t'), '').slice(0, 200) : '...'}")
|
|
final dynamic body;
|
|
}
|
|
|
|
class BasicAuth {
|
|
BasicAuth(this.username, this.password);
|
|
|
|
BasicAuth.fromAccount(Account account)
|
|
: this(
|
|
account.username2,
|
|
account.password,
|
|
);
|
|
|
|
@override
|
|
toString() {
|
|
final authString = base64.encode(utf8.encode("$username:$password"));
|
|
return "Basic $authString";
|
|
}
|
|
|
|
final String username;
|
|
final String password;
|
|
}
|
|
|
|
@npLog
|
|
class Api {
|
|
Api(Account account)
|
|
: _baseUrl = Uri.parse(account.url),
|
|
_auth = BasicAuth.fromAccount(account);
|
|
|
|
Api.fromBaseUrl(Uri baseUrl) : _baseUrl = baseUrl;
|
|
|
|
ApiFiles files() => ApiFiles(this);
|
|
|
|
ApiOcs ocs() => ApiOcs(this);
|
|
|
|
ApiSystemtags systemtags() => ApiSystemtags(this);
|
|
|
|
ApiSystemtagsRelations systemtagsRelations() => ApiSystemtagsRelations(this);
|
|
|
|
static String getAuthorizationHeaderValue(Account account) {
|
|
return BasicAuth.fromAccount(account).toString();
|
|
}
|
|
|
|
Future<Response> request(
|
|
String method,
|
|
String endpoint, {
|
|
Map<String, String>? header,
|
|
Map<String, String>? queryParameters,
|
|
String? body,
|
|
Uint8List? bodyBytes,
|
|
bool isResponseString = true,
|
|
}) async {
|
|
final url = _makeUri(endpoint, queryParameters: queryParameters);
|
|
final req = http.Request(method, url);
|
|
if (_auth != null) {
|
|
req.headers.addAll({
|
|
"authorization": _auth.toString(),
|
|
});
|
|
}
|
|
if (header != null) {
|
|
// turn all to lower case, since HTTP headers are case-insensitive, this
|
|
// smooths our processing (if any)
|
|
req.headers.addEntries(
|
|
header.entries.map((e) => MapEntry(e.key.toLowerCase(), e.value)));
|
|
}
|
|
if (body != null) {
|
|
req.body = body;
|
|
} else if (bodyBytes != null) {
|
|
req.bodyBytes = bodyBytes;
|
|
}
|
|
final response =
|
|
await http.Response.fromStream(await http.Client().send(req));
|
|
if (!_isHttpStatusGood(response.statusCode)) {
|
|
if (response.statusCode == 404) {
|
|
_log.severe(
|
|
"[request] HTTP $method (${response.statusCode}): $endpoint",
|
|
);
|
|
} else {
|
|
_log.severe(
|
|
"[request] HTTP $method (${response.statusCode}): $endpoint",
|
|
response.body,
|
|
);
|
|
}
|
|
}
|
|
return Response(response.statusCode, response.headers,
|
|
isResponseString ? response.body : response.bodyBytes);
|
|
}
|
|
|
|
Uri _makeUri(
|
|
String endpoint, {
|
|
Map<String, String>? queryParameters,
|
|
}) {
|
|
final path = _baseUrl.path + "/$endpoint";
|
|
if (_baseUrl.scheme == "http") {
|
|
return Uri.http(_baseUrl.authority, path, queryParameters);
|
|
} else {
|
|
return Uri.https(_baseUrl.authority, path, queryParameters);
|
|
}
|
|
}
|
|
|
|
final Uri _baseUrl;
|
|
BasicAuth? _auth;
|
|
}
|
|
|
|
bool _isHttpStatusGood(int status) => status ~/ 100 == 2;
|
|
|
|
class ApiOcs {
|
|
ApiOcs(this._api);
|
|
|
|
ApiOcsDav dav() => ApiOcsDav(this);
|
|
|
|
ApiOcsFacerecognition facerecognition() => ApiOcsFacerecognition(this);
|
|
|
|
ApiOcsFilesSharing filesSharing() => ApiOcsFilesSharing(this);
|
|
|
|
final Api _api;
|
|
}
|
|
|
|
class ApiOcsDav {
|
|
ApiOcsDav(this._ocs);
|
|
|
|
ApiOcsDavDirect direct() => ApiOcsDavDirect(this);
|
|
|
|
final ApiOcs _ocs;
|
|
}
|