WIP - Replaced get_it + injectable with Provider

This commit is contained in:
Anton Stubenbord
2022-12-21 01:14:06 +01:00
parent 10149fb7c1
commit 60aecb549d
59 changed files with 1099 additions and 1362 deletions

View File

@@ -1,12 +1,9 @@
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart';
import 'package:dio/dio.dart';
import 'package:paperless_api/src/models/paperless_server_exception.dart';
import 'package:paperless_api/src/modules/authentication_api/authentication_api.dart';
class PaperlessAuthenticationApiImpl implements PaperlessAuthenticationApi {
final BaseClient client;
final Dio client;
PaperlessAuthenticationApiImpl(this.client);
@@ -18,8 +15,8 @@ class PaperlessAuthenticationApiImpl implements PaperlessAuthenticationApi {
late Response response;
try {
response = await client.post(
Uri.parse("/api/token/"),
body: {
"/api/token/",
data: {
"username": username,
"password": password,
},
@@ -34,11 +31,11 @@ class PaperlessAuthenticationApiImpl implements PaperlessAuthenticationApi {
);
}
}
if (response.statusCode == HttpStatus.ok) {
final data = jsonDecode(utf8.decode(response.bodyBytes));
return data['token'];
} else if (response.statusCode == HttpStatus.badRequest &&
response.body
if (response.statusCode == 200) {
return response.data['token'];
} else if (response.statusCode == 400 &&
response
.data //TODO: Check if text is included in statusMessage instead of body
.toLowerCase()
.contains("no required certificate was sent")) {
throw PaperlessServerException(

View File

@@ -12,12 +12,10 @@ abstract class PaperlessDocumentsApi {
Uint8List documentBytes, {
required String filename,
required String title,
required String authToken,
required String serverUrl,
DateTime? createdAt,
int? documentType,
int? correspondent,
Iterable<int> tags = const [],
DateTime? createdAt,
});
Future<DocumentModel> update(DocumentModel doc);
Future<int> findNextAsn();

View File

@@ -1,94 +1,42 @@
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:http/src/boundary_characters.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_api/src/constants.dart';
import 'package:paperless_api/src/models/bulk_edit_model.dart';
import 'package:paperless_api/src/models/document_filter.dart';
import 'package:paperless_api/src/models/document_meta_data_model.dart';
import 'package:paperless_api/src/models/document_model.dart';
import 'package:paperless_api/src/models/paged_search_result.dart';
import 'package:paperless_api/src/models/paperless_server_exception.dart';
import 'package:paperless_api/src/models/query_parameters/sort_field.dart';
import 'package:paperless_api/src/models/query_parameters/sort_order.dart';
import 'package:paperless_api/src/models/similar_document_model.dart';
import 'paperless_documents_api.dart';
class PaperlessDocumentsApiImpl implements PaperlessDocumentsApi {
final BaseClient baseClient;
final HttpClient httpClient;
final Dio client;
PaperlessDocumentsApiImpl(this.baseClient, this.httpClient);
PaperlessDocumentsApiImpl(this.client);
@override
Future<void> create(
Uint8List documentBytes, {
required String filename,
required String title,
required String authToken,
required String serverUrl,
DateTime? createdAt,
int? documentType,
int? correspondent,
Iterable<int> tags = const [],
DateTime? createdAt,
}) async {
// The multipart request has to be generated from scratch as the http library does
// not allow the same key (tags) to be added multiple times. However, this is what the
// paperless api expects, i.e. one block for each tag.
final request = await httpClient.postUrl(
Uri.parse("$serverUrl/api/documents/post_document/"),
);
final formData = FormData();
final boundary = _boundaryString();
StringBuffer bodyBuffer = StringBuffer();
var fields = <String, String>{};
fields.putIfAbsent('title', () => title);
formData.fields.add(MapEntry('title', title));
if (createdAt != null) {
fields.putIfAbsent('created', () => apiDateFormat.format(createdAt));
formData.fields.add(MapEntry('created', apiDateFormat.format(createdAt)));
}
if (correspondent != null) {
fields.putIfAbsent('correspondent', () => jsonEncode(correspondent));
formData.fields.add(MapEntry('correspondent', jsonEncode(correspondent)));
}
if (documentType != null) {
fields.putIfAbsent('document_type', () => jsonEncode(documentType));
formData.fields.add(MapEntry('document_type', jsonEncode(documentType)));
}
for (final key in fields.keys) {
bodyBuffer.write(_buildMultipartField(key, fields[key]!, boundary));
}
for (final tag in tags) {
bodyBuffer.write(_buildMultipartField('tags', tag.toString(), boundary));
formData.fields.add(MapEntry('tags', tag.toString()));
}
bodyBuffer.write("--$boundary"
'\r\nContent-Disposition: form-data; name="document"; filename="$filename"'
"\r\nContent-type: application/octet-stream"
"\r\n\r\n");
final closing = "\r\n--$boundary--\r\n";
// Set headers
request.headers.set(HttpHeaders.contentTypeHeader,
"multipart/form-data; boundary=$boundary");
request.headers.set(HttpHeaders.contentLengthHeader,
"${bodyBuffer.length + closing.length + documentBytes.lengthInBytes}");
request.headers.set(HttpHeaders.authorizationHeader, "Token $authToken");
//Write fields to request
request.write(bodyBuffer.toString());
//Stream file
await request.addStream(Stream.fromIterable(documentBytes.map((e) => [e])));
// Write closing boundary to request
request.write(closing);
final response = await request.close();
final response =
await client.post('/api/documents/post_document/', data: formData);
if (response.statusCode != 200) {
throw PaperlessServerException(
ErrorCode.documentUploadFailed,
@@ -97,38 +45,14 @@ class PaperlessDocumentsApiImpl implements PaperlessDocumentsApi {
}
}
String _buildMultipartField(String fieldName, String value, String boundary) {
// ignore: prefer_interpolation_to_compose_strings
return '--$boundary'
'\r\nContent-Disposition: form-data; name="$fieldName"'
'\r\nContent-type: text/plain'
'\r\n\r\n' +
value +
'\r\n';
}
String _boundaryString() {
Random _random = Random();
var prefix = 'dart-http-boundary-';
var list = List<int>.generate(
70 - prefix.length,
(index) => boundaryCharacters[_random.nextInt(boundaryCharacters.length)],
growable: false,
);
return '$prefix${String.fromCharCodes(list)}';
}
@override
Future<DocumentModel> update(DocumentModel doc) async {
final response = await baseClient.put(
Uri.parse("/api/documents/${doc.id}/"),
body: json.encode(doc.toJson()),
headers: {"Content-Type": "application/json"},
final response = await client.put(
"/api/documents/${doc.id}/",
data: doc.toJson(),
);
if (response.statusCode == 200) {
return DocumentModel.fromJson(
jsonDecode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>,
);
return DocumentModel.fromJson(response.data);
} else {
throw const PaperlessServerException(ErrorCode.documentUpdateFailed);
}
@@ -137,17 +61,15 @@ class PaperlessDocumentsApiImpl implements PaperlessDocumentsApi {
@override
Future<PagedSearchResult<DocumentModel>> find(DocumentFilter filter) async {
final filterParams = filter.toQueryParameters();
final response = await baseClient.get(
Uri(
path: "/api/documents/",
queryParameters: filterParams,
),
final response = await client.get(
"/api/documents/",
queryParameters: filterParams,
);
if (response.statusCode == 200) {
return compute(
PagedSearchResult.fromJson,
PagedSearchResultJsonSerializer<DocumentModel>(
jsonDecode(utf8.decode(response.bodyBytes)),
response.data,
DocumentModel.fromJson,
),
);
@@ -158,8 +80,7 @@ class PaperlessDocumentsApiImpl implements PaperlessDocumentsApi {
@override
Future<int> delete(DocumentModel doc) async {
final response =
await baseClient.delete(Uri.parse("/api/documents/${doc.id}/"));
final response = await client.delete("/api/documents/${doc.id}/");
if (response.statusCode == 204) {
return Future.value(doc.id);
@@ -178,9 +99,14 @@ class PaperlessDocumentsApiImpl implements PaperlessDocumentsApi {
@override
Future<Uint8List> getPreview(int documentId) async {
final response = await baseClient.get(Uri.parse(getPreviewUrl(documentId)));
final response = await client.get(
getPreviewUrl(documentId),
options: Options(
responseType:
ResponseType.bytes), //TODO: Check if bytes or stream is required
);
if (response.statusCode == 200) {
return response.bodyBytes;
return response.data;
}
throw const PaperlessServerException(ErrorCode.documentPreviewFailed);
}
@@ -207,10 +133,9 @@ class PaperlessDocumentsApiImpl implements PaperlessDocumentsApi {
@override
Future<Iterable<int>> bulkAction(BulkAction action) async {
final response = await baseClient.post(
Uri.parse("/api/documents/bulk_edit/"),
body: json.encode(action.toJson()),
headers: {'Content-Type': 'application/json'},
final response = await client.post(
"/api/documents/bulk_edit/",
data: action.toJson(),
);
if (response.statusCode == 200) {
return action.documentIds;
@@ -241,40 +166,48 @@ class PaperlessDocumentsApiImpl implements PaperlessDocumentsApi {
@override
Future<Uint8List> download(DocumentModel document) async {
final response = await baseClient
.get(Uri.parse("/api/documents/${document.id}/download/"));
return response.bodyBytes;
//TODO: Add missing error handling
final response = await client.get(
"/api/documents/${document.id}/download/",
options: Options(responseType: ResponseType.bytes),
);
return response.data;
}
@override
Future<DocumentMetaData> getMetaData(DocumentModel document) async {
final response = await baseClient
.get(Uri.parse("/api/documents/${document.id}/metadata/"));
final response =
await client.get("/api/documents/${document.id}/metadata/");
return compute(
DocumentMetaData.fromJson,
jsonDecode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>,
response.data as Map<String, dynamic>,
);
}
@override
Future<List<String>> autocomplete(String query, [int limit = 10]) async {
final response = await baseClient
.get(Uri.parse("/api/search/autocomplete/?query=$query&limit=$limit}"));
final response = await client.get(
'/api/search/autocomplete/',
queryParameters: {
'query': query,
'limit': limit,
},
);
if (response.statusCode == 200) {
return jsonDecode(utf8.decode(response.bodyBytes)) as List<String>;
return response.data as List<String>;
}
throw const PaperlessServerException(ErrorCode.autocompleteQueryError);
}
@override
Future<List<SimilarDocumentModel>> findSimilar(int docId) async {
final response = await baseClient
.get(Uri.parse("/api/documents/?more_like=$docId&pageSize=10"));
final response =
await client.get("/api/documents/?more_like=$docId&pageSize=10");
if (response.statusCode == 200) {
return (await compute(
PagedSearchResult<SimilarDocumentModel>.fromJson,
PagedSearchResultJsonSerializer(
jsonDecode(utf8.decode(response.bodyBytes)),
response.data,
SimilarDocumentModel.fromJson,
),
))

View File

@@ -1,17 +1,19 @@
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart';
import 'package:dio/dio.dart';
import 'package:paperless_api/src/models/labels/correspondent_model.dart';
import 'package:paperless_api/src/models/labels/document_type_model.dart';
import 'package:paperless_api/src/models/labels/storage_path_model.dart';
import 'package:paperless_api/src/models/labels/tag_model.dart';
import 'package:paperless_api/src/models/paperless_server_exception.dart';
import 'package:paperless_api/src/modules/labels_api/paperless_labels_api.dart';
import 'package:paperless_api/src/utils.dart';
import 'package:paperless_api/src/request_utils.dart';
//Notes:
// Removed content type json header
class PaperlessLabelApiImpl implements PaperlessLabelsApi {
final BaseClient client;
final Dio client;
PaperlessLabelApiImpl(this.client);
@override
@@ -89,15 +91,11 @@ class PaperlessLabelApiImpl implements PaperlessLabelsApi {
@override
Future<Correspondent> saveCorrespondent(Correspondent correspondent) async {
final response = await client.post(
Uri.parse('/api/correspondents/'),
body: jsonEncode(correspondent.toJson()),
headers: {"Content-Type": "application/json"},
encoding: Encoding.getByName("utf-8"),
'/api/correspondents/',
data: correspondent.toJson(),
);
if (response.statusCode == HttpStatus.created) {
return Correspondent.fromJson(
jsonDecode(utf8.decode(response.bodyBytes)),
);
return Correspondent.fromJson(response.data);
}
throw PaperlessServerException(
ErrorCode.correspondentCreateFailed,
@@ -108,15 +106,11 @@ class PaperlessLabelApiImpl implements PaperlessLabelsApi {
@override
Future<DocumentType> saveDocumentType(DocumentType type) async {
final response = await client.post(
Uri.parse('/api/document_types/'),
body: json.encode(type.toJson()),
headers: {"Content-Type": "application/json"},
encoding: Encoding.getByName("utf-8"),
'/api/document_types/',
data: type.toJson(),
);
if (response.statusCode == HttpStatus.created) {
return DocumentType.fromJson(
jsonDecode(utf8.decode(response.bodyBytes)),
);
return DocumentType.fromJson(response.data);
}
throw PaperlessServerException(
ErrorCode.documentTypeCreateFailed,
@@ -126,18 +120,13 @@ class PaperlessLabelApiImpl implements PaperlessLabelsApi {
@override
Future<Tag> saveTag(Tag tag) async {
final body = json.encode(tag.toJson());
final response = await client.post(
Uri.parse('/api/tags/'),
body: body,
headers: {
"Content-Type": "application/json",
"Accept": "application/json; version=2",
},
encoding: Encoding.getByName("utf-8"),
'/api/tags/',
data: tag.toJson(),
options: Options(headers: {"Accept": "application/json; version=2"}),
);
if (response.statusCode == HttpStatus.created) {
return Tag.fromJson(jsonDecode(utf8.decode(response.bodyBytes)));
return Tag.fromJson(response.data);
}
throw PaperlessServerException(
ErrorCode.tagCreateFailed,
@@ -148,8 +137,8 @@ class PaperlessLabelApiImpl implements PaperlessLabelsApi {
@override
Future<int> deleteCorrespondent(Correspondent correspondent) async {
assert(correspondent.id != null);
final response = await client
.delete(Uri.parse('/api/correspondents/${correspondent.id}/'));
final response =
await client.delete('/api/correspondents/${correspondent.id}/');
if (response.statusCode == HttpStatus.noContent) {
return correspondent.id!;
}
@@ -162,8 +151,8 @@ class PaperlessLabelApiImpl implements PaperlessLabelsApi {
@override
Future<int> deleteDocumentType(DocumentType documentType) async {
assert(documentType.id != null);
final response = await client
.delete(Uri.parse('/api/document_types/${documentType.id}/'));
final response =
await client.delete('/api/document_types/${documentType.id}/');
if (response.statusCode == HttpStatus.noContent) {
return documentType.id!;
}
@@ -176,7 +165,7 @@ class PaperlessLabelApiImpl implements PaperlessLabelsApi {
@override
Future<int> deleteTag(Tag tag) async {
assert(tag.id != null);
final response = await client.delete(Uri.parse('/api/tags/${tag.id}/'));
final response = await client.delete('/api/tags/${tag.id}/');
if (response.statusCode == HttpStatus.noContent) {
return tag.id!;
}
@@ -190,17 +179,14 @@ class PaperlessLabelApiImpl implements PaperlessLabelsApi {
Future<Correspondent> updateCorrespondent(Correspondent correspondent) async {
assert(correspondent.id != null);
final response = await client.put(
Uri.parse('/api/correspondents/${correspondent.id}/'),
headers: {"Content-Type": "application/json"},
body: json.encode(correspondent.toJson()),
encoding: Encoding.getByName("utf-8"),
'/api/correspondents/${correspondent.id}/',
data: json.encode(correspondent.toJson()),
);
if (response.statusCode == HttpStatus.ok) {
return Correspondent.fromJson(
jsonDecode(utf8.decode(response.bodyBytes)));
return Correspondent.fromJson(response.data);
}
throw PaperlessServerException(
ErrorCode.unknown,
ErrorCode.unknown, //TODO: Add correct error code mapping.
httpStatusCode: response.statusCode,
);
}
@@ -209,13 +195,11 @@ class PaperlessLabelApiImpl implements PaperlessLabelsApi {
Future<DocumentType> updateDocumentType(DocumentType documentType) async {
assert(documentType.id != null);
final response = await client.put(
Uri.parse('/api/document_types/${documentType.id}/'),
headers: {"Content-Type": "application/json"},
body: json.encode(documentType.toJson()),
encoding: Encoding.getByName("utf-8"),
'/api/document_types/${documentType.id}/',
data: documentType.toJson(),
);
if (response.statusCode == HttpStatus.ok) {
return DocumentType.fromJson(jsonDecode(utf8.decode(response.bodyBytes)));
return DocumentType.fromJson(response.data);
}
throw PaperlessServerException(
ErrorCode.unknown,
@@ -227,16 +211,12 @@ class PaperlessLabelApiImpl implements PaperlessLabelsApi {
Future<Tag> updateTag(Tag tag) async {
assert(tag.id != null);
final response = await client.put(
Uri.parse('/api/tags/${tag.id}/'),
headers: {
"Accept": "application/json; version=2",
"Content-Type": "application/json",
},
body: json.encode(tag.toJson()),
encoding: Encoding.getByName("utf-8"),
'/api/tags/${tag.id}/',
options: Options(headers: {"Accept": "application/json; version=2"}),
data: tag.toJson(),
);
if (response.statusCode == HttpStatus.ok) {
return Tag.fromJson(jsonDecode(utf8.decode(response.bodyBytes)));
return Tag.fromJson(response.data);
}
throw PaperlessServerException(
ErrorCode.unknown,
@@ -247,8 +227,7 @@ class PaperlessLabelApiImpl implements PaperlessLabelsApi {
@override
Future<int> deleteStoragePath(StoragePath path) async {
assert(path.id != null);
final response =
await client.delete(Uri.parse('/api/storage_paths/${path.id}/'));
final response = await client.delete('/api/storage_paths/${path.id}/');
if (response.statusCode == HttpStatus.noContent) {
return path.id!;
}
@@ -285,12 +264,11 @@ class PaperlessLabelApiImpl implements PaperlessLabelsApi {
@override
Future<StoragePath> saveStoragePath(StoragePath path) async {
final response = await client.post(
Uri.parse('/api/storage_paths/'),
body: json.encode(path.toJson()),
headers: {"Content-Type": "application/json"},
'/api/storage_paths/',
data: path.toJson(),
);
if (response.statusCode == HttpStatus.created) {
return StoragePath.fromJson(jsonDecode(utf8.decode(response.bodyBytes)));
return StoragePath.fromJson(jsonDecode(response.data));
}
throw PaperlessServerException(ErrorCode.storagePathCreateFailed,
httpStatusCode: response.statusCode);
@@ -300,12 +278,11 @@ class PaperlessLabelApiImpl implements PaperlessLabelsApi {
Future<StoragePath> updateStoragePath(StoragePath path) async {
assert(path.id != null);
final response = await client.put(
Uri.parse('/api/storage_paths/${path.id}/'),
headers: {"Content-Type": "application/json"},
body: json.encode(path.toJson()),
'/api/storage_paths/${path.id}/',
data: path.toJson(),
);
if (response.statusCode == HttpStatus.ok) {
return StoragePath.fromJson(jsonDecode(utf8.decode(response.bodyBytes)));
return StoragePath.fromJson(jsonDecode(response.data));
}
throw const PaperlessServerException(ErrorCode.unknown);
}

View File

@@ -1,15 +1,15 @@
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart';
import 'package:dio/dio.dart';
import 'package:paperless_api/src/models/paperless_server_exception.dart';
import 'package:paperless_api/src/models/saved_view_model.dart';
import 'package:paperless_api/src/utils.dart';
import 'package:paperless_api/src/request_utils.dart';
import 'paperless_saved_views_api.dart';
class PaperlessSavedViewsApiImpl implements PaperlessSavedViewsApi {
final BaseClient client;
final Dio client;
PaperlessSavedViewsApiImpl(this.client);
@@ -28,12 +28,11 @@ class PaperlessSavedViewsApiImpl implements PaperlessSavedViewsApi {
@override
Future<SavedView> save(SavedView view) async {
final response = await client.post(
Uri.parse("/api/saved_views/"),
body: jsonEncode(view.toJson()),
headers: {'Content-Type': 'application/json'},
"/api/saved_views/",
data: view.toJson(),
);
if (response.statusCode == HttpStatus.created) {
return SavedView.fromJson(jsonDecode(utf8.decode(response.bodyBytes)));
return SavedView.fromJson(response.data);
}
throw PaperlessServerException(
ErrorCode.createSavedViewError,
@@ -43,8 +42,7 @@ class PaperlessSavedViewsApiImpl implements PaperlessSavedViewsApi {
@override
Future<int> delete(SavedView view) async {
final response =
await client.delete(Uri.parse("/api/saved_views/${view.id}/"));
final response = await client.delete("/api/saved_views/${view.id}/");
if (response.statusCode == HttpStatus.noContent) {
return view.id!;
}

View File

@@ -1,5 +1,6 @@
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:http/http.dart';
import 'package:paperless_api/src/models/paperless_server_exception.dart';
import 'package:paperless_api/src/models/paperless_server_information_model.dart';
@@ -13,25 +14,24 @@ import 'paperless_server_stats_api.dart';
/// inbox and total number of documents.
///
class PaperlessServerStatsApiImpl implements PaperlessServerStatsApi {
final BaseClient client;
final Dio client;
PaperlessServerStatsApiImpl(this.client);
@override
Future<PaperlessServerInformationModel> getServerInformation() async {
final response = await client.get(Uri.parse("/api/ui_settings/"));
final version =
response.headers[PaperlessServerInformationModel.versionHeader] ??
'unknown';
final apiVersion = int.tryParse(
response.headers[PaperlessServerInformationModel.apiVersionHeader] ??
'1');
final String username =
jsonDecode(utf8.decode(response.bodyBytes))['username'];
final response = await client.get("/api/ui_settings/");
final version = response
.headers[PaperlessServerInformationModel.versionHeader]?.first ??
'unknown';
final apiVersion = int.tryParse(response
.headers[PaperlessServerInformationModel.apiVersionHeader]?.first ??
'1');
final String username = response.data['username'];
final String host = response
.headers[PaperlessServerInformationModel.hostHeader] ??
response.request?.headers[PaperlessServerInformationModel.hostHeader] ??
('${response.request?.url.host}:${response.request?.url.port}');
.headers[PaperlessServerInformationModel.hostHeader]?.first ??
response.headers[PaperlessServerInformationModel.hostHeader]?.first ??
('${response.requestOptions.uri.host}:${response.requestOptions.uri.port}');
return PaperlessServerInformationModel(
username: username,
version: version,
@@ -42,11 +42,9 @@ class PaperlessServerStatsApiImpl implements PaperlessServerStatsApi {
@override
Future<PaperlessServerStatisticsModel> getServerStatistics() async {
final response = await client.get(Uri.parse('/api/statistics/'));
final response = await client.get('/api/statistics/');
if (response.statusCode == 200) {
return PaperlessServerStatisticsModel.fromJson(
jsonDecode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>,
);
return PaperlessServerStatisticsModel.fromJson(response.data);
}
throw const PaperlessServerException.unknown();
}

View File

@@ -1,25 +1,26 @@
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:paperless_api/src/models/paperless_server_exception.dart';
Future<T> getSingleResult<T>(
String url,
T Function(Map<String, dynamic>) fromJson,
ErrorCode errorCode, {
required BaseClient client,
required Dio client,
int minRequiredApiVersion = 1,
}) async {
final response = await client.get(
Uri.parse(url),
headers: {'accept': 'application/json; version=$minRequiredApiVersion'},
url,
options: Options(
headers: {'accept': 'application/json; version=$minRequiredApiVersion'},
),
);
if (response.statusCode == HttpStatus.ok) {
return compute(
fromJson,
jsonDecode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>,
response.data as Map<String, dynamic>,
);
}
throw PaperlessServerException(
@@ -32,16 +33,17 @@ Future<List<T>> getCollection<T>(
String url,
T Function(Map<String, dynamic>) fromJson,
ErrorCode errorCode, {
required BaseClient client,
required Dio client,
int minRequiredApiVersion = 1,
}) async {
final response = await client.get(
Uri.parse(url),
headers: {'accept': 'application/json; version=$minRequiredApiVersion'},
url,
options: Options(headers: {
'accept': 'application/json; version=$minRequiredApiVersion'
}),
);
if (response.statusCode == HttpStatus.ok) {
final Map<String, dynamic> body =
jsonDecode(utf8.decode(response.bodyBytes));
final Map<String, dynamic> body = response.data;
if (body.containsKey('count')) {
if (body['count'] == 0) {
return <T>[];

View File

@@ -17,7 +17,8 @@ dependencies:
http: ^0.13.5
json_annotation: ^4.7.0
intl: ^0.17.0
dio: ^4.0.6
dev_dependencies:
flutter_test:
sdk: flutter