mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Fix: handle versioned PaperlessTasks response
This commit is contained in:
parent
b746b6f2d6
commit
337092f345
@ -413,3 +413,11 @@ Initial API version.
|
|||||||
list of strings. When creating or updating a custom field value of a
|
list of strings. When creating or updating a custom field value of a
|
||||||
document for a select type custom field, the value should be the `id` of
|
document for a select type custom field, the value should be the `id` of
|
||||||
the option whereas previously was the index of the option.
|
the option whereas previously was the index of the option.
|
||||||
|
|
||||||
|
#### Version 8
|
||||||
|
|
||||||
|
- PaperlessTask objects now have a `task_name` field which replaces the old
|
||||||
|
`type` field. The `type` field is now used to represent the way the task
|
||||||
|
was created. Additionally, the tasks endpoint now returns different types
|
||||||
|
of tasks other than simply 'file' tasks. See the API schema for more
|
||||||
|
information.
|
||||||
|
@ -3,7 +3,7 @@ const base_url = new URL(document.baseURI)
|
|||||||
export const environment = {
|
export const environment = {
|
||||||
production: true,
|
production: true,
|
||||||
apiBaseUrl: document.baseURI + 'api/',
|
apiBaseUrl: document.baseURI + 'api/',
|
||||||
apiVersion: '7',
|
apiVersion: '8',
|
||||||
appTitle: 'Paperless-ngx',
|
appTitle: 'Paperless-ngx',
|
||||||
version: '2.14.7',
|
version: '2.14.7',
|
||||||
webSocketHost: window.location.host,
|
webSocketHost: window.location.host,
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
export const environment = {
|
export const environment = {
|
||||||
production: false,
|
production: false,
|
||||||
apiBaseUrl: 'http://localhost:8000/api/',
|
apiBaseUrl: 'http://localhost:8000/api/',
|
||||||
apiVersion: '7',
|
apiVersion: '8',
|
||||||
appTitle: 'Paperless-ngx',
|
appTitle: 'Paperless-ngx',
|
||||||
version: 'DEVELOPMENT',
|
version: 'DEVELOPMENT',
|
||||||
webSocketHost: 'localhost:8000',
|
webSocketHost: 'localhost:8000',
|
||||||
|
@ -421,6 +421,15 @@ class OwnedObjectListSerializer(serializers.ListSerializer):
|
|||||||
return super().to_representation(documents)
|
return super().to_representation(documents)
|
||||||
|
|
||||||
|
|
||||||
|
class GetAPIVersionMixin:
|
||||||
|
def get_api_version(self):
|
||||||
|
return int(
|
||||||
|
self.context.get("request").version
|
||||||
|
if self.context.get("request")
|
||||||
|
else settings.REST_FRAMEWORK["DEFAULT_VERSION"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CorrespondentSerializer(MatchingModelSerializer, OwnedObjectSerializer):
|
class CorrespondentSerializer(MatchingModelSerializer, OwnedObjectSerializer):
|
||||||
last_correspondence = serializers.DateTimeField(read_only=True, required=False)
|
last_correspondence = serializers.DateTimeField(read_only=True, required=False)
|
||||||
|
|
||||||
@ -717,7 +726,7 @@ class ReadWriteSerializerMethodField(serializers.SerializerMethodField):
|
|||||||
return {self.field_name: data}
|
return {self.field_name: data}
|
||||||
|
|
||||||
|
|
||||||
class CustomFieldInstanceSerializer(serializers.ModelSerializer):
|
class CustomFieldInstanceSerializer(serializers.ModelSerializer, GetAPIVersionMixin):
|
||||||
field = serializers.PrimaryKeyRelatedField(queryset=CustomField.objects.all())
|
field = serializers.PrimaryKeyRelatedField(queryset=CustomField.objects.all())
|
||||||
value = ReadWriteSerializerMethodField(allow_null=True)
|
value = ReadWriteSerializerMethodField(allow_null=True)
|
||||||
|
|
||||||
@ -809,13 +818,6 @@ class CustomFieldInstanceSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def get_api_version(self):
|
|
||||||
return int(
|
|
||||||
self.context.get("request").version
|
|
||||||
if self.context.get("request")
|
|
||||||
else settings.REST_FRAMEWORK["DEFAULT_VERSION"],
|
|
||||||
)
|
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
ret = super().to_internal_value(data)
|
ret = super().to_internal_value(data)
|
||||||
|
|
||||||
@ -1709,7 +1711,7 @@ class UiSettingsViewSerializer(serializers.ModelSerializer):
|
|||||||
return ui_settings
|
return ui_settings
|
||||||
|
|
||||||
|
|
||||||
class TasksViewSerializer(OwnedObjectSerializer):
|
class TasksViewSerializer(OwnedObjectSerializer, GetAPIVersionMixin):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = PaperlessTask
|
model = PaperlessTask
|
||||||
fields = (
|
fields = (
|
||||||
@ -1752,6 +1754,13 @@ class TasksViewSerializer(OwnedObjectSerializer):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def to_representation(self, instance: PaperlessTask):
|
||||||
|
result = super().to_representation(instance)
|
||||||
|
if self.get_api_version() < 8:
|
||||||
|
# Older versions only returned file tasks (filtering handled in view) and had different naming scheme
|
||||||
|
result["type"] = "file"
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class RunTaskViewSerializer(serializers.Serializer):
|
class RunTaskViewSerializer(serializers.Serializer):
|
||||||
task_name = serializers.ChoiceField(
|
task_name = serializers.ChoiceField(
|
||||||
|
@ -370,3 +370,45 @@ class TestTasks(DirectoriesMixin, APITestCase):
|
|||||||
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
mock_check_sanity.assert_not_called()
|
mock_check_sanity.assert_not_called()
|
||||||
|
|
||||||
|
def test_handle_older_api_version(self):
|
||||||
|
"""
|
||||||
|
GIVEN:
|
||||||
|
- A request from the API with version < 8
|
||||||
|
WHEN:
|
||||||
|
- Tasks are requested
|
||||||
|
THEN:
|
||||||
|
- Only consume file tasks are returned and the type is 'file'
|
||||||
|
"""
|
||||||
|
|
||||||
|
task1 = PaperlessTask.objects.create(
|
||||||
|
task_id=str(uuid.uuid4()),
|
||||||
|
task_file_name="task_one.pdf",
|
||||||
|
task_name=PaperlessTask.TaskName.CONSUME_FILE,
|
||||||
|
)
|
||||||
|
|
||||||
|
task2 = PaperlessTask.objects.create(
|
||||||
|
task_id=str(uuid.uuid4()),
|
||||||
|
task_name=PaperlessTask.TaskName.CHECK_SANITY,
|
||||||
|
type=PaperlessTask.TaskType.AUTO,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self.client.get(
|
||||||
|
self.ENDPOINT,
|
||||||
|
headers={"Accept": "application/json; version=7"},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(len(response.data), 1)
|
||||||
|
self.assertEqual(response.data[0]["task_id"], task1.task_id)
|
||||||
|
self.assertEqual(response.data[0]["type"], "file")
|
||||||
|
|
||||||
|
response = self.client.get(
|
||||||
|
self.ENDPOINT,
|
||||||
|
headers={"Accept": "application/json; version=8"},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(len(response.data), 2)
|
||||||
|
self.assertEqual(response.data[0]["task_id"], task2.task_id)
|
||||||
|
self.assertEqual(response.data[0]["type"], PaperlessTask.TaskType.AUTO)
|
||||||
|
@ -2287,6 +2287,7 @@ class TasksViewSet(ReadOnlyModelViewSet):
|
|||||||
ObjectOwnedOrGrantedPermissionsFilter,
|
ObjectOwnedOrGrantedPermissionsFilter,
|
||||||
)
|
)
|
||||||
filterset_class = PaperlessTaskFilterSet
|
filterset_class = PaperlessTaskFilterSet
|
||||||
|
queryset = PaperlessTask.objects.all().order_by("-date_created")
|
||||||
|
|
||||||
TASK_AND_ARGS_BY_NAME = {
|
TASK_AND_ARGS_BY_NAME = {
|
||||||
PaperlessTask.TaskName.INDEX_OPTIMIZE: (index_optimize, {}),
|
PaperlessTask.TaskName.INDEX_OPTIMIZE: (index_optimize, {}),
|
||||||
@ -2301,11 +2302,22 @@ class TasksViewSet(ReadOnlyModelViewSet):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
queryset = PaperlessTask.objects.all().order_by("-date_created")
|
|
||||||
task_id = self.request.query_params.get("task_id")
|
task_id = self.request.query_params.get("task_id")
|
||||||
if task_id is not None:
|
if task_id is not None:
|
||||||
queryset = PaperlessTask.objects.filter(task_id=task_id)
|
return PaperlessTask.objects.filter(task_id=task_id)
|
||||||
return queryset
|
return super().get_queryset()
|
||||||
|
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
version = int(
|
||||||
|
request.version if request else settings.REST_FRAMEWORK["DEFAULT_VERSION"],
|
||||||
|
)
|
||||||
|
if version < 8:
|
||||||
|
# Previous API versions only had file tasks, the format is also different (handled in serializer)
|
||||||
|
self.queryset = PaperlessTask.objects.filter(
|
||||||
|
task_name=PaperlessTask.TaskName.CONSUME_FILE,
|
||||||
|
).order_by("-date_created")
|
||||||
|
|
||||||
|
return super().list(request, *args, **kwargs)
|
||||||
|
|
||||||
@action(methods=["post"], detail=False)
|
@action(methods=["post"], detail=False)
|
||||||
def acknowledge(self, request):
|
def acknowledge(self, request):
|
||||||
|
@ -345,7 +345,7 @@ REST_FRAMEWORK = {
|
|||||||
"DEFAULT_VERSION": "7",
|
"DEFAULT_VERSION": "7",
|
||||||
# Make sure these are ordered and that the most recent version appears
|
# Make sure these are ordered and that the most recent version appears
|
||||||
# last. See api.md#api-versioning when adding new versions.
|
# last. See api.md#api-versioning when adding new versions.
|
||||||
"ALLOWED_VERSIONS": ["1", "2", "3", "4", "5", "6", "7"],
|
"ALLOWED_VERSIONS": ["1", "2", "3", "4", "5", "6", "7", "8"],
|
||||||
# DRF Spectacular default schema
|
# DRF Spectacular default schema
|
||||||
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
|
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user