Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proofreading api with single page checkout #975

Merged
merged 11 commits into from
May 4, 2024
597 changes: 597 additions & 0 deletions SETUP/tests/ApiTest.php

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions SETUP/tests/ProjectUtils.inc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ProjectUtils extends PHPUnit\Framework\TestCase
];
protected $created_projectids = [];
protected $TEST_TEXT = "This is a test file";
protected $TEST_MODIFIED_TEXT = "This is a modified test file";

protected function setUp(): void
{
Expand Down Expand Up @@ -94,6 +95,13 @@ class ProjectUtils extends PHPUnit\Framework\TestCase
$this->quiet_project_transition($projectid, PROJ_P2_AVAILABLE, PT_AUTO);
}

protected function advance_to_round3($projectid)
{
$this->quiet_project_transition($projectid, PROJ_P2_COMPLETE, PT_AUTO);
$this->quiet_project_transition($projectid, PROJ_P3_WAITING_FOR_RELEASE, PT_AUTO);
$this->quiet_project_transition($projectid, PROJ_P3_AVAILABLE, PT_AUTO);
}

protected function _create_project_with_pages($npage = 1)
{
$project = $this->_create_project();
Expand Down
251 changes: 251 additions & 0 deletions api/dp-openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,139 @@ paths:
default:
$ref: '#/components/responses/UnexpectedError'

/projects/{projectid}/checkout:
put:
tags:
- project
description: Check out a page for proofreading and return page-level details (current text, image name, etc).
parameters:
- $ref: '#/components/parameters/projectid'
- $ref: '#/components/parameters/state_query'
responses:
200:
description: page data
content:
application/json:
schema:
$ref: '#/components/schemas/proof_page'
'400':
$ref: '#/components/responses/InvalidValue'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimitExceeded'
default:
$ref: '#/components/responses/UnexpectedError'

/projects/{projectid}/validatetext:
put:
tags:
- project
description: Checks the given text for invalid characters, returns data indicating them
parameters:
- $ref: '#/components/parameters/projectid'
requestBody:
$ref: '#/components/requestBodies/page_text'
responses:
200:
description: analysis data
content:
application/json:
schema:
$ref: '#/components/schemas/text_analysis'
'400':
$ref: '#/components/responses/InvalidValue'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimitExceeded'
default:
$ref: '#/components/responses/UnexpectedError'

/projects/{projectid}/pages/{pagename}:
put:
tags:
- project
description: Various operations on the page as determined by the 'pageaction' parameter
parameters:
- $ref: '#/components/parameters/projectid'
- $ref: '#/components/parameters/state_query'
- $ref: '#/components/parameters/pagename'
- $ref: '#/components/parameters/pagestate_query'
- name: pageaction
in: query
description: Action to perform on the page.
<br><br>
resume - The page state can be 'out', 'temp' or 'saved'. If the state is 'saved' it is changed to 'temp'. Returns page-level details (current text, image name, etc). Response:- proof_page object.
<br><br>
checkin - Checks the page for invalid characters and if valid, saves it as done. Response:- checkin_response object.
<br><br>
save - Checks the page for invalid characters and if valid, saves it as in progress. Response:- page_text_state object.
<br><br>
revert - Checks the page for invalid characters and if valid, saves it as in progress. Response:- page_text_state object.
<br><br>
abandon - Returns the page to the round, response:- none.
required: true
schema:
type: string
requestBody:
$ref: '#/components/requestBodies/page_text'
responses:
200:
description: Page data
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/checkin_response'
- $ref: '#/components/schemas/proof_page'
- $ref: '#/components/schemas/page_text_state'
'400':
$ref: '#/components/responses/InvalidValue'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimitExceeded'
default:
$ref: '#/components/responses/UnexpectedError'

get:
tags:
- project
description: Get page text and state
parameters:
- $ref: '#/components/parameters/projectid'
- $ref: '#/components/parameters/pagename'
responses:
200:
description: Page data
content:
application/json:
schema:
$ref: '#/components/schemas/page_text_state'
'400':
$ref: '#/components/responses/InvalidValue'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimitExceeded'
default:
$ref: '#/components/responses/UnexpectedError'

/stats/site:
get:
tags:
Expand Down Expand Up @@ -1009,6 +1142,50 @@ components:
in: header
name: X-API-KEY

parameters:
projectid:
70ray marked this conversation as resolved.
Show resolved Hide resolved
name: projectid
in: path
description: ID of project
required: true
schema:
type: string

state_query:
name: state
in: query
description: Project state
required: true
schema:
type: string

pagename:
name: pagename
in: path
description: Name of page
required: true
schema:
type: string

pagestate_query:
name: pagestate
in: query
description: Page state
required: true
schema:
type: string

requestBodies:
page_text:
description: Text to save or analyse
content:
application/json:
schema:
type: object
properties:
text:
type: string

schemas:
project:
required:
Expand Down Expand Up @@ -1370,6 +1547,74 @@ components:
items:
type: string

proof_page:
type: object
properties:
text:
description: The page text. If page state is 'out' from OCR or previous round, else from current round
type: string
pagestate:
description: The page state, for checking continuity. Either out or temp
type: string
saved:
description: True if the page state is 'temp'
type: boolean
pagename:
description: The filename of the page with extension
type: string
image_url:
description: URL of the image of the page
type: string
language_direction:
description: left-to-right or right-to-left
type: string
enum: [RTL, LTR]
pagenum:
description: Page "number" without extension
type: string
round_info:
description: Array of names of proofreaders in earlier rounds
type: array
items:
type: string

checkin_response:
type: object
properties:
message:
description: message if reached limit, else empty string.
type: string
status:
description: 1 if limit reached, else 0
type: integer

page_text_state:
type: object
properties:
text:
description: The page text, current or original.
type: string
pagestate:
description: The page state, it is now in a 'temp' state since this is returned by save-as-in-progress or save-and-revert-to-original
type: string
saved:
70ray marked this conversation as resolved.
Show resolved Hide resolved
description: true if the page has been saved.
type: boolean

text_analysis:
type: object
properties:
valid:
type: boolean
mark_array:
type: array
items:
type: array
items:
oneOf:
- type: string
- type: integer

Error:
required:
- message
Expand All @@ -1394,6 +1639,12 @@ components:
application/json:
schema:
$ref: '#/components/schemas/Error'
Forbidden:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
InvalidValue:
description: Invalid Value
content:
Expand Down
13 changes: 13 additions & 0 deletions api/exceptions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,19 @@ class InvalidValue extends ApiException
}
}

class ForbiddenError extends ApiException
70ray marked this conversation as resolved.
Show resolved Hide resolved
{
public function __construct($message = "Forbidden", $code = 7)
{
parent::__construct($message, $code);
}

public function getStatusCode()
{
return 403;
}
}

//---------------------------------------------------------------------------
// Exceptions that shouldn't happen unless someone is futzing with something
// they shouldn't be, or there's an unexpected problem.
Expand Down
5 changes: 5 additions & 0 deletions api/v1.inc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ $router->add_route("GET", "v1/queues/:queueid/stats", "api_v1_queue_stats");
$router->add_route("GET", "v1/queues/:queueid/projects", "api_v1_queue_projects");


$router->add_route("PUT", "v1/projects/:projectid/checkout", "api_v1_project_checkout");
$router->add_route("PUT", "v1/projects/:projectid/validatetext", "api_v1_project_validatetext");
$router->add_route("PUT", "v1/projects/:projectid/pages/:pagename", "api_v1_project_page");
$router->add_route("GET", "v1/projects/:projectid/pages/:pagename", "api_v1_project_page");

$router->add_route("GET", "v1/stats/site", "api_v1_stats_site");
$router->add_route("GET", "v1/stats/site/projects/stages", "api_v1_stats_site_projects_stages");
$router->add_route("GET", "v1/stats/site/projects/states", "api_v1_stats_site_projects_states");
Expand Down
Loading