diff --git a/Dockerfile b/Dockerfile index 7dbb8473e..29584e611 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,7 +31,6 @@ ADD ./Gemfile /rails_app/ ADD ./Gemfile.lock /rails_app/ RUN bundle config --global jobs `cat /proc/cpuinfo | grep processor | wc -l | xargs -I % expr % - 1` -RUN gem update --system RUN bundle install --without development test ADD ./ /rails_app diff --git a/Dockerfile.dev b/Dockerfile.dev index d32b626ac..fa67743c9 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -19,7 +19,6 @@ ADD ./Gemfile /rails_app/ ADD ./Gemfile.lock /rails_app/ RUN bundle config --global jobs `cat /proc/cpuinfo | grep processor | wc -l | xargs -I % expr % - 1` -RUN gem update --system RUN bundle install ADD ./ /rails_app diff --git a/docs/source/includes/_classifications.md b/docs/source/includes/_classifications.md new file mode 100644 index 000000000..a230c93d3 --- /dev/null +++ b/docs/source/includes/_classifications.md @@ -0,0 +1,222 @@ +# Classifications + +```json +{ + "classifications": [{ + "id": 1001, + "created_at": "2014-08-24T22:24:32Z", + "updated_at": "2014-08-24T22:24:32Z", + "completed": false, + "metadata": { + "started_at": "2014-08-24T22:20:21Z", + "finished_at": "2014-08-24T22:24:31Z", + "user_agent": "cURL", + "user_language": "es_MX", + "workflow_version": "11.12" + }, + "annotations": [ + { + "task": "task-1", + "value": [10.4, 12.4, 13.2] + } + ], + "links": { + "user": "1", + "subjects": ["10"], + "workflow": "81", + "project": "2" + } + }], + "links": { + "classifications.user": { + "href": "/users/{classifications.user}", + "type": "classifications" + }, + "classifications.project": { + "href": "/projects/{classifications.project}", + "type": "projects" + }, + "classifications.workflow": { + "href": "/workflows/{classification.workflow}", + "type": "workflows" + }, + "classifications.subject": { + "href": "/subjects/{classifications.subjects}", + "type": "subjects" + } + }, +} + +``` + +A single Classification resource object. This represents a _user's_ +responses to a _workflow's_ questions about a _subject_. + +A classification has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +created_at | string | read-only +updated_at | string | read-only +completed | string | read-only +metadata | hash | +gold_standard | boolean | +annotations | array(hash) | + +Annotations is an array of maps of the form `{ "task": "task_key", +"value": "question answer" }`. Metadata contains additional information about a +classification including: + +- started_at +- finished_at +- user_agent +- workflow_version +- user_language + + +## List classifications + +```http +GET /api/classifications HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + +Only lists classifications the active user has made or projects the user has edit permissions for. + +Classifications have special collection routes that indicate the scope you would like to retrieve. + +Possible options are: + ++ `/api/classifications/` default, will fetch the current user's past complete classifications. ++ `/api/classifications/incomplete` will fetch the current user's past incomplete classifications. ++ `/api/classifications/project` will fetch classifications from projects a user has 'edit' permissions for ++ `/api/classifications/gold_standard` will fetch gold standard classifications for all marked workflows + +Any of the scopes may be further filtered using the *project_id*, *workflow_id* +and *user_group_id* parameters. + +### Parameters + ++ page (optional, integer) ... index of the collection page, 1 is default ++ page_size (optional, integer) ... number of items on a page. 20 is default ++ sort (optional, string) ... fields to sort collection by. updated_at is default ++ project_id (optional, integer) ... only retrieve classifications for a specific project ++ workflow_id (optional, integer) ... only retrieve classifications for a specific workflow ++ user_group_id (optional, integer) ... only retrieve classifications for a specific user group ++ include (optional, string) ... comma separated list of linked resources to return with the collection ++ last_id (optional, integer) ... only classifications with ids greater than `last_id` will be returned (`/project` only, requires project_id) + + + + +## Retrieve a single Classification + +```http +GET /api/classifications/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + +A User may retrieve any classification, irrespective of the complete status. + +### Parameters + ++ `id` (required, integer) ... integer id of the resource to retrieve + + + +## Create a Classification [POST] + +```http +POST /api/classifications HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "classifications": { + "completed": false, + "metadata": { + "started_at": "2014-08-24T22:20:21Z", + "finished_at": "2014-08-24T22:24:31Z", + "user_agent": "cURL", + "user_language": "es_MX", + "workflow_version": "11.12" + }, + "annotations": [ + { + "task": "task-name", + "value": "Any type: string, hash, array, etc" + } + ], + "links": { + "subjects": ["11"], + "workflow": "81", + "project": "2" + } + } +} +``` + +Create a classification by providing a JSON-API formatted object, that +must include _metadata_, _annotations_ and a _links_ hash. Optionally, it +may include the _completed_ field, which if not included defaults to true. +The completed field is used to store half-completed classifications, so the user +can later continue from where they stopped. + +The _links_ hash must contain a _subjects_ hash, a _project_ and a _workflow_. +The _metadata_ hash must contain all the keys specified in the example. +Please note, the _workflow_version_ should be the value returned from the +specific workflow representation. The annotations array must be in the +format specified in the example, i.e. an array of objects, containing a _task_ and a _value_. +The _task_ can be anything and must not necessarily align with the tasks of the workflow +(even though that is generally not advised). + + + + +## Edit a single Classification [PUT] + +```http +PUT /api/classifications/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "classifications": { + "annotations": [ + { + "task": "task-1", + "value": [10.4, 12.4, 13.2] + }, + { + "task": "workflow-2", + "value": "fishy" + } + ], + "completed": true + } +} +``` + +A User may modify an incomplete classification. It should be marked as +completed when done. + +The *annotations* attributes must be returned as a full representation +of the annotations array. + + +## Destroy a single Classification [DELETE] + +```http +DELETE /api/classifications/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + +A User may delete an incomplete classification. diff --git a/docs/source/includes/_collection_preferences.md b/docs/source/includes/_collection_preferences.md new file mode 100644 index 000000000..2f5e764d9 --- /dev/null +++ b/docs/source/includes/_collection_preferences.md @@ -0,0 +1,104 @@ +# Collection preferences + +```json +{ + "collection_preferences": [{ + "id": "942", + "preferences": { + "display": "grid" + }, + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:22:22Z", + "links": { + "user" : "30", + "collection": "11" + } + }], + "links": { + "collection_preferences.user": { + "href": "/user/{collection_preferences.user}", + "type": "users" + }, + "collection_preferences.collection": { + "href": "/collections/{collection_preferences.collection}", + "type": "collections" + } + } +} +``` + +A Collection Preference resource captures a user's settings for a +particular collection. + +It has the following attributes: + +- id +- created_at +- updated_at +- preferences + +*id*, *created_at*, and *updated_at* are set the by the API. Collection + preferences are only visible to user they belong to. + +## List collection preferences + +All collections add a meta attribute hash containing paging information. + +### Parameters + ++ page (optional, integer) ... the index of the page to retrieve default is 1 ++ page_size (optional, integer) ... number of items to include on a page default is 20 ++ sort (optional, string) ... field to sort by ++ user_id (optional, integer) ... user_id to see preferences for ++ collection_id (optional, integer) ... collection_id to see preferences for ++ include (optional, string) ... comma separated list of linked resources to load + + +## Retrieve a single CollectionPreference [GET] + +### Parameters + ++ include (optional, string) ... comma separated list of linked resources to load + + +## Edit a CollectionPreference [PUT] + +```http +PUT /api/collection_preferences/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "collection_preferences": { + "preferences": { + "receive_updates": false, + } + } +} +``` + +Only the owning user may edit a Collection Preference resource. The preferences field may be edited. Editing the preferences field requires a full representation of the preferences object to be sent. + +## Create a CollectionPreference [POST] + +```http +POST /api/collection_preferences HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "collection_preferences": { + "preferences": { + "display": "grid" + }, + "links": { + "collection": "1" + } + } +} +``` + +Creating a Collection Preference requires only a link to a collection. Optionally an object of settings for preferences may be included. + +Since a user can only create, read, or modify their own preferences the currently logged in user is always set as the linked user on creation. + diff --git a/docs/source/includes/_collection_roles.md b/docs/source/includes/_collection_roles.md new file mode 100644 index 000000000..4e4d6b5e7 --- /dev/null +++ b/docs/source/includes/_collection_roles.md @@ -0,0 +1,156 @@ +# CollectionRole +```json +{ + "links": { + "collection_roles.owner": { + "href": "/{collection_roles.owner.href}", + "type": "owners" + }, + "collection_roles.collection": { + "href": "/collections/{collection_roles.collection}", + "type": "collections" + } + }, + "meta": { + "collection_roles": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/collection_roles?page_size=2", + "previous_href": "/collection_roles?page=14page_size=2", + "next_href": "/collection_roles?page=2&page_size=2", + "last_href": "/collection_roles?page=14&page_size=2" + } + }, + "collection_roles": [{ + "id": "942", + "roles": ["collaborator"], + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:22:22Z", + "links": { + "collection": "11", + "owner": { + "id": "4", + "display_name": "Owner 4", + "type": "user_groups", + "href": "user_groups/4" + } + } + },{ + "id": "949", + "roles": ["viewer"], + "created_at": "2014-08-20T06:23:12Z", + "updated_at": "2014-09-21T08:22:22Z", + "links": { + "collection": "81", + "owner": { + "id": "1", + "display_name": "Owner 1", + "type": "users", + "href": "users/1" + } + } + }] +} +``` + +Resources related to Roles for _Panoptes Collections_ +A Collection Role resources contains an array of roles assigned to a user +for a particular collection. + +It has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +created_at | string | read-only +updated_at | string | read-only +roles | array(string) | + +*id*, *created_at*, and *updated_at* are set the by the API. Collection +roles are visible to the collection owner and the user given roles. + +### Collection Role Types +- `collaborator` - full access to edit or delete a collection +- `viewer` - may view a private collection + +## List All Collection Roles + +A Collection of CollectionRole resources. + +All collections add a meta attribute hash containing paging +information. + +CollectionRoles are returned as an array under *collection_roles*. + +```http +GET /api/collection_roles HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + + sort (optional, string) ... field to sort by + + user_id (optional, integer) ... user_id to see roles for + + collection_id (optional, integer) ... collection_id to see roles for + + include (optional, string) ... comma separate list of linked resources to load + + + +## Retrieve a single CollectionRole + +```http +GET /api/collection_roles/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + id (required, integer) ... integer identifier of the collection role resource + + include (optional, string) ... comma separate list of linked resources to load + +## Create a CollectionRole +```http + +POST /api/collection_roles/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "collection_roles": { + "roles": ["collaborator"], + "links": { + "collection": "1", + "user": "842" + } + } +} +``` + +Creating a Collection Role resource requires a link to a user and a +collection. You may also include an array of roles. + + +## Edit a CollectionRole +```http +PUT /api/collection_roles/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "collection_roles": { + "roles": ["viewer"] + } +} +``` +A user with permissions to edit a collection may modify roles for other +users in the collection. A user without edit permissions may not edit +their own roles. + +Editing requires sending a full representation of the roles array. diff --git a/docs/source/includes/_collections.md b/docs/source/includes/_collections.md new file mode 100644 index 000000000..36d08a02e --- /dev/null +++ b/docs/source/includes/_collections.md @@ -0,0 +1,189 @@ +# Collections + +```json +{ + "links": { + "collections.subjects": { + "href": "/subjects{?collection_id=collections.id}", + "type": "subjects" + } + }, + "collections": [{ + "id": "101", + "created_at": "2014-04-20T06:23:12Z", + "updated_at": "2014-04-20T06:23:12Z", + "name" : "flowers", + "display_name": "Lots of Pretty flowers", + "default_subject_src": "panoptes-uploads.zooniverse.org/production/subject_location/hash.jpeg", + "links": { + "owner": { + "id": "10", + "display_name": "Owner 10", + "href": "/users/10", + "type": "users" + } + } + }] +} +``` + +A collection is a user curated set of subjects for a particular +project. + +It has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +display_name | string | +name | string | +created_at | string | read-only +updated_at | string | read-only +default_subject | id | + + +*id*, *created_at*, and *updated_at* are set by the API. + +## List all collections +```http +GET /api/collections HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + + sort (optional, string) ... field to sort by + + owner (optional, string) ... string name of either a user or user group to filter by + +All collections add a meta attribute hash containing paging +information.
+Collections are returned as an array under *collections*. + +## Retrieve a single collection +```http +GET /api/projects/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + id (required, integer) ... integer id of the resource to retrieve + + display_name (string) ... project name filter + +## Create a Collection +A Collection only needs a *display name* to be created. By default +name will be the underscored and downcased version of *display_name*, +and the current user will be set as the owner. + +Optionally a create request may include name, a link to an +owner, and links to subjects. + +```http +POST /api/collections HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "collections": { + "display_name": "flowers", + "links": { + "owner": { + "id" : "10", + "display_name": "Owner 10", + "type": "user_groups", + "href": "/user_groups/10" + } + } + } +} +``` + + +## Edit a Collection + +```http +PUT /api/collections/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "collections": { + "name": "flower_power", + } +} +``` +A user may edit a collection they are the owner of or have edit +permissions for. A user may edit a collection's name, or display_name, +and may also send a full representation of a collections subject links +or a single subject id to set the default subject. + +Sending subject links through a put is not recommend, especially if a +collection has many subjects. + +Removing subjects from a collection does not destroy the subject record. + + +## Destroy a Collection +```http +DELETE /api/collections/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` +A user who is the owner of a collection or who has destroy permissions +for a collection, may delete it. + + +## Add subject links +Add subjects to a collection. + +```http +POST /api/collections/123/links/subjects HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "subjects": ["1", "2"] +} +``` + +A user is permitted to add subject if they are the collection owner or +have edit permissions. + + +## Remove subject links +```http +DELETE /api/collections/123/links/subjects/1,2 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + +Remove subjects from a collection. + +A user is permitted to remove subjects if they are the collection +owner or have edit permissions. + ++ Parameters + + id (required, integer) ... id of collection to edit + + link_ids (required, string) ... comma separated list of ids to remove + + +## Add default subject link + +```http +POST /api/collections/123/links/default_subject HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "default_subject": "1" +} +``` +Links a default subject to a collection. This subject's first media +location URL will be included in the serialized collection and used +as the thumbnail. Update this attribute with `null` to use the first +subject in the linked list instead. + +A user is permitted to add a default subject if they are the collection +owner or have edit permissions. \ No newline at end of file diff --git a/docs/source/includes/_deprecated_aggregations.md b/docs/source/includes/_deprecated_aggregations.md new file mode 100644 index 000000000..0deae67cc --- /dev/null +++ b/docs/source/includes/_deprecated_aggregations.md @@ -0,0 +1,215 @@ +# Group Aggregation +Resources related to setting preferences for _Panoptes Collections_ + +## Aggregation [/aggregation/{id}{?include}] +An Aggregation resource captures the results of the aggregation engine for +the set of classifications for a particular workflow and subject. + +It has the following attributes: + +- id +- created_at +- updated_at +- aggregation + +*id*, *created_at*, and *updated_at* are set the by the API. Aggregations are +only visible to users with rights on the workflow's associated project. + ++ Parameters + + id (required, integer) ... integer identifier of resource + ++ Model + + + Body + + { + "links": { + "aggregation.workflow": { + "href": "/workflows/{aggregation.workflow}", + "type": "workflows" + }, + "aggregation.subject": { + "href": "/subjects/{aggregation.subject}", + "type": "subjects" + } + }, + "aggregations": [{ + "id": "5", + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:22:22Z", + "aggregation": { + "mean": 1, + "std": 1, + "count": [1, 1, 1], + "workflow_version": "1.1" + }, + "links": { + "workflow" : "3", + "subject": "4" + } + }] + } + +### Retrieve a single Aggregation [GET] ++ Parameters + + include (optional, string) ... comma separated list of linked resources to load + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + ++ Response 200 + + [Aggregation][] + +### Edit an Aggregation [PUT] +Only a user with rights on the workflow's project may edit an Aggregation resource. +The aggregation field may be edited. + +Editing the aggregation field requires a full representation of the +aggregation object to be sent. + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + + + Body + + { + "aggregations": { + "aggregation": { + "mean": 1, + } + } + } + ++ Response 200 + + [Aggregation][] + +## Aggregation Collection [/aggregations{?workflow_id,subject_id,page,page_size,sort,include}] +A Collection of Aggregation resources. + +All collections add a meta attribute hash containing paging +information. + +Aggregations are returned as an array under *aggregations*. + ++ Model + + { + "links": { + "aggregation.workflow": { + "href": "/workflows/{aggregation.workflow}", + "type": "workflows" + }, + "aggregation.subject": { + "href": "/subjects/{aggregation.subject}", + "type": "subjects" + } + }, + "meta": { + "collection_preferences": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/collection_preferences?page_size=2", + "previous_href": "/collection_preferences?page=14page_size=2", + "next_href": "/collection_preferences?page=2&page_size=2", + "last_href": "/collection_preferences?page=14&page_size=2" + } + }, + "aggregations": [{ + "id": "5", + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:22:22Z", + "aggregation": { + "mean": 1, + "std": 1, + "count": [1, 1, 1], + "workflow_version": "1.1" + }, + "links": { + "workflow" : "3", + "subject": "4" + } + }, { + "id": "6", + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:23:22Z", + "aggregation": { + "mean": 2, + "std": 3, + "count": [2, 1, 1], + "workflow_version": "1.2" + }, + "links": { + "workflow" : "4", + "subject": "3" + } + }] + } + +### List all Aggregations [GET] ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + + sort (optional, string) ... field to sort by + + workflow_id (optional, integer) ... workflow to see aggregations for + + subject_id (optional, integer) ... subject_id to see aggregations for + + include (optional, string) ... comma separated list of linked resources to load + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + ++ Response 200 + + [Aggregation Collection][] + +### Create a Aggregation [POST] +Creating an Aggregation requires an aggregation hash with the _workflow_version_ +set. Please note, the _workflow_version_ should be the value returned from the +specific aggregation workflow's representation. The workflow and subject links +must be provided as well. + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + + + Body + + { + "aggregations": { + "aggregation": { + "mean": 1, + "std": 1, + "count": [1, 1, 1], + "workflow_version": "1.1" + }, + "links": { + "workflow" : "3", + "subject": "4" + } + } + } + ++ Response 201 + + [Aggregation][] diff --git a/docs/source/includes/_deprecated_project_contents.md b/docs/source/includes/_deprecated_project_contents.md new file mode 100644 index 000000000..c8bf357fa --- /dev/null +++ b/docs/source/includes/_deprecated_project_contents.md @@ -0,0 +1,390 @@ +# Group ProjectContents +Resources related to the translatable strings for _Panotpes Projects_. + +## ProjectContent [/project_contents/{id}{?include}] +A Project Content resources contains all strings for a project for a +particular language. This resource will normally only be accessed by +project translators. Users will receive translated versions of +projects based on their *Accept-Language* header or preferences. + +It has the following attributes + +- id +- language +- title +- description +- created_at +- updated_at +- introduction +- science_case +- team_members +- guide + +*id*, *created_at*, and *updated_at* are created by the api +server. + +*language* is a two or five character identifier where the first two +characters are the [ISO 639](http://en.wikipedia.org/wiki/ISO_639) +language codes. In the five character version, the middle character +may be a "-" or "_" and the final two characters the [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) +country code. This allows multiple translations for each language, for +instance Simplified Chinese (zh_CN) vs Traditional Chinese (zh_TW or +zh_HK). + ++ Parameters + + id (required, integer) ... integer id of the resource + ++ Model + + + Body + + { + "links": { + "project_content.project": { + "href": "/project/{project_content.project}", + "type": "projects" + } + }, + "project_contents": [{ + "id": "42", + "language": "en_UK", + "title": "A Labourious and Colourful project", + "description": "Lots of colours and labour go into this", + "introduction": "Text..", + "science_case": "More text..", + "team_memebrs": [{ + "name": "Rocky", + "bio": "a bio", + "institution": "whatsmattau", + "twitter": "@rocky", + }], + "guide": { + "image": "http://asdfasdf.jpg.gif", + "explanation": "It's a bear!" + }, + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:22:22Z", + "links": { + "project": "11" + } + }] + } + + +### Retrieve a single ProjectContent [GET] ++ Parameters + + include (optional, string) ... comma separated list of linked resources to load + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + ++ Response 200 + + [ProjectContent][] + +### Update a ProjectContent [PUT] +Only users with edit permissions for the parent project or users who +have the "translator" roles may edit project contents". + +The *team_members* and *guide* fields must be updated as a full +representation. The *language* field is not editable once created. + +Project Contents that have the same language as their parent project's +primary_language field may not be edited. + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + + + Body + + { + "project_contents": { + "title": "A Less Labourious Title" + } + } + ++ Response 200 + + [ProjectContent][] + +### Destroy a ProjectConent [DELETE] +Only users who edit permissions for the parent project may remove +project content models. + +Project Contents that have the same language as their parent project's +primary_language field may not be destroyed. + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + ++ Response 204 + +## ProjectContent Version [/project_contents/{project_contents_id}/versions/{id}] +A Project Content Version resource represents a set of changes made to +a Project Content resource. + +It has the following attributes: + +- id +- changset +- whodunnit +- created_at + +It is not editable. + ++ Model + + + Body + + { + "versions": [{ + "id": "42", + "changeset": { + "title": ["A Colourful Project", "A Colorful Project"] + }, + "whodunnit": "stuartlynn", + "created_at": "2014-03-20T06:23:12Z", + "links": { + "item": { + id: "101", + "href": "/project_contents/101", + "type": "project_contents" + } + } + }] + } + +### Retrieve a Single Version [GET] + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + ++ Response 200 + + [ProjectContent Version][] + + +## ProjectContent Version Collection [/project_contents/{project_contents_id}/versions{?page_size,page}] +A collection of Project Content Version resources. + +All collections add a meta attribute hash containing paging +information. + +Project Content Versions are returned as an array under *versions*. + ++ Model + + + Body + + { + "meta": { + "versions": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/project_contents/101/versions?page_size=2", + "previous_href": "/project_contents/101/versions?page=14page_size=2", + "next_href": "/project_contents/101/versions/?page=2&page_size=2", + "last_href": "/project_contents/101/versions?page=14&page_size=2" + } + }, + "versions": [{ + "id": "42", + "changeset": { + "title": ["A Colourful Project", "A Colorful Project"] + }, + "whodunnit": "stuartlynn", + "created_at": "2014-03-20T06:23:12Z", + "links": { + "item": { + id: "101", + "href": "/project_contents/101", + "type": "project_contents" + } + } + },{ + "id": "43", + "changeset": { + "description": ["No Words Here!", "Words"] + }, + "whodunnit": "edwardothegreat", + "created_at": "2014-03-20T06:23:12Z", + "links": { + "item": { + id: "101", + "href": "/project_contents/101", + "type": "project_contents" + } + } + }] + } + +### List all Project Content Versions [GET] ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + ++ Response 200 + + [ProjectContent Version Collection][] + +## ProjectContent Collection [/project_contents{?project_id,language,page,page_size,include}] +A collection of Project Content resources. + +All collections add a meta attribute hash containing paging +information. + +Project Contents are returned as an array under *project_contents*. + ++ Model + + + Body + + { + "links": { + "project_contents.project": { + "href": "/project/{project_content.project}", + "type": "projects" + } + }, + "meta": { + "project_contents": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/project_contents?page_size=2", + "previous_href": "/project_contents?page=14page_size=2", + "next_href": "/project_contents?page=2&page_size=2", + "last_href": "/project_contents?page=14&page_size=2" + } + }, + "project_contents": [{ + "id": "42", + "language": "en_UK", + "title": "A Labourious and Colourful project", + "description": "Lots of colours and labour go into this", + "introduction": "Text..", + "science_case": "More text..", + "team_memebrs": [{ + "name": "Rocky", + "bio": "a bio", + "institution": "whatsmattau", + "twitter": "@rocky", + }], + "guide": { + "image": "http://asdfasdf.jpg.gif", + "explanation": "It's a bear!" + }, + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:22:22Z", + "links": { + "project": "11" + } + }, + { + "id": "43", + "language": "en_CA", + "title": "A Labourious and Colourful project", + "description": "Lots of colours and labour go into this", + "introduction": "Text..", + "science_case": "More text..", + "team_memebrs": [{ + "name": "Rocky", + "bio": "a bio", + "institution": "whatsmattau", + "twitter": "@rocky", + }], + "guide": { + "image": "http://asdfasdf.jpg.gif", + "explanation": "It's a bear!" + }, + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:22:22Z", + "links": { + "project": "11" + } + }] + } + +### List all ProjectContents [GET] ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + + project_id (optional, integer) ... project_id to see contents for + + language (optional, string) ... language code to search for + + include (optional, string) ... comma separated list of linked resources to load + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + ++ Response 200 + + [ProjectContent Collection][] + +### Create ProjectContent [POST] +A ProjectContent resource can be created for a project by either a +user with edit permissions for the project or a user with a +"translator" role. + +The *language* field and a link to a project are the only required +fields to created a ProjectContent resource. + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + + + Body + + { + "project_contents": { + "language": "es", + "links": { + "project": "11" + } + } + } + ++ Response 201 + + [ProjectContent][] + +# Group WorkflowContents +Resources related to the translatable strings for _Panotpes Workflows_. diff --git a/docs/source/includes/_deprecated_workflow_contents.md b/docs/source/includes/_deprecated_workflow_contents.md new file mode 100644 index 000000000..8164d2fae --- /dev/null +++ b/docs/source/includes/_deprecated_workflow_contents.md @@ -0,0 +1,386 @@ +## WorkflowContent [/workflow_contents/{id}{?include}] +A Workflow Content resource contains strings for a workflow in a +particular language. + +This resource will normally only be accessed by +project translators. Users will receive translated versions of +workflows based on their *Accept-Language* header or preferences. + +It has the following attributes + +- id +- language +- created_at +- updated_at +- strings + +*id*, *created_at*, and *updated_at* are created by the api +server. + +*language* is a two or five character identifier where the first two +characters are the [ISO 639](http://en.wikipedia.org/wiki/ISO_639) +language codes. In the five character version, the middle character +may be a "-" or "_" and the final two characters the [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) +country code. This allows multiple translations for each language, for +instance Simplified Chinese (zh_CN) vs Traditional Chinese (zh_TW or +zh_HK). + ++ Parameters + + id (required, integer) ... integer id of the resource + ++ Model + + + Body + + { + "links": { + "workflow_contents.workflow": { + "href": "/workflows/{workflow_content.workflow}", + "type": "workflows" + } + }, + "workflow_contents": [{ + "id": "43", + "strings": [ + "a string", + "oh look", + "another one" + ], + "language": "en_US", + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:22:22Z", + "links": { + "workflow": "11" + } + }] + } + + +### Retrieve a single WorkflowContent [GET] ++ Parameters + + include (optional, string) ... comma separated list of linked resources to load + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + ++ Response 200 + + [WorkflowContent][] + +### Update a WorkflowContent [PUT] +Only users with edit permissions for the parent project or users who +have the "translator" roles may edit workflow contents. + +The *strings* field must be edited as a full representation. The +*language* field may not be changed. + +Workflow Contents that have the same language as their parent workflow's +primary_language field may not be edited. + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + + + Body + + { + "workflow_contents": { + "strings": [ + "a replacement string" + ] + } + } + ++ Response 200 + + [WorkflowContent][] + +### Destroy a WorkflowConent [DELETE] +Only users who edit permissions for the parent project may remove +workflow content models. + +Workflow Contents that have the same language as their parent workflow's +primary_language field may not be destroyed. + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + ++ Response 204 + +## WorkflowContent Version [/workflow_contents/{workflow_contents_id}/versions/{id}] +A Workflow Content Version resource represents a set of changes made to +a Workflow Content resource. + +It has the following attributes: + +- id +- changset +- whodunnit +- created_at + +It is not editable. + ++ Parameters + + workflow_contents_id (required, integer) ... id of the workflow to retrieve versions for + + id (required, integer) ... integer id of the version to load + ++ Model + + + Body + + { + "versions": [{ + "id": "42", + "changeset": { + "strings": [[ + "a string", + "another string", + "stringer bell" + ],[ + "a string", + "another string", + "Stringer Bell" + ]] + }, + "whodunnit": "stuartlynn", + "created_at": "2014-03-20T06:23:12Z", + "links": { + "item": { + "id": "101", + "href": "/workflow_contents/101", + "type": "workflow_contents" + } + } + }] + } + +### Retrieve a Single Version [GET] + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + ++ Response 200 + + [WorkflowContent Version][] + + +## WorkflowContent Version Collection [/workflow_contents/{workflow_contents_id}/versions{?page_size,page}] +A collection of Workflow Content Version resources. + +All collections add a meta attribute hash containing paging +information. + +Workflow Content Versions are returned as an array under *versions*. + ++ Parameters + + workflow_contents_id (required, integer) ... id of the workflow to retrieve versions for + ++ Model + + + Body + + { + "meta": { + "versions": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/workflow_contents/101/versions?page_size=2", + "previous_href": "/workflow_contents/101/versions?page=14page_size=2", + "next_href": "/workflow_contents/101/versions/?page=2&page_size=2", + "last_href": "/workflow_contents/101/versions?page=14&page_size=2" + } + }, + "versions": [{ + "id": "42", + "changeset": { + "strings": [[ + "a string", + "another string", + "stringer bell" + ],[ + "a string", + "another string", + "Stringer Bell" + ]] + }, + "whodunnit": "stuartlynn", + "created_at": "2014-03-20T06:23:12Z", + "links": { + "item": { + "id": "101", + "href": "/workflow_contents/101", + "type": "workflow_contents" + } + } + },{ + "id": "43", + "changeset": { + "strings": [[ + "a string", + "another string", + "Stringer Bell" + ],[ + "a string", + "a brother string", + "Stringer Bell" + ]] + }, + "whodunnit": "stuartlynn", + "created_at": "2014-03-20T06:23:12Z", + "links": { + "item": { + "id": "101", + "href": "/workflow_contents/101", + "type": "workflow_contents" + } + } + }] + } + +### List all Workflow Content Versions [GET] ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + ++ Response 200 + + [WorkflowContent Version Collection][] + +## WorkflowContent Collection [/workflow_contents{?workflow_id,language,page,page_size,include}] +A collection of Workflow Content resources. + +All collections add a meta attribute hash containing paging +information. + +Workflow Contents are returned as an array under *workflow_contents*. + ++ Model + + + Body + + { + "links": { + "workflow_contents.workflow": { + "href": "/project/{workflow_content.workflow}", + "type": "workflows" + } + }, + "meta": { + "workflow_contents": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/workflow_contents?page_size=2", + "previous_href": "/workflow_contents?page=14page_size=2", + "next_href": "/workflow_contents?page=2&page_size=2", + "last_href": "/workflow_contents?page=14&page_size=2" + } + }, + "workflow_contents": [{ + "id": "43", + "strings": [ + "a string", + "oh look", + "another one" + ], + "language": "en_US", + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:22:22Z", + "links": { + "workflow": "11" + } + },{ + "id": "44", + "strings": [ + "a string", + "oh look", + "another one" + ], + "language": "en_US", + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:22:22Z", + "links": { + "workflow": "12" + } + }] + } + +### List all WorkflowContents [GET] ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + + workflow_id (optional, integer) ... id of workflow to see contents for + + language (optional, string) ... language code to search for + + include (optional, string) ... comma separated list of linked resources to load + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + ++ Response 200 + + [WorkflowContent Collection][] + +### Create WorkflowContent [POST] +A WorkflowContent resource can be created for a workflow by either a +user with edit permissions for the parent project or a user with a +"translator" role. + +The *language* field and a link to a workflow are the only required +fields to create a WorkflowContent resource. + ++ Request + + + Headers + + Accept: application/vnd.api+json; version=1 + Content-Type: application/json + + + Body + + { + "workflow_contents": { + "language": "es", + "links": { + "workflow": "11" + } + } + } + ++ Response 201 + + [WorkflowContent][] diff --git a/docs/source/includes/_memberships.md b/docs/source/includes/_memberships.md new file mode 100644 index 000000000..7df785de3 --- /dev/null +++ b/docs/source/includes/_memberships.md @@ -0,0 +1,155 @@ +# Memberships +```json +{ + "links": { + "memberships.user_group": { + "href": "/user_groups/{memberships.user_group}", + "type": "user_groups" + }, + "memberships.user": { + "href": "/users/{memberships.user}", + "type": "users" + } + }, + "meta": { + "memberships": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/memberships?page_size=2", + "previous_href": "/memberships?page=14page_size=2", + "next_href": "/memberships?page=2&page_size=2", + "last_href": "/memberships?page=14&page_size=2" + } + }, + "memberships": [{ + "id": "101", + "created_at": "2014-04-20T06:23:12Z", + "updated_at": "2014-04-20T06:23:12Z", + "state": "active", + "roles": ["group_admin"], + "links": { + "user": "12", + "user_groups": "31" + } + },{ + "id": "111", + "created_at": "2014-04-20T06:23:12Z", + "updated_at": "2014-04-20T06:23:12Z", + "state": "inactive", + "roles": [], + "links": { + "user": "12", + "user_groups": "20" + } + }] +} +``` + +A membership represents and user's status in a group and their role +within the group. + +It has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +created_at | string | read-only +updated_at | string | read-only +state | string | +roles | array(string) | + + +*id*, *created_at*, and *update_at* are assigned by the API. + ++ Membership *state* can be: + + "invited" + + "active" + + "inactive" + +When a user is added to a group, their state is set to "invited". After they take +action to join the group their state becomes "active". A User who leaves +a group has their state set to "inactive". + +## List All Memberships +```http +GET /api/memberships HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + page (optional, integer) ... index of the page to retrieve 1 by default + + page_size (optional, integer) ... number of items per page 20 by default + + sort (optional, string) ... field to sort by, id by default + + user_id (optional, integer) ... filter list to memberships for a user + + user_group_id (optional, integer) ... filter list to memberships for a user group + +All memberships add a meta attribute hash containing paging +information. + +Memberships are returned as an array under *memberships*. + + +## Retreive a Membership +```http +GET /api/memberships/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + id (required, integer) ... integer id of the resource to retrieve + +## Create a Membership +```http +POST /api/memberships HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "memberships": { + "join_token": "decafbad", + "links": { + "user": "10", + "user_group": "11 + } + } +} +``` +A membership creation request must include a link to a user and to a +user_group, although currently the linked user must always be the current user. +The request must also include the secret join_token of the user_group as an attribute +of the membership (although this property is not persisted). + + +## Edit a Membership +```http +PUT /api/memberships/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "memberships": { + "state": "inactive" + } +} +``` +A user can ordinary only change their membership state. A user with +user group edit permissions can change the membership's roles. + + +## Destroy a Membership +```http +DELETE /api/memberships/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` +Destroying a membership only sets the state to inactive. A user may +destroy their own memberships and a user with edit permission in a +user group may destroy membership for that group. + diff --git a/docs/source/includes/_organizations.md b/docs/source/includes/_organizations.md new file mode 100644 index 000000000..5c1661d98 --- /dev/null +++ b/docs/source/includes/_organizations.md @@ -0,0 +1,261 @@ +# Organizations + +```json +{ + "organizations": [ + { + "id": "5", + "display_name": "United Federation of Projects", + "description": "Every project in the galaxy", + "introduction": "Hello and welcome to the UFP", + "title": "United Federation of Projects", + "href": "/organizations/5", + "primary_language": "en", + "listed_at": null, + "listed": true, + "slug": "user/slug", + "urls": [ + { + "url": "https://twitter.com/UFP", + "path": "United Federation of Twitter", + "site": "twitter.com/", + "label": "" + } + ], + "categories": [], + "announcement": "Oh Gosh!", + "links": { + "organization_contents": [ + "5" + ], + "organization_roles": [ + "9999" + ], + "projects": [ + "1", + "2" + ], + "owner": { + "id": "811067", + "display_name": "meredithspalmer", + "type": "users", + "href": "/users/811067" + }, + "pages": [ + "5" + ], + "avatar": { + "href": "/organizations/5/avatar", + "type": "avatars", + "id": "27687087" + }, + "background": { + "href": "/organizations/5/background", + "type": "backgrounds", + "id": "30335947" + }, + "attached_images": { + "href": "/organizations/5/attached_images", + "type": "attached_images" + } + } + } + ], + "links": { + "organizations.attached_images": { + "href": "/organizations/{organizations.id}/attached_images", + "type": "media" + }, + "organizations.organization_contents": { + "href": "/organization_contents?organization_id={organizations.id}", + "type": "organization_contents" + }, + "organizations.organization_roles": { + "href": "/organization_roles?organization_id={organizations.id}", + "type": "organization_roles" + }, + "organizations.projects": { + "href": "/projects?organization_id={organizations.id}", + "type": "projects" + }, + "organizations.pages": { + "href": "/organizations/{organizations.id}/pages", + "type": "organization_pages" + }, + "organizations.owner": { + "href": "/{organizations.owner.href}", + "type": "owners" + }, + "organizations.avatar": { + "href": "/organizations/{organizations.id}/avatar", + "type": "media" + }, + "organizations.background": { + "href": "/organizations/{organizations.id}/background", + "type": "media" + } + }, + "meta": { + "organizations": { + "page": 1, + "page_size": 20, + "count": 1, + "include": [], + "page_count": 1, + "previous_page": null, + "next_page": null, + "first_href": "/organizations", + "previous_href": null, + "next_href": null, + "last_href": "/organizations" + } + } +} +``` + +An Organization is a collection of projects that are related by dicipline, research group + +It has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +display_name | string | +title | string | +description | string | +introduction | string | +slug | string | +primary_language | string | +listed_at | datetime | +activated_state | integer | +created_at | datetime | read-only +updated_at | datetime | read-only +urls | jsonb | +listed | boolean | +categories | string | +available_languages | array(string) | +background | string | +avatar | string | + +## List All Organizations +```http +GET /api/organizations HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + + sort (optional, string) ... field to sort by + + owner (optional, string) ... string owner name of either a user or a user group to filter by. + + include (optional, string) ... comma separated list of linked resources to include in the response + +Response a *meta* attribute hash containing +paging information. + +Organizations are returned as an array under the _organizations_ key. + + +## Retrieve a single Organization +```http +GET /api/organizations/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` ++ Parameters + + id (required, integer) ... integer id of the resource to retrieve + + include (optional, string) ... comma separated list of linked resources to include in the response + + display_name (optional, string)...name filter + + listed (boolean) ... publicly visible + + +## Create a Organization +```http +POST /api/organizations HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "Organizations": { + "display_name": "United Federation of Projects", + "description": "Lots o' Projects", + "primary_language": "en-us", + "links": { + "projects": ["1", "2"] + } + } +} +``` + +Requires at least a *display_name*, *description* and primary_language*. + + +## Edit a single Organization +```http +PUT /api/organizations/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "organizations": { + "display_name": "Klingon Empire", + "links": { + "workflows": ["1"], + "subject_sets": ["10"] + } + } +} +``` + +A User must be the owner of a Organization or have update +permissions to edit the resource. + +Setting has may links through a PUT, while supported, is not +recommended. Instead, use the link endpoints explained below. + + +## Destroy a single Organization +```http +DELETE /api/organizations/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` +A user may destroy a Organization they own or have destroy permissions for. + +## Add Organization Links +```http +POST /api/organizations/123/links/projects HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "projects": ["1", "2"] +} +``` +The body key must match the link_type parameter. + ++ Parameters + + id (required, integer) - the id of the project to add + + link_type (required, string) + the name of the link to edit + + Members + + `projects` + + +## Destroy a Link +```http +DELETE /api/organizations/123/links/projects/1,2 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` +The recommended way to destroy Organization links. +Will destroy the comma separated list of link ids for the given link +type. + ++ Parameters + + id (required, integer) ... the id of the project to modify + + link_type (required, string) + the name of the link to edit + + Members + + `projects` + + link_ids (required, string) ... comma separated list of ids to destroy \ No newline at end of file diff --git a/docs/source/includes/_project_preferences.md b/docs/source/includes/_project_preferences.md new file mode 100644 index 000000000..4947dd8db --- /dev/null +++ b/docs/source/includes/_project_preferences.md @@ -0,0 +1,171 @@ +# Project Preferences +```json + { + "links": { + "project_preferences.user": { + "href": "/user/{project_preferences.user}", + "type": "users" + }, + "project_preferences.project": { + "href": "/projects/{project_preferences.project}", + "type": "projects" + } + }, + "meta": { + "project_preferences": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/project_preferences?page_size=2", + "previous_href": "/project_preferences?page=14page_size=2", + "next_href": "/project_preferences?page=2&page_size=2", + "last_href": "/project_preferences?page=14&page_size=2" + } + }, + "project_preferences": [{ + "id": "942", + "email_communication": true, + "preferences": { + "tutorial": true + }, + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:22:22Z", + "links": { + "user" : "30", + "project": "11" + } + },{ + "id": "949", + "email_communication": true, + "preferences": { + "tutorial": true + }, + "created_at": "2014-08-20T06:23:12Z", + "updated_at": "2014-09-21T08:22:22Z", + "links": { + "user" : "33", + "project": "81" + } + }] +} +``` + +A Project Preference resource captures a user's settings for a +particular project. + +It has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +created_at | datetime | read-only +updated_at | datetime | read-only +preferences | jsonb | +email_communication | boolean | + +*id*, *created_at*, and *updated_at* are set the by the API. Project + preferences are only visible to user they belong to. + + +## List all ProjectPreferences +```http +GET /project_preferences HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + + sort (optional, string) ... field to sort by + + user_id (optional, integer) ... user_id to see preferences for + + project_id (optional, integer) ... project_id to see preferences for + + include (optional, string) ... comma separated list of linked resources to load + +Responses will have meta attribute hash containing paging information. + +ProjectPreferences are returned as an array under *project_preferences*. + + +## Retrieve a single ProjectPreference +```http +GET /api/project_preferences/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` ++ Parameters + + id (required, integer) ... integer identifier of resource + + include (optional, string) ... comma separated list of linked resources to load + +## Create a ProjectPreference +```http +POST /api/project_preferences HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "project_preferences": { + "email_communication": true, + "preferences": { + "tutorial": true + }, + "links": { + "project": "1" + } + } +} +``` +Creating a Project Preference requires only a link to a +project. Optionally a boolean flag for email_communication or a hash +of settings for preferences may be included. + +Since a user can only create, read, or modify their own preferences +the currently logged in user is always set as the linked user on +creation. + +## Edit a ProjectPreference +```http +PUT /api/project_preferences/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "project_preferences": { + "preferences": { + "mini_course": false, + } + } +} +``` +Only the owning user may edit a Project Preference resource. The +email_communication field and the preferences field may be edited. + +Editing the preferences field requires a full representation of the +preferences hash to be sent. + + +## Edit ProjectPreferences Settings +```http +POST /api/project_preferencess?user_id=1&project_id=1 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "project_preferences": { + "settings": { + "workflow_id": 1234, + } + } +} +``` +Project owners may edit the settings attribute of any user's Project Preferences associated +with that project (and only that project). You need to provide the "user_id" and the "project_id" +to specify the resource to apply the settings update to. Note: in the settings payload the +"workflow_id" is the only accepted parameter. + ++ Parameters + + user_id (string) ... The id of the user whose preference needs updating + + project_id (string) ... The id of the project the preference setting should be scoped to diff --git a/docs/source/includes/_project_roles.md b/docs/source/includes/_project_roles.md new file mode 100644 index 000000000..9438f3374 --- /dev/null +++ b/docs/source/includes/_project_roles.md @@ -0,0 +1,148 @@ +# Project Roles +```json +{ + "links": { + "project_roles.owner": { + "href": "/{project_roles.owner.href}", + "type": "owners" + }, + "project_roles.project": { + "href": "/projects/{project_roles.project}", + "type": "projects" + } + }, + "meta": { + "project_roles": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/project_roles?page_size=2", + "previous_href": "/project_roles?page=14page_size=2", + "next_href": "/project_roles?page=2&page_size=2", + "last_href": "/project_roles?page=14&page_size=2" + } + }, + "project_roles": [{ + "id": "942", + "roles": ["collaborator"], + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:22:22Z", + "links": { + "project": "11", + "owner": { + "id": "3", + "display_name": "Owner 3", + "type": "users", + "href": "users/3" + } + } + },{ + "id": "949", + "roles": ["tester", "translator"], + "created_at": "2014-08-20T06:23:12Z", + "updated_at": "2014-09-21T08:22:22Z", + "links": { + "project": "81", + "owner": { + "id": "33", + "display_name": "Owner 33", + "type": "users", + "href": "users/33" + } + } + }] +} +``` +A Project Role resources contains an array of roles assigned to a user +for a particular project + +It has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +roles | array(string) | +created_at | datetime | read-only +updated_at | datetime | read-only + + +*id*, *created_at*, and *updated_at* are set the by the API. Project +roles are visible to the project owner and the user given roles. + ++ **Roles for a project may be:** + + collaborator - full access to edit or delete a project + + tester - Able to see a private project + + scientist - Able to moderate project Talk and see a private project + + moderator - Able to moderate project Talk and see a private project + + translator - Able to create new and edit project and workflow translations + +## List all ProjectRoles +```http +GET /api/project_roles HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + + sort (optional, string) ... field to sort by + + user_id (optional, integer) ... user_id to see roles for + + project_id (optional, integer) ... project_id to see roles for + + include (optional, string) ... comma separate list of linked resources to load + +Response will have a meta attribute hash containing paging +information. + +ProjectRoles are returned as an array under *project_roles*. + +## Retrieve a single ProjectRole +```http +GET /api/project_roles/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` ++ Parameters + + id (required, integer) ... integer identifier of the project role resource + + include (optional, string) ... comma separate list of linked resources to load + +## Create a ProjectRole +```http +POST /api/project_roles HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "project_roles": { + "roles": ["collaborator"], + "links": { + "project": "11", + "user": "30" + } + } +} +``` +Creating a Project Role resource requires a link to a user and a +project. You may also include an array of roles. + + +## Edit a ProjectRole +```http +PUT /api/project_roles/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "project_roles": { + "roles": ["tester", "translator"] + } +} +``` +A user with permissions to edit a project may modify roles for other +users in the project. A user without edit permissions may not edit +their own roles. + +Editing requires sending a full representation of the roles array. diff --git a/docs/source/includes/_set_member_subjects.md b/docs/source/includes/_set_member_subjects.md new file mode 100644 index 000000000..97037614f --- /dev/null +++ b/docs/source/includes/_set_member_subjects.md @@ -0,0 +1,151 @@ +# SetMemberSubjects +```json +{ + "links": { + "set_member_subjects.subject": { + "href": "/subjects/{set_member_subjects.subject}", + "type": "subjects" + }, + "set_member_subjects.subject_set": { + "href": "/subject_sets/{set_member_subjects.subject_set}", + "type": "subject_sets" + } + }, + "meta": { + "set_member_subjects": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/set_member_subjects?page_size=2", + "previous_href": "/set_member_subjects?page=14page_size=2", + "next_href": "/set_member_subjects?page=2&page_size=2", + "last_href": "/set_member_subjects?page=14&page_size=2" + } + }, + "set_member_subjects": [{ + "id": "1023", + "created_at": "2014-03-20T00:15:47Z", + "updated_at": "2013-09-30T10:20:32Z", + "state": "active", + "priority": 101231.1231, + "links": { + "subject": "1231", + "subject_set": "101" + } + },{ + "id": "1024", + "created_at": "2014-03-20T00:15:47Z", + "updated_at": "2013-09-30T10:20:32Z", + "state": "retired", + "priority": 1231.1231, + "links": { + "subject": "1232", + "subject_set": "101" + } + }] +} +``` + +A Set Member Subject resource contains the state of a subject that is +included in a resource. + +It has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +state | string | +priority | float | +created_at | datetime | read-only +updated_at | datetime | read-only + +*id*, *created_at*, and *updated_at* are set by the API server. + + +## List all SetMemberSubjects +```http +GET /api/set_member_subjects HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + + subject_id (optional, integer) ... id of subject to see set_member_subjects for + + subject_set_id (optional, integer) ... id of subject_set to see set_member_subjects for + + include (optional, string) ... comma separated list of linked resources to load + +Response will contain a meta attribute hash containing paging information. + +SetMemberSubjects are returned as an array under *set_member_subjects*. + + +## Retrieve a Single SetMemberSubject +```http +GET /api/set_member_subjects/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` ++ Parameters + + id (required, integer) ... integer identifier for the resource + + include (optional, string) ... comma separated list of linked resources to load + +## Create a SetMemberSubject +```http +POST /api/set_member_subjects HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "set_member_subjects: { + "links": { + "subject": "12031", + "subject_set": "10" + } + } +} +``` + +A SetMemberSubject may be created by a user that can see the Subject +they wish to link to and can edit the project the SubjectSet belongs +to. + +A SetMemberSubject requires links be provided to a Subject and a +SubjectSet. Optionally, the create request may include a state and a +priority. The state will be 'active' by default and the priority will +be null by default. + + +## Edit a SetMemberSubject +```http +PUT /api/set_member_subjects/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "set_member_subjects: { + "state": "inactive" + } +} +``` + +A user with edit permissions for the project a SetMemberSubject's +SubjectSet belongs to may edit the *state* and *priority* attributes. + + +## Destroy a SetMemberSubject +```http +DELETE /api/set_member_subjects/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` +A user with edit permissions for the project a SetMemberSubject's +Subject belongs to may destroy a SetMemberSubject resource. This +removes the linked Subject form the linked SubjectSet + + diff --git a/docs/source/includes/_subject_sets.md b/docs/source/includes/_subject_sets.md new file mode 100644 index 000000000..f9c7617bb --- /dev/null +++ b/docs/source/includes/_subject_sets.md @@ -0,0 +1,218 @@ +# SubjectSets +```json +{ + "links": { + "subject_sets.workflows": { + "href": "/workflows?subject_set_id={subject_sets.id}", + "type": "workflows" + }, + "subject_sets.subjects": { + "href": "/subjects{?subject_set_id=subject_sets.id}", + "type": "subjects" + }, + "subject_sets.set_member_subjects": { + "href": "/set_member_subjects{?subject_set_id=subject_sets.id}", + "type": "set_member_subjects" + }, + "subject_sets.project": { + "href": "/project/{subject_sets.project}", + "type": "projects" + } + }, + "meta": { + "subject_sets": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/subject_sets?page_size=2", + "previous_href": "/subject_sets?page=14page_size=2", + "next_href": "/subject_sets?page=2&page_size=2", + "last_href": "/subject_sets?page=14&page_size=2" + } + }, + "subject_sets": [{ + "id": "20", + "display_name": "Weird Looking Galaxies", + "metadata": { + "category": "things" + }, + "created_at": "2014-02-13T10:11:34Z", + "updated_at": "2014-02-13T10:11:34Z", + "set_member_subject_count": 100, + "links": { + "project": "1", + "workflow": "10" + } + },{ + "id": "20", + "display_name": "Boring Looking Galaxies", + "metadata": { + "category": "things" + }, + "created_at": "2014-02-13T10:11:34Z", + "updated_at": "2014-02-13T10:11:34Z", + "set_member_subject_count": 100, + "links": { + "project": "1", + "workflow": "11" + } + }] +} +``` + +Subject Sets represent collections of Subjects that are paired with a +workflow of questions to be answered. A SubjectSet belongs to one +Workflow, while a single Workflow may have many SubjectSets. + +A SubjectSet has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +display_name | string | +metadata | jsonb | +set_member_subjects_count | integer | +created_at | datetime | read-only +updated_at | datetime | read-only + +All attributes except display_name are set by the API + +## List all Subject Sets +```http +GET /api/subject_sets HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + page (optional, integer) ... index of the page to retrieve 1 by default + + page_size (optional, integer) ... number of items per page 20 by default + + sort (optional, string) ... field to sort by, id by default + + project_id (optional, integer) ... filter by linked project + + workflow_id (optional, integer) ... filter by linked workflow + + include (optional, string) ... comma separated list of linked resources to include in the response + +Response contains a meta attribute hash containing paging +information. + +Subject Sets are returned as an array under *subject_sets*. + + +## Retrieve a single Subject Set +```http +GET /api/subject_sets/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + id (required, integer) ... integer id of the subject_set to retrieve + + include (optional, string) ... comma separated list of linked resources to include in the response + +## Create a Subject Set +```http +POST /api/subject_sets HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "subject_sets": { + "display_name": "A Group of Interesting Subjects", + "metadata": { + "category": "things" + }, + "links": { + "project": "43", + "workflows": ["47"], + "subjects": ["234", "1243", "8023"] + } + } +} +``` +A subject set must supply a display_name and a link to a project. Optionally, +it may include links to subjects and a single workflow. + +Instead of a list of subjects a SubjectSet may include a link to a +Collection which will import the collection's subjects into a new +SubjectSet. + + +## Edit a single Subject Set +```http +PUT /api/subject_sets/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "subject_sets": { + "display_name": "Normal Galaxies", + "links": { + "subjects": ["1", "2", "4", "5", "10"] + } + } +} +``` + +A user may only edit a subject if they edit permissions for the parent +project. The display_name attributes and links to workflows and subjects are +editable. Editing links requires a full representation of the new set +of links, but does not destroy unlinked resources. + +This is NOT the recommended way to manage linked subjects. + + +## Destroy a Subject Set +```http +DELETE /api/subject_sets/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + +A user may only destroy a subject set if they have destroy permissions +for the subject set's project. + +## Subject Set Links +Allows the addition of links to subjects to a subject +set object without needing to send a full representation of the linked +relationship. + +**This is the recommended way to managed linked subjects.** + +## Add Subject Set Link +```http +POST /api/subject_sets/123/links/subjects HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "subjects": ["1", "5", "9", "11"] +} +``` + ++ Parameters + + id (required, integer) ... the id of the Subject Set to modify + + link_type (required, string) ... the relationship to modify must be the same as the supplied body key +Only Subjects links may be edited. + + +## Destroy Subject Set Links +```http +DELETE /api/subject_sets/123/links/subjects/1,2,3 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + +Allows links to be removed without sending a full representation of the +linked relationship. + ++ Parameters + + id (required, integer) ... the id of the Subject Set to modify + + link_type (required, string) ... the relationship to modify + + link_ids (required, integer) ... comma separated list of ids to remove + +Will only remove the link. This operation does not destroy the linked object. + diff --git a/docs/source/includes/_subject_workflow_statuses.md b/docs/source/includes/_subject_workflow_statuses.md new file mode 100644 index 000000000..96433d18e --- /dev/null +++ b/docs/source/includes/_subject_workflow_statuses.md @@ -0,0 +1,102 @@ +# SubjectWorkflowStatuses +```json +{ + "links": { + "SubjectWorkflowStatuses.workflow": { + "href": "/workflows/{subject_workflow_statuses.workflow}", + "type": "workflows" + }, + "SubjectWorkflowStatus.subject": { + "href": "/subjects/{subject_workflow_statuses.subject}", + "type": "subjects" + } + }, + "meta": { + "collection_preferences": { + "page": 1, + "page_size": 2, + "count": 2, + "include": [], + "page_count": 1, + "previous_page": 0, + "next_page": 0, + "first_href": "/subject_workflow_statuses?page_size=2", + "previous_href": "", + "next_href": "", + "last_href": "/subject_workflow_statuses?page=2&page_size=2" + } + }, + "subject_workflow_statuses": [{ + "id": "1", + "created_at": "2014-03-20T06:23:12Z", + "updated_at": "2014-04-21T08:22:22Z", + "classifications_count": 10, + "retired_at": "2014-04-21T08:22:22Z", + "retirement_reason": "consensus", + "links": { + "workflow" : "3", + "subject": "4" + } + },{ + "id": "2", + "created_at": "2014-03-21T06:23:12Z", + "updated_at": "2014-04-22T08:22:22Z", + "classifications_count": 2, + "retired_at": "2014-04-22T08:22:22Z", + "retirement_reason": "blank", + "links": { + "workflow" : "3", + "subject": "5" + } + }] +} +``` + +A SubjectWorkflowStatus resource collates the status of a subject in a workflow. +This status includes the classification count and the retirement state and reason. + +It has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +classifications_count | integer | +retired_at | datetime | +retirement_reason | string | +created_at | datetime | read-only +updated_at | datetime | read-only + +*id*, *created_at*, and *updated_at* are set the by the API. + +SubjectWorkflowStatuses are +only visible to users with rights on the workflow's associated project. + +## List all SubjectWorkflowStatuses +```http +GET /api/subject_workflow_statuses HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + + workflow_id (optional, integer) ... workflow to see SubjectWorkflowStatuses for + + subject_id (optional, integer) ... subject_id to see SubjectWorkflowStatuses for + + include (optional, string) ... comma separated list of linked resources to load + +Response will have a meta attribute hash containing paging +information. + +SubjectWorkflowStatuses are returned as an array under *subject_workflow_statuses*. + + +## Retrieve a single SubjectWorkflowStatus +```http +GET /api/subject_workflow_statuses/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` ++ Parameters + + id (required, integer) ... integer identifier of resource + + include (optional, string) ... comma separated list of linked resources to load diff --git a/docs/source/includes/_subjects.md b/docs/source/includes/_subjects.md new file mode 100644 index 000000000..f64758fc8 --- /dev/null +++ b/docs/source/includes/_subjects.md @@ -0,0 +1,310 @@ +# Subjects +```json + { + "links": { + "subjects.project": { + "href": "/projects/subjects.project", + "type": "projects" + }, + "subjects.subject_sets": { + "href": "/subject_sets/subjects.subject_sets", + "type": "subject_sets" + } + }, + "meta": { + "subjects": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/subjects?page_size=2", + "previous_href": "/subjects?page=14page_size=2", + "next_href": "/subjects?page=2&page_size=2", + "last_href": "/subjects?page=14&page_size=2" + } + }, + "subjects": [{ + "id": "1", + "zooniverse_id": "AGFS0001231", + "created_at": "2014-03-24T10:42:21Z", + "updated_at": "2014-03-24T10:42:21Z", + "locations": [ + {"image/jpeg": "http://s3.amazonaws.com/subjects/1.png"} + ], + "metadata": { + "lens_type": "50mm" + }, + "links": { + "project": "1" + "subject_sets": ["1"] + } + },{ + "id": "2", + "zooniverse_id": "AGFS0001232", + "created_at": "2014-03-24T10:44:21Z", + "updated_at": "2014-03-24T10:44:21Z", + "locations": [ + {"image/jpeg": "http://s3.amazonaws.com/subjects/2.png"} + ], + "metadata": { + "lens_type": "50mm" + }, + "links": { + "project": "1" + "subject_sets": ["1"] + } + }] + } +``` + +A single Subject object. A Subject is a resource that describe a +piece of media to be classified including metadata about the object. + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +zooniverse_id | integer | read-only +locations | array(hash) | +metadata | hash | +created_at | datetime | read-only +updated_at | datetime | read-only + +*id*, *zooniverse_id*, *created_at*, and *updated_at* are assigned by +the API. + +## List Subjects +```http +GET /api/subjects HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + + sort (optional, string) ... field to sort by + + workflow_id (optional, integer) ... filter to subjects belonging to a specific workflow + + subject_set_id (optional, integer) ... return subjects belonging to the identified subject_set + +Response will have a *meta* attribute hash containing paging information. + +Subjects are returned as an array under the _subjects_ key. + +## Retrieve a single Subject +```http +GET /api/subjects/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + id (required, integer) ... integer id of the subject resource + +## Create a Subject +```http +POST /api/subjects HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "subjects": { + "locations": [ + "image/png", + [ + "video/webm", + "video/mp4" + ] + ], + "metadata": { + "lens_type": "50mm" + }, + "links": { + "project": "1" + } + } +} +``` + +A *locations* attribute and a project link are required. + +To have the Zooniverse host your media resources the *locations* array +should have the mime-types of the subject's associated media, +e.g `"locations":["image/png", "image/jpeg", "image/png"]`, +note the locations mime types are stored in order. + +The create response will contain signed s3 urls the client may make a PUT +request containing the media to. The signed urls will be valid for 20 minutes. +Please take the order of the returned s3 urls into account when PUT'ing +local media resources to the remote location. + +To use your own hosted media resources the *locations* array +should be comprised of objects that represent the mime-type and the hosted URL +of the subject's associated media, +e.g. `"locations":[ +{"image/png": "https://your.s3_account.com/subjects/1.png"}, +{"image/jpeg": "https://your.s3_account.com/subjects/1.jpg"} +]`. + +The *metadata* attribute is optional. + +## Edit a single Subject +```http +PUT /api/subjects/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "subjects": { + "locations": [ + "image/png" + ] + } +} +``` + +Users are permitted to edit subjects belonging to projects a user +has edit permissions for. A user may not change the project of a +subject. + +The *locations* array should have the mime-types of the subject's +associated media. The response will contain signed s3 urls the client +may make a PUT request containing the media to. The signed urls will +be valid for 20 minutes. + +A request changing the *metadata* hash must contain a full +representation of the attribute. + +## Destroy a single subject +```http +DELETE /api/subjects/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + +Users are permitted to destroy a subjects they own or +subjects belongs to a project a user has destroy permissions for. + +## Subject Versions +```json +{ + "meta": { + "versions": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/subjects/101/versions?page_size=2", + "previous_href": "/subjects/101/versions?page=14page_size=2", + "next_href": "/subjects/101/versions/?page=2&page_size=2", + "last_href": "/subjects/101/versions?page=14&page_size=2" + } + }, + "versions": [{ + "id": "42", + "changeset": { + "metadata": [{ + "ra": "120.2", + "dec": "-12.4" + },{ + "ra": "121.1", + "dec": "-11.1" + }] + }, + "whodunnit": "stuartlynn", + "created_at": "2014-03-20T06:23:12Z", + "links": { + "item": { + "id": "101", + "href": "/subject/101", + "type": "subjects" + } + } + },{ + "id": "43", + "changeset": { + "metadata": [{ + "ra": "20.2", + "dec": "12.4" + },{ + "ra": "21.1", + "dec": "11.1" + }] + }, + "whodunnit": "stuartlynn", + "created_at": "2014-03-20T06:23:12Z", + "links": { + "item": { + "id": "101", + "href": "/subject/101", + "type": "subjects" + } + } + }] +} +``` + +A Subject Version resource represents a set of changes made to +a Subject resource. + +It has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +changeset | jsonb | read-only +whodunnit | string | read-only +created_at | datetime | read-only + + +**It is NOT editable.** + +## List all Subject Versions +```http +GET /api/subjects/123/versions HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + subject_id (required, integer) ... id of the subject to retreive versions for + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + +Response will have a meta attribute hash containing paging +information. + +Subject Versions are returned as an array under *versions*. + + +## Retrieve a Single Subject Version +```http +GET /api/subjects/123/versions/2 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + subject_id (required, integer) ... id of the subject to retreive versions for + + id (required, integer) ... integer id of the version to load + + +## Retrieve subjects to classify +```http + +GET /api/v1/subjects/queued HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + +While the normal GET on the subjects resource will return a list of subjects in a project, there is a special API for getting some subjects that need classifications: `GET /api/v1/subjects/queued`. This special API is optimized specifically for serving a selection of subjects that should be shown to the user in the classify interface. + ++ Parameters + + workflow_id (required, integer) ... filter to subjects belonging to a specific workflow + + subject_set_id (optional, integer) ... return subjects belonging to the identified subject_set, it is required when the workflow is grouped. + diff --git a/docs/source/includes/_user_groups.md b/docs/source/includes/_user_groups.md new file mode 100644 index 000000000..f8339b214 --- /dev/null +++ b/docs/source/includes/_user_groups.md @@ -0,0 +1,242 @@ +# UserGroups +```json +{ + "links": { + "user_groups.projects": { + "href": "/projects?owner={user_groups.owner_name}", + "type": "projects" + }, + "user_groups.classifications": { + "href": "/classifications?user_group_id={user_groups.id}", + "type": "classifications" + }, + "user_groups.collections": { + "href": "/collections?owner={user_groups.owner_name}" + "type": "collections" + }, + "user_groups.users": { + "href": "/users?user_group_id={user_groups.id}", + "type": "users" + }, + "user_groups.memberships": { + "href": "/memberships?user_group_id={user_groups.id}", + "type": "memberships" + } + }, + "meta": { + "user_groups": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/user_groups?page_size=2", + "previous_href": "/user_groups?page=14page_size=2", + "next_href": "/user_groups?page=2&page_size=2", + "last_href": "/user_groups?page=14&page_size=2" + } + }, + "user_groups": [{ + "id": "42", + "name": "a_cool_group", + "display_name": "A Cool Group", + "owner_name": "a_cool_group", + "created_at": "2014-08-11T10:11:34Z", + "updated_at": "2014-12-11T00:11:34Z", + "classifications_count": "1002340", + "activated_state": "active", + "stats_visibility": "private_agg_only", + "links": { + "memberships": ["101", "102"], + "users": ["10001", "9102"], + "projects": ["10"], + "collections": ["11"] + } + },{ + "id": "44", + "name": "a_cool_gang", + "display_name": "A Cool Gang", + "owner_name": "a_cool_gang", + "created_at": "2014-09-10T10:41:54Z", + "updated_at": "2014-11-11T01:21:33Z", + "classifications_count": "2341", + "activated_state": "active", + "stats_visibility": "public_show_all", + "links": { + "memberships": ["101", "102"], + "users": ["10001", "9102"], + "projects": ["10"], + "collections": ["11"] + } + }] +} +``` + +A user group represents a collection of users that share ownership of +projects, collections, and classifications. Individual users within +the group can be given different levels of permissions to act on +group owned resources. + +A User Group has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +classifications_count | integer | +activated_state | string | +name | string | +display_name | string | +stats_visibility | string | +created_at | datetime | read-only +updated_at | datetime | read-only + + +*id*, *created_at*, *updated_at*, and *classifications_count* are all + set by the API. + +## Stats Visibility Levels +We have added Stats Visibility Levels for new stats features on User Groups. The `stats_visibility` is an enum type on the `user_group` model on Panoptes. + +**Currently there are 5 Levels of Visibility.** + +**Stats Visibility Levels (Matching number with its corresponding numeric in Panoptes):** + +0) `private_agg_only` (DEFAULT) : Only members of a user group can view aggregate stats. Individual stats are ONLY viewable by ADMINS of the user group.
+1) `private_show_agg_and_ind`: Only members of a user group can view aggregate stats. Individual stats is viewable by BOTH members and admins of the user group.
+2) `public_agg_only`: Anyone can view aggregate stats of the user group. Only ADMINS of the user group can view individual stats.
+3) `public_agg_show_ind_if_member`: Anyone can view aggregate stats of the user group. Both members and admins of the user group can view individual stats.
+4) `public_show_all`: Anyone can view aggregate stats of the user group and can view individual stats of the user group. Authentication/Authorization to view user_group stats is NOT needed. + + +## List all User Groups +```http +GET /api/user_groups HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + page (optional, integer) ... index of the page to retrieve 1 by default + + page_size (optional, integer) ... number of items per page 20 by default + + sort (optional, string) ... field to sort by, id by default + + user_id (optional, integer) ... filter list to groups a user is part of + + include (optional, string) ... comma separated list of linked resources to include in the response + +Response has a meta attribute hash containing paging +information. + +User Groups are returned as an array under *user_groups*. + +## Retrieve a single User Group +```http +GET /api/user_groups/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + id (required, integer) ... integer, id of the user group + + include (optional, string) ... comma separated list of linked resources to include in the response + +## Create a User Group +```http +POST /api/user_groups HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "user_groups": { + "display_name": "A Super Grouper!", + "links": { + "users": ["10", "22"] + } + } +} +``` + +A user can create new group by just giving it a name (how it appears +in a @mention and url) or display name (how it shown to other users). + +In the case where only a display name is provided, the name will be +set to the underscored, downcased, and url escaped version of the +display name. When only a name is provided, display_name will be set +to the same string as name. + +Optionally links to other users who will be given +memberships with the 'invited' state. + + +## Edit a single User Group +```http +PUT /api/user_groups/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "user_groups": { + "display_name": "A Uncool Group", + "links": { + "projects": [], + "collections": [] + } + } +} +``` + +A user with edit permissions on a user group may edit the group's +name, display_name, or links to projects, collections and +users. Projects and Collections may only be removed. Removing a +link to a project or collection will destroy the project or +collection, removing a link to a user will set their +membership state to inactive. + +Adding a user creates a membership link with an 'invited' +state. Membership and Classification links cannot be modified. + +**This is NOT the recommended way to modify links.** + +## Destroy a User Group +```http +DELETE /api/user_groups/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + +A user may destroy a group if they have the requisite permissions. A +destroyed group and linked projects, collections, and memberships will +be placed in an 'inactive' state. + + +## Add user links +```http +POST /user_groups/123/links/users HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "users": ["123", "23"] +} +``` + +Only links to users may be added. Creates a membership for a user. The membership will be immediately +added, but a user won't show up in the group's links until they set +their membership to 'active'. +Only links to users may be added. + +## Remove links +```http +DELETE /user_groups/123/links/users/1,2,3 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + id (required, integer) ... id of the group to be edited. + + link_type (required, string) ... name of the link to modify + + link_ids (required, string) ... comma separated list of ids to remove + +Allows links to users, projects, or collections to be removed. Removed +projects and collections are deleted. Removed users have their +membership set to 'inactive'. diff --git a/docs/source/includes/_workflows.md b/docs/source/includes/_workflows.md new file mode 100644 index 000000000..d5680f9e1 --- /dev/null +++ b/docs/source/includes/_workflows.md @@ -0,0 +1,487 @@ +# Workflows +```json +{ + "links": { + "workflows.subjects": { + "href": "/subjects{?workflow_id=workflows.id}", + "type": "subjects" + }, + "workflows.project": { + "href": "/projects/{workflows.project}", + "type": "projects" + }, + "workflows.subject_sets": { + "href": "/subject_sets?workflow_id={workflows.id}", + "type": "subject_sets" + } + }, + "meta": { + "workflows": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/workflows?page_size=2", + "previous_href": "/workflows?page=14page_size=2", + "next_href": "/workflows?page=2&page_size=2", + "last_href": "/workflows?page=14&page_size=2" + } +}, +"workflows": [{ + "id": "22", + "display_name": "Find moons", + "created_at": "2014-02-13T10:11:34Z", + "updated_at": "2014-02-13T10:11:34Z", + "classifications_count": 1000, + "pairwise": false, + "grouped" : false, + "prioritized": false, + "primary_language": "es_MX", + "workflow_version": "22.1", + "content_language": "en_US", + "first_task": "interest", + "tasks": { + "interest": { + "type": "drawing", + "question": "Color some points", + "tools": [ + {"value": "red", "label": "Red", "type": "point", "color": "red"}, + {"value": "green", "label": "Green", "type": "point", "color": "lime"}, + {"value": "blue", "label": "Blue", "type": "point", "color": "blue"} + ], + "next": "shape" + }, + "shape": { + "type": "multiple", + "question": "What shape is this galaxy?", + "answers": [ + {"value": "smooth", "label": "Smooth"}, + {"value": "features", "label": "Features"}, + {"value": "other", "label": "Star or artifact"} + ], + "required": true, + "next": "roundness" + }, + "roundness": { + "type": "single", + "question": "How round is it?", + "answers": [ + {"value": "very", "label": "Very...", "next": "shape"}, + {"value": "sorta", "label": "In between"}, + {"value": "not", "label": "Cigar shaped"} + ], + "next": null + } + }, + "links": { + "project": "1", + "subject_sets": ["10", "11", "12"] + } +},{ + "id": "23", + "display_name": "Find moons", + "created_at": "2014-02-13T10:11:34Z", + "updated_at": "2014-02-13T10:11:34Z", + "classifications_count": 1000, + "pairwise": false, + "grouped" : false, + "prioritized": false, + "primary_language": "es_MX", + "workflow_version": "22.1", + "content_language": "en_US", + "first_task": "interest", + "tasks": { + "interest": { + "type": "drawing", + "question": "Color some points", + "tools": [ + {"value": "red", "label": "Red", "type": "point", "color": "red"}, + {"value": "green", "label": "Green", "type": "point", "color": "lime"}, + {"value": "blue", "label": "Blue", "type": "point", "color": "blue"} + ], + "next": "shape" + }, + "shape": { + "type": "multiple", + "question": "What shape is this galaxy?", + "answers": [ + {"value": "smooth", "label": "Smooth"}, + {"value": "features", "label": "Features"}, + {"value": "other", "label": "Star or artifact"} + ], + "required": true, + "next": "roundness" + }, + "roundness": { + "type": "single", + "question": "How round is it?", + "answers": [ + {"value": "very", "label": "Very...", "next": "shape"}, + {"value": "sorta", "label": "In between"}, + {"value": "not", "label": "Cigar shaped"} + ], + "next": null + } + }, + "links": { + "project": "1", + "subject_sets": ["10", "11", "12"] + } +}] +} +``` + +Workflows represent the series of questions/tasks a user will be asked +to complete for a subject. Subjects are selected from SubjectSets. A +Workflow may have many SubjectSets linked to, but a SubjectSet may +only be linked to a single Workflow. + +A workflow has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +display_name | string | +finished_at | datetime | +tasks | jsonb | +classifications_count | integer | +pairwise | boolean | +grouped | boolean | +prioritized | boolean | +retirement | jsonb | +retired_set_member_subjects_count | integer | +active | boolean | +aggregation | jsonb | +configuration | jsonb | +completeness | decimal | +primary_language | string | +workflow_version | string | +content_language | string | +created_at | datetime | read-only +updated_at | datetime | read-only + + +*id*, *created_at*, *updated_at*, *workflow_version*, *content_language*, +and *classifications_count* are assigned by the API + +*finished_at* is set by the API to a date/time when all subjects for this workflow have been retired. + +Three parameters: _grouped_, _prioritized_, and _pairwise_ configure +how the api chooses subjects for classification. They are all false by default, +which will give a random selection of subjects from all subject\_sets that +are part of a workflow. _grouped_ enables selecting subjects from a specific +subject set. _prioritized_ ensures that users will see subjects in a +predetermined order. _pairwise_ will select two subjects at a tim for classification. + +A workflow's `tasks` is a hash of keys to task definitions. + +A workflow's `first_task` is a string matching the key of its first task. (The order of keys in JSON hashes is not guaranteed). + +Each task has a `type` string of "single" or "multiple" choice, or "drawing". (More task types to come, e.g. Serengeti-style filter and Sunspotter's comparison.) + +"multiple" and "drawing" tasks have a `next` string, linking to the next task in the workflow. If this string is empty, the workflow ends. In "single" tasks, each answer has a `next` string, allowing branching based on the user's decisions. + +"single" and "multiple" tasks have a `question` string, which the user must answer. Answers to the question are in an `answers` array. Each answer has a `label` string displayed to the user. + +"single" and "multiple" tasks may define a boolean `required`, which when true will force the user to provide an answer before moving on to the next task. + +"drawing" tasks have an `instruction` string telling the user how to complete the task. + +"drawing" tasks have a `tools` array. + +Each tool has a `label` shown to the user. + +Each tool has a string `type`. Options include: + ++ point ++ ellipse ++ circle ++ line ++ rectangle ++ polygon + +Each tool has a string `color`, which is applied to the marks made by the tool. Any format valid as CSS can be used. + +## List All Workflows +```http +GET /api/workflows HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + + sort (optional, string) ... field to sort by id by default + + project_id (optional, integer) ... filter workflows by project id + + include (optional, string) ... comma separated list of linked resources to load + +Response has a *meta* attribute hash containing +paging information. + +Workflows are returned as an array under the _workflows_ key. + +## Retrieve a single Workflow +```http +GET /api/workflows/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + id (required, integer) ... id of the workflow + + include (optional, string) ... comma separated list of linked resources to include in the response + +## Create a Workflow +```http +POST /api/workflows HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "workflows": { + "display_name": "Spot Monsters!", + "tasks": { + "interest": { + "type": "drawing", + "question": "Color some points", + "tools": [ + {"value": "red", "label": "Red", "type": "point", "color": "red"}, + {"value": "green", "label": "Green", "type": "point", "color": "lime"}, + {"value": "blue", "label": "Blue", "type": "point", "color": "blue"} + ], + "next": "shape" + }, + "shape": { + "type": "multiple", + "question": "What shape is this galaxy?", + "answers": [ + {"value": "smooth", "label": "Smooth"}, + {"value": "features", "label": "Features"}, + {"value": "other", "label": "Star or artifact"} + ], + "required": true, + "next": "roundness" + }, + "roundness": { + "type": "single", + "question": "How round is it?", + "answers": [ + {"value": "very", "label": "Very...", "next": "shape"}, + {"value": "sorta", "label": "In between"}, + {"value": "not", "label": "Cigar shaped"} + ], + "next": null + } + }, + "retirement": { + "criteria": "classification_count", + "options": { + "count": 15 + } + }, + "primary_language": "en-ca", + "links": { + "project": "42", + "subject_sets": ["1", "2"] + } + } +} +``` + +Requires a set of *tasks*, a *primary_language*, a *display_name*, and a +link to a *project*. Can optionally set cellect parameters *grouped*, +*prioritized*, and *pairwise* (all false by default) and links to +*subject_sets*. + +A SubjectSet that already belongs to another workflow will be +duplicated when it is linked. + +A Workflow may also include a _retirement_ object with a _criteria_ +key and an _options_ key. _criteria_ describes the strategy Panoptes +will use to decide when to retire subjects while _options_ configures +the strategy. There are 2 valid criteria: + 1. `classification_count` will retire subjects after a target number + of classifications are reached. You must supply an `options` hash + with an integer `count` to specify the minimum number of classifications. + + `{"criteria": "classification_count", "options": {"count": 15} }` + 2. `never_retire` will never retire subjects and requires an empty + `options` hash. + + `{"criteria": "never_retire "options": {} }` + +If retirement is left blank Panoptes defaults to the `classification_count` +strategy with 15 classifications per subject. + + +## Edit a single workflow +```http +PUT /api/workflows/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ + "workflows": { + "tasks": { "format": "all new!"}, + "links": { + "subject_sets": ["8"] + } + } +} +``` + +A user may edit a workflow if they have edit permissions for the parent +project. Editing tasks content requires a full replacement for the +field. Only the subject set link may be edited. Removing a subject_set +link doesn't destroy the subject_set. + +This is not the recommended way to edit links. Use the subject_set +link mode documented below. + + +## Destroy a single workflow +```http +DELETE /api/workflows/123 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + +A user may destroy a workflow if they have destroy permissions for the +parent project. + +## Link Subject Set to Workflow +```http +POST /api/workflows/123/links/subject_sets HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json + +{ "subject_sets": ["9"] } +``` + +**The recommended way to update links.** + +Adds the posted subject sets to a workflow's links. Creates a copy of +the subject set if it belongs do a different project. + ++ Parameters + + id (required, integer) ... id of workflow to update + + + +## Destroy Workflow's Subject Set Links +```http +DELETE /api/workflows/123/links/subject_sets/1,2,3 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + +**The recommended way to remove links.** + +Removes workflow's links to the given subject_sets. It does not +destroy the subject set models. + ++ Parameters + + id (required, integer) ... id of workflow to update + + subject_set_ids (required, string) ... comma separated list of ids to destroy + +## Workflow Versions +```json +{ + "meta": { + "versions": { + "page": 1, + "page_size": 2, + "count": 28, + "include": [], + "page_count": 14, + "previous_page": 14, + "next_page": 2, + "first_href": "/workflows/101/versions?page_size=2", + "previous_href": "/workflows/101/versions?page=14page_size=2", + "next_href": "/workflows/101/versions/?page=2&page_size=2", + "last_href": "/workflows/101/versions?page=14&page_size=2" + } + }, + "versions": [{ + "id": "42", + "changeset": { + "grouped": [ + true, + false + ] + }, + "whodunnit": "stuartlynn", + "created_at": "2014-03-20T06:23:12Z", + "links": { + "item": { + "id": "101", + "href": "/workflows/101", + "type": "workflows" + } + } + },{ + "id": "43", + "changeset": { + "prioritized": [ + false, + true + ] + }, + "whodunnit": "stuartlynn", + "created_at": "2014-03-20T06:23:12Z", + "links": { + "item": { + "id": "101", + "href": "/workflows/101", + "type": "workflows" + } + } + }] +} +``` + +A Workflow Version resource represents a set of changes made to +a Workflow resource. + +It has the following attributes: + +Attribute | Type | Description +--------- | ---- | ----------- +id | integer | read-only +changeset | hash | read-only +whodunnit | string | read-only +created_at | datetime | read-only + + +**It is NOT editable.** + +## List All Workflow Versions +```http +GET /api/workflows/123/versions HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + workflow_id (required, integer) ... integer id of the workflow resource + + page (optional, integer) ... the index of the page to retrieve default is 1 + + page_size (optional, integer) ... number of items to include on a page default is 20 + +Response will have a meta attribute hash containing paging +information. + +Workflow Versions are returned as an array under *versions*. + +## Retrieve a Single Version +```http +GET /api/workflows/123/versions/1 HTTP/1.1 +Accept: application/vnd.api+json; version=1 +Content-Type: application/json +``` + ++ Parameters + + workflow_id (required, integer) ... integer id of the workflow resource + + id (required, integer) ... integer id of the version to retrieve + diff --git a/docs/source/index.html.md b/docs/source/index.html.md index 283719102..ba85656a0 100644 --- a/docs/source/index.html.md +++ b/docs/source/index.html.md @@ -14,9 +14,24 @@ toc_footers: includes: - authentication - json_api + - headers + - classifications + - collection_preferences + - collection_roles + - collections + - memberships + - organizations + - project_preferences + - project_roles - projects - subject_set_imports + - set_member_subjects + - subject_sets + - subject_workflow_statuses + - subjects + - user_groups - users + - workflows search: true ---